Bootstrap your Synology NAS setup with automatic provisioning for: filesystem structure, shares, docker user, docker group, 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]
int[watchtower/cloudflare-ddns]
postgres
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-1525
or higher. At the time of writing, this version is only available by joining the Beta program. Only this version supports Docker Composeinclude
statements, 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
.
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 scripts. Configure as specified in the comments of each file. All scripts are idempotent and designed for repeated use without damaging an existing setup.
-
filesystem.sh creates the filesystem structure, shares, docker user, docker group and permissions (inspired by DrFrankenstein), also modifies
.env
file variables. -
routedocker.sh fixes the iptables for docker (introduced by Pedro Lamas).
-
freeports.sh frees port 443 and 80 for own use.
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
andcloudflare-ddns
as internal services without inbound traffic. -
Configures
caddy
as reverse proxy for all inbound traffic. -
Provisions
postgres
as a service via port 6432. -
Provisions
qBittorrent
as a service via port 50777. -
Provisions
coreDNS
as 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 |
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 subnets
and add0.0.0.0/0
as value since we use tinyauth instead. -
Change the listening port to
50777
for incoming connections.
-
Go to
Settings
-Connections
and configureJellyfin
with:Host
-jellyfin
Port
-8096
-
Go to
Settings
-General
and setAuthentication Required
toDisabled for Local Addresses
since we use tinyauth instead.
-
Go to
Settings
-Apps
and configureRadarr
with:Prowlarr Server
-http://prowlarr:9696
Radarr Server
-http://radarr:7878
-
Go to
Settings
-General
and setAuthentication Required
toDisabled for Local Addresses
since we use tinyauth instead.
- Go to
Settings
-Radarr
and configureRadarr
with:- Enabled -
true
- Host Address -
radarr
- API Key - add from
Radarr
-Settings
-General
-API Key
- Enabled -
- Go to
Settings
-Languages
and configure via bazarr languages guide. - Go to
settings
-Providers
and configure via bazarr providers guide forOpenSubtitles.com
,Supersubtitles
andGestdown (Addic7ed proxy)
. - Set the language profile for existing media, via bazarr - First Time Installation Configuration.
- Make sure to create an
init.sql
file 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.