Running Your First Container on Synology Docker
I stopped waiting for Synology to package the software I wanted the day I installed the Docker package. You pull a standard image, run it in its own container, and the NAS itself stays clean. The GUI hides most of the command line, which is nice until you need to know what it actually did.
I always start people on a plain nginx container. It's harmless, and it shows how images, port mappings and volume mounts fit together before you trust a database to it. You need an x86-64 model (DS216+, DS716+, DS918+, DS1517+ and similar; ARM models don't get the package), DSM 6.0 or 6.1, and the Docker package from Package Center. It creates /volume1/docker, which I use for everything.
Pull the image
Open Docker from the main menu and go to Registry. Search for nginx. The result marked "Official" at the top is the one you want. Click Download and pick the latest tag, or a specific one such as 1.13. The image appears under Image once the download completes; nginx is about 100 MB.
The same action from SSH looks like this:
sudo docker pull nginx:1.13
sudo docker images
Everything the GUI does is a Docker API call, so docker images and docker ps from the shell show exactly what the Image and Container tabs show.
A folder for the site content
In File Station, create docker/nginx/html inside the docker shared folder and put an index.html there. From SSH:
sudo mkdir -p /volume1/docker/nginx/html
echo '<h1>Hello from the NAS</h1>' | sudo tee /volume1/docker/nginx/html/index.html
The container will read this folder instead of its built-in default page. Anything not mounted from the NAS disappears when the container is deleted, so any file you care about must live under a mounted folder.
Launching it from the GUI
Under Image, select the nginx image and click Launch. The wizard asks for:
- Container name:
nginx-test. - Execute container using high privilege: leave unticked. It is the
--privilegedflag and almost nothing needs it. - Resource limitation: optional. I set a memory limit of 256 MB on anything experimental so it can't starve DSM. I learned to do that after a runaway container made the whole UI unusable.
Click Advanced Settings:
- Enable auto-restart: tick it so the container comes back after a DSM reboot or package update.
- Volume tab → Add Folder → pick
docker/nginx/html, set the mount path to/usr/share/nginx/html, and tick Read-Only. - Port Settings tab: change the Local Port for container port 80 from Auto to a fixed value such as
8080. Auto assigns a random high port on every start, which is useless for anything you want to bookmark. - Network: leave "Use the same network as Docker Host" unticked. Bridge mode with a port mapping is the default and is the right choice here.
Apply, then Next and Apply again. The container starts within a second or two.
The same thing from the shell
Look at the equivalent command once. The GUI doesn't expose every Docker option, and sooner or later you'll want one it lacks:
sudo docker run -d \
--name nginx-test \
--restart unless-stopped \
-p 8080:80 \
-v /volume1/docker/nginx/html:/usr/share/nginx/html:ro \
nginx:1.13
Containers created from SSH show up in the GUI and can be managed there, with one caveat: the GUI's Edit dialog will not display settings it does not understand, and saving from there can drop them. If you create something from the shell, keep managing it from the shell.
Did it work?
Open http://nas-ip:8080/ in a browser. You should see the heading from your index.html. Check the container's state and logs:
sudo docker ps
sudo docker logs nginx-test
sudo docker inspect nginx-test --format '{{.HostConfig.PortBindings}}'
The Container tab in the GUI shows CPU and memory per container, and Details → Log shows the same output as docker logs.
Edit index.html on the NAS and refresh the browser. The change is immediate because the folder is mounted, not copied.
Things that went wrong for me
- "Local port 8080 conflicts with other ports used by other services" when applying the wizard: another container or a DSM package already owns that host port. Pick another one, or find the holder with
sudo netstat -tlnp | grep 8080. - The container starts and immediately stops, and
docker logsshowsnginx: [emerg] open() "/usr/share/nginx/html" failed (13: Permission denied). The mounted folder is not readable by the container's user. Runsudo chmod -R o+rX /volume1/docker/nginxor, for images that support it, set thePUID/PGIDstyle environment variables to a NAS user. - Ports 80 and 443 cannot be used as local ports even though nothing appears to be listening. DSM's own nginx binds them for the HTTP to HTTPS redirect and for Web Station. Use a high port, or publish through Control Panel → Application Portal → Reverse Proxy.
- After a Docker package update all containers are stopped. That is expected; anything with auto-restart enabled comes back automatically, anything without it needs a manual start.
Every other container I run follows the same pattern: pull, mount what must persist, pin the port, turn on auto-restart. MariaDB is next, where the mounted folder is the difference between a database and a very fast way to lose one.