Bootstrap your Synology NAS setup with automatic provisioning for: filesystem structure, shares, users, groups, permissions, network, container orchestration and .env variables. Just configure the scheduled tasks and the Docker Compose .env file with your own dns and folder variables, that's it.
Makes use of the Synology CLI (pdf), Synology Task Scheduler and Synology Container Manager.
Following is the partial network design. Refer to the code for full details.
flowchart TD
subgraph access[DNS Access layer]
privateservices[http://
code/whoami/qbittorrent/jellyfin/dozzle/based
.yourinternal.domain.wow
]
externalservices[https://
whoami/based
.yourexternal.domain.wow
]
end
subgraph router L3
6432[port 6432]
80[port 80]
443[port 443]
end
subgraph cr7[frontend Caddy L7]
extendspe[docker extends service/private]
extendspub[docker extends service/public]
extendscr7[docker extends service/base]
end
subgraph cr4[frontend Caddy L4]
extendscr4[docker extends service/base]
end
subgraph cm[backend containers]
postgres
int[watchtower/cloudflare-ddns]
ext[whoami]
prv[whoami/dozzle/jellyfin/qbittorrent/code]
end
privateservices -- A record '*.yourinternal' to local NAS ip --> 80 --> extendspe
6432 --> extendscr4
externalservices -- A record '*.yourexternal' to public ip (DDNS) --> 443 -- port forwarding to local NAS ip --> extendspub
extendscr7 --> int
extendscr4 --> postgres
extendspub --> ext
extendspe -- private_ip_range check -->prv
A Synology NAS, including:
-
Container Manager
24.0.2-1525or higher. Only this version supports Docker Composeincludestatements, introduced in Docker compose 2.20.3, which this project uses. -
A compatible DSM version, confirmed to work on
7.2.2-72806(Update 2 and 3).
Place the entire project (repo) structure inside of your NAS with path /volume1/docker/projects (replace volume1 with your own volume). You end up with /volume1/docker/projects/garden.
Change the filename of .env.example to .env and use your own values.
Remove the .example postfix of the files in the secrets folder and use your own values.
The tasks folder provides boot-up and shutdown scripts.
For shutdown, configure garden/tasks/main-shutdown.sh as specified in the comment of that script.
For boot-up, configure garden/tasks/main.sh as specified in the comment of that script. The following scripts are part of main:
-
filesystem.sh creates the filesystem structure, shares, users, groups and permissions (inspired by DrFrankenstein), also modifies
.envfile variables. -
configuredocker.sh fixes the iptables for docker (introduced by Pedro Lamas) and sets the group permissions for docker socket.
-
freeports.sh frees port 443 and 80 for own use.
All scripts are idempotent and designed for repeated use without damaging an existing setup.
The docker-compose.yaml file configures all containers. Create a project called garden in Container Manager based on this file, and fill in the variables in the .env file. It does the following:
-
Provisions
watchtower,cloudflare-ddns-privateandcloudflare-ddns-publicas internal services without inbound traffic. -
Configures
caddyas reverse proxy for all inbound traffic. -
Provisions
postgresas a service via port 6432. -
Provisions
qBittorrentas a service via port 50777. -
Provisions
ibm-mqas a service via port 1414. With listenerDEV.LISTENER.TCP, channelDEV.APP.SVRCONN, queue managerQM1, queueDEV.QUEUE.1and cert authentication. -
Provisions
coreDNSas a service via port 53 (udp and tcp). -
Provisions the following http/https services:
| public | Uri | Authentication |
|---|---|---|
| yes | https://auth.domain.wow | tinyauth itself |
| yes | https://whoami.yourexternal.domain.wow | tinyauth |
| yes | https://based.yourexternal.domain.wow | DSM |
| no | http://based.yourinternal.domain.wow | DSM |
| no | http://jellyfin.yourinternal.domain.wow | jellyfin |
| no | http://code.yourinternal.domain.wow | tinyauth |
| no | http://whoami.yourinternal.domain.wow | tinyauth |
| no | http://qbittorrent.yourinternal.domain.wow | tinyauth |
| no | http://dozzle.yourinternal.domain.wow | tinyauth |
| no | http://radarr.yourinternal.domain.wow | tinyauth |
| no | http://bazarr.yourinternal.domain.wow | tinyauth |
| no | http://prowlarr.yourinternal.domain.wow | tinyauth |
| no | http://ibmmq.yourinternal.domain.wow/ibmmq/console | tinyauth |
If not public, it's;
- blocking any traffic that doesn't originate
private_ip_range; - only resolvable locally.
Transcoding settings in jellyfin admin dashboard, under http://jellyfin.yourinternal.domain.wow/web/#/dashboard/playback/transcoding. Specific for each CPU, assumes you're using a Gemini Lake Refresh model. Check for init_hw_device in logs to confirm it's working.
Hardware acceleration: Intel QuickSync
Enable hardware decoding for:
- H264
- HEVC
- MPEG2
- VC1
- VP8
- VP9
- HEVC 10 bit
- VP9 10 bit
- Prefer OS native DXVA or VA-API hardware decoders
Hardware encoding options:
- Enable hardware encoding
- Allow encoding in HEVC format
- Enable VPP Tone mapping
- Enable Tone mapping
-
Default username:
admin, password is printed in container log first time. Go toOptions-WebUI-Authentication- checkBypass authentication for clients in the whitelisted IP subnetsand add0.0.0.0/0as value since we use tinyauth instead. -
Change the listening port to
50777for incoming connections.
-
Go to
Settings-Connectionsand configureJellyfinwith:Host-jellyfinPort-8096
-
Go to
Settings-Generaland setAuthentication RequiredtoDisabled for Local Addressessince we use tinyauth instead.
-
Go to
Settings-Appsand configureRadarrwith:Prowlarr Server-http://prowlarr:9696Radarr Server-http://radarr:7878
-
Go to
Settings-Generaland setAuthentication RequiredtoDisabled for Local Addressessince we use tinyauth instead.
- Go to
Settings-Radarrand configureRadarrwith:- Enabled -
true - Host Address -
radarr - API Key - add from
Radarr-Settings-General-API Key
- Enabled -
- Go to
Settings-Languagesand configure via bazarr languages guide. - Go to
settings-Providersand configure via bazarr providers guide forOpenSubtitles.com,SupersubtitlesandGestdown (Addic7ed proxy). - Set the language profile for existing media, via bazarr - First Time Installation Configuration.
- Make sure to create an
init.sqlfile containingALTER ROLE admin SUPERUSER;, or similar, and place it into${host_data_config_path}/postgres/scripts, this folder is mounted in/docker-entrypoint-initdb.d/so postgres picks this up.
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
