Self-Hosting Nextcloud
August 4, 2026
Nextcloud replaces Google Drive, Dropbox, and calendar/contact services with a self-hosted platform you control. On Gentoo, Nextcloud is available through Portage and deployed with webapp-config, which manages multiple web applications across virtual hosts. This post covers installing Nextcloud with Apache and PHP-FPM, configuring it with either SQLite (for standalone servers) or MySQL (for mail server integration), and hardening the setup for production use.
Prerequisites
Before starting:
- Apache is installed and running
- PHP-FPM is installed with required extensions
- For MySQL mode: a running MySQL server
- A domain name pointed at your server (e.g.,
cloud.example.com)
Setting USE Flags
Nextcloud and PHP need specific USE flags on Gentoo. Create the package.use files:
For SQLite mode (standalone server):
cat > /etc/portage/package.use/nextcloud << 'EOF'
www-apps/nextcloud sqlite -mysql vhosts
EOF
cat > /etc/portage/package.use/php-nextcloud << 'EOF'
dev-lang/php xmlreader xmlwriter truetype gd curl intl bcmath gmp zip pdo sqlite fpm
EOF
For MySQL mode (shared with a mail server):
cat > /etc/portage/package.use/nextcloud << 'EOF'
www-apps/nextcloud -sqlite mysql vhosts
EOF
cat > /etc/portage/package.use/php-nextcloud << 'EOF'
dev-lang/php xmlreader truetype gd curl intl bcmath gmp zip fpm
EOF
Additional dependencies:
cat > /etc/portage/package.use/gd-nextcloud << 'EOF'
media-libs/gd truetype
EOF
cat > /etc/portage/package.use/imagemagick-nextcloud << 'EOF'
media-gfx/imagemagick -openmp
EOF
cat > /etc/portage/package.use/apache-nextcloud << 'EOF'
www-servers/apache apache2_modules_proxy apache2_modules_proxy_fcgi
EOF
The vhosts USE flag tells Portage to install Nextcloud into a location that webapp-config can manage, rather than directly into a document root.
Installing Nextcloud
emerge -av www-apps/nextcloud
This pulls in Nextcloud and its PHP dependencies. The compilation may take significant time depending on how many dependencies need rebuilding with the new USE flags.
Deploying with webapp-config
Gentoo's webapp-config deploys web applications into virtual host directories. Deploy Nextcloud for your domain:
webapp-config -I -h cloud.example.com -d / nextcloud $(qatom -F "%{PV}" $(portageq best_visible / www-apps/nextcloud))
This installs Nextcloud to /var/www/cloud.example.com/htdocs/. The version number is pulled dynamically from the installed package.
Alternatively, specify the version manually:
webapp-config -I -h cloud.example.com -d / nextcloud 29.0.0
Creating the Data Directory
Nextcloud's data directory should be outside the web root for security:
mkdir -p /var/nextcloud/data
chown apache:apache /var/nextcloud/data
chmod 750 /var/nextcloud/data
Configuring PHP-FPM
Create or edit the PHP-FPM pool configuration. On Gentoo, this is typically at /etc/php/fpm-php8.2/fpm.d/www.conf (adjust the version number):
[www]
user = apache
group = apache
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
Adjust PHP settings for Nextcloud's requirements. Edit /etc/php/fpm-php8.2/php.ini:
memory_limit = 512M
upload_max_filesize = 512M
post_max_size = 512M
max_execution_time = 300
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 1
Start PHP-FPM:
rc-update add php-fpm default
rc-service php-fpm start
Configuring Apache
Enable the proxy modules in /etc/conf.d/apache2:
APACHE2_OPTS="-D DEFAULT_VHOST -D SSL -D SSL_DEFAULT_VHOST -D PROXY"
Create the PHP-FPM integration file at /etc/apache2/modules.d/70_php-fpm.conf:
<IfModule proxy_fcgi_module>
<FilesMatch "\.php$">
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
DirectoryIndex index.php index.html
</IfModule>
Virtual Host for Nextcloud
Create /etc/apache2/vhosts.d/cloud.example.com.conf:
For a standalone server behind a reverse proxy (no local TLS):
<VirtualHost *:80>
ServerName cloud.example.com
DocumentRoot "/var/www/cloud.example.com/htdocs"
# Trust X-Forwarded-Proto from reverse proxy
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
<Directory "/var/www/cloud.example.com/htdocs">
Require all granted
AllowOverride All
Options FollowSymLinks
</Directory>
ErrorLog /var/log/apache2/cloud.example.com_error.log
CustomLog /var/log/apache2/cloud.example.com_access.log combined
</VirtualHost>
For a server with local TLS (not behind a reverse proxy):
<VirtualHost *:80>
ServerName cloud.example.com
Redirect permanent / https://cloud.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName cloud.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
DocumentRoot "/var/www/cloud.example.com/htdocs"
<Directory "/var/www/cloud.example.com/htdocs">
Require all granted
AllowOverride All
Options FollowSymLinks
</Directory>
ErrorLog /var/log/apache2/cloud.example.com_ssl_error.log
CustomLog /var/log/apache2/cloud.example.com_ssl_access.log combined
</VirtualHost>
Validate and restart Apache:
apache2ctl configtest
rc-service apache2 restart
Running the Nextcloud Installer
Web-Based Installation
Navigate to https://cloud.example.com/ in your browser. The installer asks for:
- Admin username and password
- Data directory path (
/var/nextcloud/data) - Database type (SQLite or MySQL)
- For MySQL: host, database name, user, and password
Command-Line Installation
For automated setups, use the occ command:
With SQLite:
sudo -u apache php /var/www/cloud.example.com/htdocs/occ maintenance:install \
--database "sqlite" \
--admin-user "admin" \
--admin-pass "your-admin-password" \
--data-dir "/var/nextcloud/data"
With MySQL:
sudo -u apache php /var/www/cloud.example.com/htdocs/occ maintenance:install \
--database "mysql" \
--database-host "localhost" \
--database-name "nextcloud" \
--database-user "nextcloud" \
--database-pass "nextcloud-db-password" \
--admin-user "admin" \
--admin-pass "your-admin-password" \
--data-dir "/var/nextcloud/data"
Post-Installation Configuration
Trusted Domains
Nextcloud only responds to requests for domains listed in its trusted domains configuration. Add your domain:
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
trusted_domains 0 --value="cloud.example.com"
Trusted Proxy
If Nextcloud runs behind a reverse proxy, configure the trusted proxy to get correct client IPs:
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
trusted_proxies 0 --value="10.0.0.0/8"
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
overwriteprotocol --value="https"
The overwriteprotocol setting ensures Nextcloud generates HTTPS URLs even though the backend receives HTTP from the proxy.
Background Jobs
Switch from AJAX-based cron to system cron for reliable background processing:
sudo -u apache php /var/www/cloud.example.com/htdocs/occ background:cron
Add the cron job:
crontab -u apache -e
Add:
*/5 * * * * php -f /var/www/cloud.example.com/htdocs/cron.php
This runs Nextcloud's background jobs every 5 minutes.
Memory Cache
Enable APCu for local caching and Redis for file locking (if Redis is installed):
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
memcache.local --value="\OC\Memcache\APCu"
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
memcache.locking --value="\OC\Memcache\Redis"
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
redis host --value="127.0.0.1"
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
redis port --value=6379 --type=integer
Default Phone Region
Set the default phone region to avoid a warning in the admin panel:
sudo -u apache php /var/www/cloud.example.com/htdocs/occ config:system:set \
default_phone_region --value="US"
Upgrading Nextcloud
When a new version is available in Portage:
emerge -av www-apps/nextcloud
Then upgrade the deployment:
webapp-config -U -h cloud.example.com -d / nextcloud $(qatom -F "%{PV}" $(portageq best_visible / www-apps/nextcloud))
Run the database migration:
sudo -u apache php /var/www/cloud.example.com/htdocs/occ upgrade
Choosing SQLite vs MySQL
SQLite is the right choice for a standalone Nextcloud server with a small number of users. It requires no external database service, simplifies backups (the entire database is a single file), and has zero configuration overhead. The downside is limited concurrency — SQLite locks the entire database on writes, which causes slowdowns with multiple simultaneous users.
MySQL is necessary when Nextcloud shares a server with other database-backed applications (like a mail server with PostfixAdmin) or when you expect more than a handful of concurrent users. The performance difference is significant under load — MySQL handles concurrent connections without blocking.
For a personal server with 1-5 users, SQLite is fine. For anything shared or production-facing, use MySQL.
Verifying the Installation
# Apache is serving Nextcloud
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1/status.php
# PHP-FPM is processing requests
curl -s http://127.0.0.1/status.php | python3 -m json.tool
# occ works
sudo -u apache php /var/www/cloud.example.com/htdocs/occ status
# Check for warnings
sudo -u apache php /var/www/cloud.example.com/htdocs/occ check
The status.php endpoint returns JSON with the Nextcloud version and whether it's installed.
Summary
After completing these steps:
- Nextcloud is deployed on Gentoo via
webapp-config - Apache serves the application through PHP-FPM
- The data directory is outside the web root
- Background jobs run via system cron every 5 minutes
- Memory caching is enabled via APCu and Redis
- Trusted proxy settings ensure correct client IPs behind a reverse proxy
Nextcloud pairs with Syncthing for server-to-server file replication, and with a mail server for integrated calendar and contact sync via CalDAV/CardDAV.