Synology access and troubleshooting
For a new Container Manager project, use Synology setup.
The recipes below cover release files over SSH and alternative access routes. The .env
examples apply to the two-file release installation. With the builder's single file, set the
same values directly in the app service's environment and ports entries.
SSH/Compose installation from published files
This is a separate route from the Project wizard. On the NAS, enable SSH for an approved account and open a terminal in a new app-only directory under your DSM home. Follow Quick start, Download the files there, using that documentation build's published assets. A preview without downloads cannot supply this prebuilt route. Never use the Immich project's directory.
Edit .env on the NAS: set IMMICH_URL, IMMICH_API_KEY, TZ, and keep TIER=basic and
UI_BIND_ADDRESS=127.0.0.1. Use the ten read permissions.
From the resulting immich-memories project directory on the NAS:
chmod 700 .
chmod 600 .env
mkdir -p output
/usr/syno/bin/synoacltool -addace output user:1000:allow:rwxpdDaARWc--:fd--
/usr/syno/bin/synoacltool -addace output user:$(id -un):allow:rwxp-DaARWc--:fd--
sudo docker compose -p immich-memories pull
sudo docker compose -p immich-memories up -d
sudo docker compose -p immich-memories exec immich-memories immich-memories models fetch
sudo docker compose -p immich-memories exec immich-memories immich-memories preflight
The two synoacltool lines give the container's uid 1000 write access to output and keep your
DSM user able to read and remove the files. Without the second entry, the ACL can deny your own
account access to the folder. See the output folder for why chown
isn't enough. Run every later Compose command from this directory with -p immich-memories;
the explicit project name also determines its named volume prefix.
For French films, open Settings, set title_screens.locale to French and save.
For a file-based setting, add locale: fr under title_screens: in config.yaml.
Automatic language detection reads the container's locale, not DSM's. Adding LANG to .env
has no effect because the release Compose file does not pass it into the container.
This stock release-file route uses host port 22830. If occupied, change only the number before
:8080 in the port line, so it reads ${UI_BIND_ADDRESS:-127.0.0.1}:18081:8080.
Keep ${UI_BIND_ADDRESS:-127.0.0.1}: the LAN route depends on it. Use the new NAS port in the
tunnel and proxy destinations below.
When you script these commands over ssh, docker compose exec can consume the script's stdin.
Change to the project directory in the remote script, and add -T and </dev/null to each
Compose exec command so the next script line stays available. Scripted Docker commands also
need permission to run without an interactive sudo password prompt.
On your desktop, the permitted-tunnel route is:
ssh -o ExitOnForwardFailure=yes -L 8080:127.0.0.1:22830 your-user@your-nas
Keep that session open and visit http://localhost:8080 on the desktop. If you changed the NAS
port to 18081, use -L 8080:127.0.0.1:18081; the browser URL stays the same. If forwarding is
denied, use either the HTTPS proxy or
LAN port with app login below.
Authenticated proxy when forwarding is disabled
Use DSM's HTTPS reverse proxy on the NAS with application Basic auth. The app remains
published on 127.0.0.1:22830; there is no unauthenticated LAN mapping in this procedure.
memories.example.com below is an example: substitute your LAN DNS name and its valid TLS
certificate, already configured on the NAS. This does not require internet exposure or router forwarding.
-
On the NAS, edit the project's
.envand set bothIMMICH_MEMORIES_AUTH_USERNAMEandIMMICH_MEMORIES_AUTH_PASSWORDto your chosen login and a unique password of at least 12 characters. KeepUI_BIND_ADDRESS=127.0.0.1. -
In
docker-compose.yml, under the app'senvironment, addIMMICH_MEMORIES_AUTH__PUBLIC_URL: https://memories.example.comandIMMICH_MEMORIES_SERVER__SECURE_COOKIES: "true". Configure the exact proxy peer asIMMICH_MEMORIES_AUTH__TRUSTED_PROXIES: '["YOUR_PROXY_PEER_IP"]'using the peer-address check. Keep these edits in your deployment files;.envalone passes only variables the Compose file references. -
Recreate the app on the NAS, before creating/enabling the proxy:
sudo docker compose -p immich-memories up -dcurl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:22830/api/v1/settingsThe protected settings endpoint must answer 401 without a session (and 200 after login). Add
-u user:passwordand it still answers 401: the login is a form that sets a session cookie, not HTTP Basic, socurl -unever signs in. To test the 200, sign in the way the page does and reuse its cookie, see Checking auth with curl. Stop if it returns settings. The public health endpoint is deliberately anonymous and is not an auth test. -
In DSM Control Panel → Login Portal → Advanced → Reverse Proxy, create a source HTTPS, hostname
memories.example.com, port 443, and destination HTTP, hostname127.0.0.1, port 22830 (or your chosen host port). Assign the matching certificate in DSM's certificate settings. PreserveHost, setX-Forwarded-Prototohttps, and overwrite forwarded client headers as in the proxy checklist. Menu labels depend on DSM; this GUI sequence still needs the validation below. -
On a second LAN machine, open a private browser window at
https://memories.example.com. Confirm it requires app login before showing settings or media. Sign in, then follow the bounded trial. -
Restart with
sudo docker compose -p immich-memories restart, and repeat the signed-out, login and saved-run checks from the second machine.
| Symptom | Check |
|---|---|
| 502 or connection refused | Proxy destination is HTTP to the NAS loopback host port, not HTTPS or container port 80; check sudo docker compose -p immich-memories ps |
| Login works over HTTP but fails through HTTPS | Check public URL, secure cookies, actual trusted peer and forwarded protocol; use the auth guide |
| Wrong password / temporary lockout | Use the app login from .env, not the DSM password; repeated failures trigger the documented rate limit |
| Output permission failure | Check this project's output owner and DSM ACLs, then rerun preflight; do not change Immich's media directories |
LAN port with app login (no tunnel, no proxy)
If your account can't forward ports and you don't want to set up the proxy, publish the port on the LAN with app authentication on. Do it in this order, from the project directory on the NAS:
- In
.env, set the login:IMMICH_MEMORIES_AUTH_USERNAME=adminandIMMICH_MEMORIES_AUTH_PASSWORD=a long password of your own (12 characters or more). - In the same file, set
UI_BIND_ADDRESS=0.0.0.0. - Start it:
sudo docker compose -p immich-memories up -d.
From a second machine, /api/v1/settings, thumbnails and film downloads should answer 401
without a session and 200 after login, and both should survive restart and down/up.
The port is plain HTTP, so the password and cookie are visible on your LAN; the proxy route above
is the one with TLS. /health/ready stays anonymous: it returns readiness status and the app
version, with Immich details set to null until you sign in. It cannot confirm that login is
required.
Checking auth with curl
The app's "Basic auth" is a username and password typed into a login form. It does not read an
HTTP Authorization: Basic header, so curl -u user:password .../api/v1/settings gets 401 whatever
the password. Sign in over /auth/login, keep the cookie, and ask again:
Set memories_url to the URL you use in the browser. For the proxy route, use
https://memories.example.com: its secure session cookie is not sent over plain HTTP.
Replace the sample credentials with your app login. The example below uses the default host port,
22830; use your installation's URL.
memories_url=http://nas-address:22830
umask 077
curl -fsS -c jar.txt -H 'Content-Type: application/json' \
-d '{"username":"admin","password":"your-password"}' "$memories_url/auth/login"
curl -sS -b jar.txt -o /dev/null -w '%{http_code}\n' "$memories_url/api/v1/settings" # 200
rm jar.txt
A wrong password gets 401. Repeated failures trigger the rate limit and return 429.
See the deployment matrix for which of these routes have a verified first run on this platform, and what still needs a report.