Featured image
Info

Homelab Series Index

Digital freedom: creating a personal service ecosystem without depending on big tech.

  1. Homelab: Necessity or Whim?
  2. Homelab: Proxmox and LXC Containers
  3. Homelab: Immich Setup
  4. Homelab: Navidrome Setup
  5. Homelab: Secure Remote Access
  6. Homelab: Migrating from iCloud to Immich
  7. Homelab: Paperless-NGX and Document Management

From Test Container to Production Deployment Link to heading

In the previous article we configured Proxmox, created a test LXC container, and installed Docker. Now it’s time to get serious: create a dedicated container for Immich and configure the final external storage.

Info
Unlike other photo managers, Immich maintains the original structure of photos on the filesystem. This means my files remain accessible and portable - if tomorrow I decided to migrate to another solution, I always have my organized folders ready for transfer.

External Storage Configuration Link to heading

In the previous article we mentioned the strategy of separating system and data. Now we’re implementing this separation concretely by configuring the external disk hermes.

External Disk Setup Link to heading

Connect the 256GB external SSD to the mini PC and proceed with complete configuration:

# FROM PROXMOX HOST - check available disks
lsblk

# Expected output - the new disk should appear as /dev/sda
# sda                            8:0    0 238.5G  0 disk
# nvme0n1                      259:0    0 238.5G  0 disk (system disk)

Formatting and Preparation Link to heading

# FROM PROXMOX HOST

# If disk already has data, clean it
wipefs -a /dev/sda

# Create Linux partition
echo "n
p
1


w" | fdisk /dev/sda

# Format with ext4
mkfs.ext4 -F /dev/sda1

# Label for recognition
e2label /dev/sda1 hermes

Hermes Shared Storage Configuration Link to heading

Configure the hermes disk as Directory Storage in Proxmox to share it between homelab containers.

# FROM PROXMOX HOST - not from container!

# Create mount directory
mkdir -p /mnt/hermes

# Mount the disk
mount /dev/sda1 /mnt/hermes

# Verify it's mounted correctly
df -h /mnt/hermes

# Should show something like:
# /dev/sda1    222G  xxx  xxx  x% /mnt/hermes
# NOT: /dev/mapper/pve-root

Add Hermes Storage to Proxmox Link to heading

Add the disk as Directory Storage in Proxmox:

Via Web Interface Link to heading

  1. Datacenter → Storage → Add → Directory
  2. ID: hermes
  3. Directory: /mnt/hermes
  4. Content: Select Container (VZDump backup files will be available automatically)
  5. Enable: ✓ Enabled

directoryimmich

Make Mount Permanent Link to heading

# FROM PROXMOX HOST

# Get disk UUID
UUID=$(blkid /dev/sda1 -s UUID -o value)
echo "Found UUID: $UUID"

# Add to fstab for automatic mount on reboot
echo "UUID=$UUID /mnt/hermes ext4 defaults 0 2" >> /etc/fstab

# Test mount from fstab
umount /mnt/hermes && mount -a

# Verify it works
df -h /mnt/hermes

Prepare Directory Structure Link to heading

# FROM PROXMOX HOST

# Create directories for services
mkdir -p /mnt/hermes/{immich,navidrome,shared}

# Create subdirectories for Immich
mkdir -p /mnt/hermes/immich/{upload,database,redis-data}

# Verify structure
ls -la /mnt/hermes/

# Output should show:
# drwxr-xr-x immich/
# drwxr-xr-x navidrome/
# drwxr-xr-x shared/
Info
Directory Storage Advantages: Proxmox automatically handles permissions and shareability between containers. Storage is easily expandable and each container sees only its own directory through dedicated mount points.

Immich Mount Point on Hermes Link to heading

Add the specific mount point for Immich to the container, pointing to the immich subdirectory of shared storage:

Via Proxmox Web Interface Link to heading

  1. Select the docker-immich container
  2. Resources → Add → Mount Point
  3. Mount Point ID: mp0 (assigned automatically)
  4. Storage: hermes
  5. Disk size: 32 GB (initial size, expandable)
  6. Path in Container: /immich (where it will be mounted in the container)
  7. Backup: ✓ (recommended for data)
  8. Enable: NOT Enabled

mountpointimmich

Docker Setup in Immich Container Link to heading

