Well, I solved it! …sort of.
Still unsure why photos aren’t syncing with the regular /e/Cloud server…but what I’ve learned thus far is that a good amount of what I’d like to do can be performed by appending it! Here’s my tutorial for implementing Immich, a self-hosted photo management app. It also includes some AI stuff that does facial recognition and a few other things, so it’s a bit more robust than standard Nextcloud photo syncing. Also, be aware that, especially during the initial upload and cataloguing, it will peg that CPU needle at 100% for quite a while…so if you’re paying by the CPU cycle…read the documentation to avoid the use of its photo analysis.
Here’s my tutorial:
- Add a subdomain to your registrar’s DNS records, just like you did with mail., autodiscover., and so on. Point it to the same IP, and wait a few minutes for the record to propagate (photos.voyager529.com for this example)
- SSH into your server (192.168.1.2 for this example).
- Add the domain to the autorenew list and get a cert:
a. nano /mnt/repo-base/config/letsencrypt/autorenew/ssl-domains.dat
b. add the domain to the bottom of the list; Ctrl+X to quit, save when prompted.
c. docker stop nginx
d. cd /mnt/repo-base/scripts && ./ssl-renew.sh
nano `/mnt/repo-base/.env
and append it with these environment variables:
a. #immich
: a friendly comment to help isolate issues later (documentation is a love letter you write to your future self).
UPLOAD_LOCATION=/mnt/immich/library
a folder where photos go; be sure it exists.
DB_DATA_LOCATION=/mnt/immich/db
a folder where the database goes; be sure it exists.
TZ=UTC
your time zone; this is helpful for finding photos later.
IMMICH_VERSION=release
…I’m assuming there are other releases, but I’m not crazy, so ‘release’ it is
DB_PASSWORD=omgwtfbbqchangeme12345
Database Password; make your own, this isn’t mine.
DB_USERNAME=postgres
default; no real reason to change it
DB_DATABASE_NAME=immich
default; no real reason to change it.
b. Ctrl+X, save when prompted.
nano /etc/repo-base/docker-compose.yml
; append the file with the docker-compose section below.
cd /mnt/repo-base && docker-compose up -d
; let it do its magic.
- Open a web browser and go to http://192.168.1.2:2283. Go through the initial post-install config and create your account.
nano /mnt/repo-base/config/nginx/sites-enabled/photos.voyager529.com.conf
, and add the nginx config section below (please read the comments)
docker restart nginx
; test on your phone to see that you can access the website.
Now, download the app on your phone, point it to your instance, and you can let it handle your photo uploads!
Two things to note before I get to the files:
First, I removed all the GPU acceleration options from the software; I might be the weirdo who self-hosts on actual hardware instead of a VPS, but I would be fairly surprised if anyone is running this somewhere that’s got a GPU and would benefit from its use here. If you want to add it, you can, but go consult the Immich documentation regarding the process (it’s just a few extra lines in the docker-compose).
Second, my particular version of docker didn’t like Immich’s health check intervals, so I removed them as some other forum posters did. It may take them a bit to show up as ‘healthy’ as a result, but it’s purely cosmetic, which is why they’re not present here.
Without further ado…
the docker-compose file for Step 5 (again, ADD to the bottom of your EXISTING docker-compose.yml)
docker-compose
name: immich
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
ports:
- 2283:3001
depends_on:
- redis
- database
restart: always
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
- model-cache:/cache
env_file:
- .env
restart: always
redis:
container_name: immich_redis
image: docker.io/redis:6.2-alpine@sha256:328fe6a5822256d065debb36617a8169dbfbd77b797c525288e465f56c1d392b
healthcheck:
test: redis-cli ping || exit 1
restart: always
database:
container_name: immich_postgres
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
healthcheck:
test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='S>
# interval: 5m
# start_interval: 30s
# start_period: 5m
command: ["postgres", "-c" ,"shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", ">
restart: always
volumes:
model-cache:
And, the nginx config from step 8:
yoursubdomain.conf
server {
listen 8000; #YES THIS IS THE CORRECT PORT
server_name photos.voyager529.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 4430 ssl http2; #YES THIS IS THE CORRECT PORT
server_name photos.voyager529.com;
#replace these if you're using commercial certs
ssl_certificate /certs/live/photos.voyager529.com/fullchain.pem;
ssl_certificate_key /certs/live/photos.voyager529.com/privkey.pem;
include /etc/nginx/params/ssl_params;
include /etc/nginx/params/headers_params;
client_max_body_size 50000M; #from Immich documentation; make smaller if needed
# Set headers
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# enable websockets: http://nginx.org/en/docs/http/websocket.html
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
# set timeout
proxy_read_timeout 600s;
proxy_send_timeout 600s;
send_timeout 600s;
location / {
proxy_pass http://immich_server:3001; #YES THIS IS THE CORRECT PORT
}
}
Hope it helps someone else who’s either having issues with photo syncing, or prefers some of Immich’s more robust features!
@smu44, always up for your input…and @manoj , feel free to edit the original post with how-to tags if it’d be helpful.