تخطي إلى المحتوى الرئيسي
Microsoft
separator
https://catalogartifact.azureedge.net/publicartifacts/lynxroute.immich-947b7de2-57c7-41ac-bf1d-45647e96cfa4/image3_Azureready.png

Immich - Hardened Self-Hosted Photo Backup

بواسطة Lynxroute

Immich 3.2.4 - CIS Level 1 hardened self-hosted photo backup with ML search on Ubuntu 24.04 LTS

What is Immich

Immich is an open-source self-hosted photo and video backup platform - a private alternative to Google Photos and iCloud. The stack runs as four docker containers: a Node and Python server exposing the REST API and web UI, a Python ML container running CLIP for natural-language smart search and face detection, PostgreSQL 14 with VectorChord and pgvecto.rs for embedding queries, and Valkey 9 (Redis-compatible) for cache and queues. The iOS and Android apps perform background auto-upload at full original quality with EXIF and GPS metadata preserved. Operators get shared albums, public links, multi-user libraries with quotas, partner sharing, external libraries, RAW support, and HEIC and HEVC transcoding.

Why self-host Immich

Self-hosting puts every photo, every face embedding, and every ML inference inside your own Azure tenant - no per-seat SaaS fee, no third-party access to private albums. Ideal for households leaving Google Photos or iCloud, photographers with RAW workflows that exceed free-tier quotas, and organisations with data residency requirements under GDPR or similar frameworks. AGPL-3.0 license, no vendor lock-in.

What this VM image adds

Security hardening:

  • No pre-seeded admin account - on first visit the Immich web UI prompts you to register the first user, who becomes the admin. Immich auto-locks admin sign-up once the users table is non-empty, so subsequent attempts are rejected without operator action
  • PostgreSQL password generated at first boot - 32 random characters, written into /opt/immich/.env (mode 0640), never baked into the image
  • All four containers reachable only via the docker bridge - host port 2283 is bound to 127.0.0.1 only, the only public-facing endpoint is Nginx on TCP 443
  • Nginx reverse proxy with TLS - HTTP to HTTPS redirect, hardened cipher suite, WebSocket support, security headers, 50 GB client_max_body_size for RAW and 4K uploads
  • All four container images pre-pulled at build time so first launch is fast and not dependent on upstream registry availability
  • Docker daemon log rotation pre-configured to prevent json-file logs from filling the root volume
  • UFW firewall - only TCP 22, 80, 443 are exposed; fail2ban for SSH brute-force protection; AppArmor mandatory access control
  • CVE scan - every image is scanned for vulnerabilities with Trivy before release
  • Certbot pre-installed - one command issues a Let's Encrypt certificate after you point a domain at the VM

OS hardening (CIS Level 1):

  • CIS Level 1 hardened - CIS Ubuntu 24.04 LTS Level 1 Benchmark via ansible-lockdown
  • auditd - system call auditing for critical paths
  • SSH hardening - PasswordAuthentication disabled, key-only access
  • Kernel hardening - SYN cookies, ASLR, rp_filter, TCP BBR
  • /tmp as tmpfs - nosuid, nodev, noexec
  • Azure IMDS endpoints - egress rules pre-configured (169.254.169.254, 168.63.129.16)

Compliance artifacts (inside the VM):

  • SBOM - CycloneDX 1.6 at /etc/lynxroute/sbom.json
  • CIS Conformance Report - OpenSCAP HTML at /etc/lynxroute/cis-report.html
  • Tailored CIS profile - /usr/share/doc/lynxroute/CIS_TAILORED_PROFILE.md
  • Server credentials file - /root/immich-credentials.txt with web UI URL, mobile-app endpoint, the per-instance PostgreSQL password, and stack-management commands (no admin email/password - the operator registers the first admin via the web UI)

Quick Start

  1. Deploy VM from Azure Marketplace (Standard_D2s_v3 or larger recommended)
  2. Open NSG: TCP 443 from YOUR IP/32 only (widen after admin registration), TCP 80 if you want Let's Encrypt, TCP 22 from management IPs
  3. SSH: ssh -i key.pem azureuser@<PUBLIC_IP>
  4. Read connection details: sudo cat /root/immich-credentials.txt
  5. Open https://<PUBLIC_IP>, accept the self-signed cert, click Sign up - the first registered user becomes the admin. Sign-up auto-locks afterwards
  6. Install the Immich app, set Server URL to https://<PUBLIC_IP>/api, log in, enable Background Backup
  7. Public TLS: sudo certbot --nginx -d your.domain.com

The photo library lives at /opt/immich/library and Postgres data at /opt/immich/postgres - attach an Azure Managed Disk there for libraries larger than the root disk.

العربية (ليبيا)
أيقونة إلغاء الاشتراك في اختيارات خصوصيتك خيارات خصوصيتك
خصوصية صحة المستهلك خريطة الموقع اتصل بنا الخصوصية وملفات تعريف الارتباط شروط الاستخدام حول إعلاناتنا إدارة ملفات تعريف الارتباط