Docker installation in the new dedicated container:

# Enter dedicated container
pct enter 102

# Docker setup (same process as test container)
apt update && apt install -y curl
curl -fsSL https://get.docker.com | sudo sh
usermod -aG docker $USER

# Verify installation
docker --version

# Restart to apply docker group
exit
pct reboot 102
pct enter 102

Verify Mount Point Link to heading

# Verify mount point is available
df -h
ls -la /immich/

# Test write
touch /immich/test-write
ls -la /immich/test-write
rm /immich/test-write

# Create necessary directories for Immich
mkdir -p /immich/{upload,database,redis-data}

Immich Setup with Official Guide Link to heading

We follow the official Immich guide for Docker Compose, adapting it to our external storage.

Step 1 - Download Required Files Link to heading

# Create working directory
mkdir -p /root/immich-app
cd /root/immich-app

# Download official docker-compose.yml
wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml

# Download example .env file
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

# Verify files were downloaded
ls -la

Step 2 - .env File Configuration Link to heading

Modify the .env file for our external storage setup:

# Edit .env file
nano .env

Custom .env configuration:

# External storage for photos and backup
UPLOAD_LOCATION=/immich/upload

# Database on external storage
DB_DATA_LOCATION=/immich/database

# Timezone (uncomment and customize)
TZ=Europe/Rome

# Immich version (pinned to release)
IMMICH_VERSION=release

# Database password (change to a secure one!)
DB_PASSWORD=immich_secure_password_123

# Default values (do not modify)
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
Warning
Database Password: Change DB_PASSWORD to a secure password using only A-Za-z0-9 characters. Use pwgen or online generators to create random passwords.

Step 3 - Docker Compose Verification Link to heading

The downloaded docker-compose.yml file is official and up-to-date. For our setup, we should verify it points to the correct paths:

# Verify docker-compose.yml uses .env variables
cat docker-compose.yml | grep -A5 -B5 "UPLOAD_LOCATION\|DB_DATA_LOCATION"
Info
Official Docker Compose: The file downloaded from GitHub automatically uses variables defined in .env to configure volumes. It’s not necessary to manually modify the YAML.

Advanced Configurations Link to heading

For additional customizations, consult the Immich environment variables documentation.

Common Configurations Link to heading

# In .env file, add optional configurations:

# Video transcoding (for external SSD)
# FFMPEG_TRANSCODE=all

# Machine Learning (facial recognition)
# MACHINE_LEARNING_ENABLED=true

# Log level for debugging
# LOG_LEVEL=verbose

Step 4 - Storage Directory Preparation Link to heading

# In container, verify external storage is available
df -h /immich/

# Should show ~47GB available (the hermes disk)
# If showing few GB, check mount point from Proxmox host

# Create directories for Immich
mkdir -p /immich/{upload,database}

# Verify space and permissions
ls -la /immich/
id  # Verify docker group

Step 5 - First Launch Link to heading

Following the official guide, start Immich:

# From project directory
cd /root/immich-app

# Start with Docker Compose (official command)
docker compose up -d

# Check container status
docker compose ps

# Check logs for any errors
docker compose logs immich-server

immichwelcome

Step 6 - Health Check and Troubleshooting Link to heading

# Verify all containers are healthy
docker compose ps

# If there are health check errors with Docker Engine < v25
# Comment out start_interval line in docker-compose.yml
sed -i 's/start_interval/#start_interval/' docker-compose.yml
Tip
For advanced troubleshooting and additional configurations, always consult the official Immich documentation.
Tip
The first startup will require several minutes to download images and initialize the database. The machine-learning container might take extra time to download AI models.

Access and Initial Configuration Link to heading

Once started, Immich will be accessible at http://CONTAINER_IP:2283.

Initial setup:

  1. Create admin account
  2. Configure photo libraries
  3. Install mobile app and test connection
  4. Test upload of some photos to verify functionality

Next Steps Link to heading

With Immich operational and first photos uploaded, the homelab starts coming to life. The first service is online and functional, but there’s still a long road ahead!

The next articles in the series will cover:

  • Automatic container and data backups
  • Container destroy and backup restore tests
  • Migration from iCloud Photos to Immich

→ Continue with: Homelab: Setup Navidrome per Streaming Musicale Privato