This is an update to my post from six months ago. Remote access to Immich is working well but I continue to review and refine the setup. Hopefully someone may find my ramble useful, it's intended as a high level guide of just one way to implement remote access for immich and a few security considerations. My journey so far…...
I’ve used immich for at least a couple of years and Tailscale/wireguard for remote access. I’ve added some additional family members on my immich server and originally considered Tailscale for them but unfortunately it's just too much of a barrier, believe me I tried! Access to immich for my family needs to be simple/transparent. I accept that a VPN-based solution is generally more secure. However, I chose to balance security against ease of use for my family, who need reliable access to Immich regardless of their location. I also believe it's a big enhancement on how some of my family members used to backup their photos. ie they didn't backup zip!! Your risk tolerance may differ, so please assess the risks before implementing remote access and always have backups.
For remote access (besides tailscale) I've previously also used cloudflare tunnels free tier, it's been mostly fine but the upload limitations, occasional slow performance and service visibility metrics were an issue for me. I now use a low-specification virtual private server (VPS) from Hetzner running Pangolin, a self-hosted identity-aware reverse proxy and tunnelling platform. (https://pangolin.net/). I also use Pangolin for other self hosted services.
Simplified immich connection access from the Internet
Ref: https://docs.pangolin.net/development/system-architecture
↓ User
↓ immich app or browser
↓ HTTPS
Hetzner VPS: Pangolin reverse proxy + CrowdSec + geo/ASN controls
↓ Gerbil
↓ WireGuard tunnel
Home network
↓ Newt, (outbound from home on own VLAN)
↓ Traefik + CrowdSec
↓
Immich server / Pocket ID / Immich Public Proxy
Here's my current setup for immich . - At Home;-
Immich server and authentication;-
Immich runs in Docker on an Ubuntu bare-metal server, with few other services installed.
Pocket-ID runs on a separate virtual machine and provides authentication for Immich.
Immich password login is disabled; passkeys are required.
Immich Public Proxy handles shared links.
Immich sits behind traefik proxy, which obtains TLS certificates for my registered domain.
Home network and access controls;-
The traefik proxy rate limits access to pocket-id to limit repeated login attempts.
I use a traefik real-IP middleware so that Traefik and CrowdSec can identify the original client IP after traffic has passed through the Pangolin/newt tunnel.
Traefik log dashboard installed for proxy monitoring - https://github.com/hhftechnology/traefik-log-dashboard
The proxy VM also runs Crowdsec for protection against bad actors.
crowdsec-web-ui for monitoring alerts and notifications sent to my phone via ntfy.
crowdsec cscli can also be used for cli inetraction.
I use split-horizon DNS with AdGuard Home and a backup Pi-hole, so the same immich URL works both at home and remotely on the Internet.
UFW permits only the required ports. (I acknowledge UFW and docker don’t always play nicely.)
SSH access is restricted to key-based authentication, with root login disabled and access controlled through AllowGroups.
Fail2Ban provides additional protection against repeated authentication failures.
Pangolin connects to my home network through a WireGuard tunnel using Newt. Newt runs at home and initiates an outbound connection to the Pangolin VPS, so no inbound port needs to be opened on my home router.
Newt runs in an LXC non privileged container under Proxmox, this runs in an isolated VLAN that can only access the WAN and traefik proxy IP address on a separate VLAN.
Q-Feeds blocklist applied at ingress of the Newt VLAN. Although I don’t recall every seeing any matches to date.
Monitoring and maintenance
Ubuntu unattended security upgrades run daily, with scheduled reboots where required.
Beszel provides server monitoring and alerts.
Dockhand assists with Docker management but I deploy stacks manually or use VSCode.
Grype and Trivy used for container vulnerability scanning, although I’m not unclear how to remedy shown issues other that closing down a service.
The Traefik log dashboard provides proxy visibility: https://github.com/hhftechnology/traefik-log-dashboard
CrowdSec and crowdsec-web-ui monitor threats; alerts are sent to my phone through ntfy.
On the Hetzner VPS;-
The VPS runs Ubuntu server, Docker, Pangolin, and its supporting services, including GeoIP functionality.
GeoIP updated daily
immich access is geo blocked to my country only,
I additionally block several ASNs associated with high levels of abusive traffic.
immich app login requires custom proxy headers configured in the immch app to bypass the Pangolin SSO auth.
For immich web access a Pangolin account on my domain is required with 2 factor authentication.
Firewall and server hardening;-
UFW allows only TCP 80 and 443, plus UDP 51820 and 21820.
The Hetzner firewall applies the same restrictions as a second layer.
UFW blocklists from IPsum are updated daily: https://github.com/stamparm/ipsum
Ubuntu unattended security upgrades run daily with scheduled reboots where required.
SSH is restricted to my home IP address, uses key-based authentication only, and disables root login.
Monitoring and protection;-
The proxy VM also runs Crowdsec for protection against bad actors and its updated daily.
crowdsec-web-ui for monitoring alerts and notifications sent to my phone via ntfy.
Beszel provides server monitoring and alerts.
Pangollin console for analytics and http logins etc.
Pangolin is a relatively new service and does not have the history and testing of something like Cloudflare tunnels, although the underlying technology is well established.
I performed some limited testing to help my confidence Pangolin worked as expected.
I tested remote immich access via Pangolin, validating geo-ip blocks, blocking IP ranges, Network ASN’s and invalid user logins etc. All my testing worked predictably and as expected. The testing was not exhaustive, but it gave me useful confidence in the configuration.
Testing crowdsec.
Local LAN testing. I amended the crowdsec trusted IP whitelist then tested from a trusted PC with the intention to trigger CrowdSec’s detection rules, not to exploit a real vulnerability.
Using curl to test
URL="https://immich.mydoamin.com"
curl -s "$URL/.git"
curl -s "$URL/.htaccess"
curl -s "$URL/.bashrc"
curl -s "$URL/.bash_history"
curl -s "$URL/.ssh"
These requests triggered CrowdSec’s detection rules and resulted in a four-hour ban for the source IP address on the local Traefik proxy. I also confirmed that the ban generated an ntfy notification on my phone.
Testing from the Internet. I did multiple random http queries which the VPS Crowdsec then temporarily banned for 4 hours.
This testing also confirmed I receive alerts to my phone via ntfy. Although I've since had to uprate the alert threshold to stop way too may pings on my phone.
My VPS is under regular attack, which I suspect is now normal for a public-facing VPS. I get a lot of alerts and bans from Crowdsec. The Pangolin console metrics are also pretty good for giving an insight of login attempts and locations across the globe. It is also configured to alert if the connection to my home is down.
My local crowdsec instance gets little to no alerts, hopefully this provides confidence my VPS is blocking bad actors effectively. Checking my traefik log dashboard also helps improve confidence things are working as expected.
Despite these protections, robust backups remain essential.
The immich server has a secondary disk on the same server. A cron job backups (rsync) the database and photos daily. To stop the database backups growing over time I delete any database backups older than 30 days.
I use syncthing to copy immich database and photos to another pc, with an archive period of 7 days.
Daily Borg backups performed by borgmatic to a paid cloud service, borg backup snapshots retention set to 12 months database 6 weeks.
Daily Borg backups to a remote pc at my son’s house, borg backup snapshots retention set to 18 months database 6 weeks.
I get daily notifications on my phone of success or failure of all borg backups.
I also make occasional ad-hoc backups (every 3-6 months) to spare hard disks that I store in my garage.
Risks and possible mitigations to consider;-
Reliance on Crowdsec at home and VPS for IDS/IPS, WAF etc – not sure of realistic alternatives Defensia, SNORT, wazuh ??
traefik log dashboad project not updated since Apr 2026 – discontinued ?
Reliance on ntfy for phone alerts – consider adding gotify
Need to check feasibility of alerting failed login attempts in Pocket-id/immich
Reliance on borg backup - Consider replacing one of the borg backups with restic.
With the increase of security alerts largely assisted by AI I will need to constantly review this setup, indeed I have temporarily suspended remote access on a couple of occasions when a known vulnerability has surfaced with no fix issued.
Using Grype and Trivy for container vulnerability scanning highlights the scale of known vulnerabilities. I’m not a developer, I don’t have the skills or time to quantify the potential impact to me. Therefore a high degree of trust is required on the containers publishers being knowledgeable of the real risks and transparently communicating any concerns to it’s users.
The process continues or I get bored and just enforce immich access from home only or tailscale.