Nextcloud on Synology with Docker
Cloud Station is fine for syncing my own machines, but it falls over when I have to share something with people outside, or want a WebDAV endpoint. So I ended up running Nextcloud. In Docker on the NAS it stays apart from DSM's own PHP and web server, and upgrading is just an image tag change.
My setup is the official nextcloud image with Apache, a MariaDB container, and Redis for file locking, all in one Compose file. I assume Docker and docker-compose already work over SSH (see my earlier post on Compose), and that you have a DDNS hostname and certificate if you want outside access. The clients insist on HTTPS in practice. Leave plenty of room on the volume too; the data directory holds every synced file.
Step 1: Folders and the Compose file
sudo -i
mkdir -p /volume1/docker/nextcloud/{db,html,data}
cd /volume1/docker/nextcloud
vi docker-compose.yml
version: '2'
services:
db:
image: mariadb:10.1
container_name: nextcloud-db
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
environment:
MYSQL_ROOT_PASSWORD: rootpw-change-me
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: ncpw-change-me
volumes:
- /volume1/docker/nextcloud/db:/var/lib/mysql
redis:
image: redis:4-alpine
container_name: nextcloud-redis
restart: unless-stopped
app:
image: nextcloud:12-apache
container_name: nextcloud-app
restart: unless-stopped
depends_on:
- db
- redis
ports:
- "8088:80"
environment:
MYSQL_HOST: db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: ncpw-change-me
volumes:
- /volume1/docker/nextcloud/html:/var/www/html
- /volume1/docker/nextcloud/data:/var/www/html/data
The READ-COMMITTED and ROW options are what the Nextcloud documentation requires for MariaDB. I mount data separately so I can exclude the bulky files from a config-only backup.
Step 2: Start it and finish the installer
docker-compose up -d
docker-compose logs -f app
Wait for Apache's "resuming normal operations" line, then open http://<nas-ip>:8088. Create the admin account. Under "Storage & database" choose MySQL/MariaDB with user nextcloud, the password from the YAML, database nextcloud and host db. Click Finish.
Step 3: Add Redis and trusted domains to config.php
The installer does not know about Redis. Edit the configuration on the host:
vi /volume1/docker/nextcloud/html/config/config.php
Add inside the array:
'memcache.local' => '\OC\Memcache\APCu',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => 'redis',
'port' => 6379,
),
'trusted_domains' => array(
0 => '192.168.1.20:8088',
1 => 'cloud.example.synology.me',
),
'overwriteprotocol' => 'https',
The overwriteprotocol line is needed once you put DSM's reverse proxy in front, otherwise Nextcloud generates http:// links and the desktop client loops on login.
Step 4: Put DSM's reverse proxy in front for HTTPS
Control Panel → Application Portal → Reverse Proxy → Create:
- Source: HTTPS, hostname
cloud.example.synology.me, port 443. - Destination: HTTP,
localhost, port 8088.
Assign the Let's Encrypt certificate for that hostname under Control Panel → Security → Certificate → Configure. Forward port 443 on the router to the NAS. DSM's nginx now terminates TLS and passes plain HTTP to the container.
Set a cron job for background tasks with DSM's Task Scheduler (Control Panel → Task Scheduler → Create → Scheduled Task → User-defined script, run as root, every 15 minutes):
docker exec -u www-data nextcloud-app php -f /var/www/html/cron.php
Then in Nextcloud's admin settings, switch Background jobs from AJAX to Cron.
Checking it
Log in over https://cloud.example.synology.me. Open Settings → Administration → Basic settings and check that "Last job ran" updates every 15 minutes. Run the built-in check:
docker exec -u www-data nextcloud-app php occ status
docker exec -u www-data nextcloud-app php occ config:system:get memcache.locking
Install the desktop client on a PC, connect, and confirm files appear under /volume1/docker/nextcloud/data/<user>/files/. Those files are not visible in File Station in a useful way; never edit them there, Nextcloud tracks them in the database.
Things that bit me
- "Access through untrusted domain": the hostname you used is not in
trusted_domains. Add it and reload; no restart needed. - Large uploads through the web interface fail with "413 Request Entity Too Large": DSM's nginx applies its own
client_max_body_sizein front of the container. The reverse proxy GUI has no setting for it; the workaround is a custom nginx include such as/usr/local/etc/nginx/conf.d/nextcloud.confcontainingclient_max_body_size 0;followed bysynoservice --restart nginx, and it may need re-applying after DSM updates. The desktop and mobile clients upload in chunks and are not affected. - Clients keep asking for the password:
overwriteprotocolis missing, so Nextcloud thinks it is serving HTTP. - "Your data directory is readable by other users": the
datafolder was created through File Station with open ACLs. Runchmod 770 /volume1/docker/nextcloud/dataandchown -R 33:33on it (33 is www-data in the image).
Upgrades are docker-compose pull and up -d after bumping the tag one major version at a time; Nextcloud won't let you skip versions, and I learned that by trying. Keep html, data and db in Hyper Backup and the whole thing is portable.