feat: add Immich - Google Photo self-hosted alternative
This commit is contained in:
parent
7f93fee6d7
commit
c57f6720d2
@ -1,12 +1,16 @@
|
|||||||
CONTACT_EMAIL=your@email.com
|
CONTACT_EMAIL=your@email.com
|
||||||
|
TIMEZONE=Europe/Berlin
|
||||||
SSH_TO_SERVER=user@server
|
SSH_TO_SERVER=user@server
|
||||||
PATH_APPS=~/apps
|
PATH_APPS=~/apps
|
||||||
PATH_MOVIES=~/movies
|
PATH_MEDIA=~/media
|
||||||
|
PATH_MOVIES=~/media/movies
|
||||||
|
PATH_SERIES=~/media/series
|
||||||
|
PATH_PHOTOS=~/media/photos
|
||||||
HOSTNAME_UPTIME_KUMA=uptime.example.com
|
HOSTNAME_UPTIME_KUMA=uptime.example.com
|
||||||
HOSTNAME_TORRENTS=torrents.example.com
|
HOSTNAME_TORRENTS=torrents.example.com
|
||||||
HOSTNAME_MOVIES=movies.example.com
|
HOSTNAME_MOVIES=movies.example.com
|
||||||
|
HOSTNAME_PHOTOS=photos.example.com
|
||||||
HOSTNAME_GITEA=git.example.com
|
HOSTNAME_GITEA=git.example.com
|
||||||
HOSTNAME_HOME_ASSISTANT=smart.example.com
|
|
||||||
HOSTNAME_HOMEPAGE=ui.example.com
|
HOSTNAME_HOMEPAGE=ui.example.com
|
||||||
HOSTNAME_SAGE=sage.example.com
|
HOSTNAME_SAGE=sage.example.com
|
||||||
HOSTNAME_AQS=example.com
|
HOSTNAME_AQS=example.com
|
23
Makefile
23
Makefile
@ -1,3 +1,4 @@
|
|||||||
|
.PHONY: *
|
||||||
-include .env
|
-include .env
|
||||||
export $(shell sed 's/=.*//' .env)
|
export $(shell sed 's/=.*//' .env)
|
||||||
|
|
||||||
@ -6,7 +7,25 @@ build-homepage:
|
|||||||
mkdir -p ./homepage/dist
|
mkdir -p ./homepage/dist
|
||||||
envsubst < ./homepage/src/index.html > ./homepage/dist/index.html
|
envsubst < ./homepage/src/index.html > ./homepage/dist/index.html
|
||||||
|
|
||||||
|
# Copy files to server
|
||||||
|
copy-files:
|
||||||
|
rsync -avhzru -P -e ssh --include-from='deploy.files.txt' --exclude '*' ./ $(SSH_TO_SERVER):$(PATH_APPS)
|
||||||
|
|
||||||
|
# Create proxy network (so reverse proxy can access other containers), if it doesn't exist yet
|
||||||
|
create-proxy-network:
|
||||||
|
ssh homelab "docker network create proxy 2>/dev/null || true"
|
||||||
|
|
||||||
|
# Deploy main homelab services
|
||||||
|
up-homelab:
|
||||||
|
ssh homelab "cd $(PATH_APPS) && docker compose up -d"
|
||||||
|
|
||||||
|
# Deploy Immich
|
||||||
|
up-immich:
|
||||||
|
ssh homelab "cd $(PATH_APPS)/immich && docker compose --env-file=.env --env-file=../.env up -d"
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
make build-homepage
|
make build-homepage
|
||||||
rsync -avz -e 'ssh' --include-from='deploy.files.txt' --exclude '*' ./ $(SSH_TO_SERVER):$(PATH_APPS)
|
make copy-files
|
||||||
ssh homelab "cd $(PATH_APPS) && docker compose up -d"
|
make create-proxy-network
|
||||||
|
make up-homelab
|
||||||
|
make up-immich
|
||||||
|
@ -27,9 +27,8 @@ Think of movies, TV shows, home videos, music, and pictures.
|
|||||||
### [Gitea](https://github.com/go-gitea/gitea)
|
### [Gitea](https://github.com/go-gitea/gitea)
|
||||||
Gitea is a lightweight self-hosted Git service, similar to GitHub.
|
Gitea is a lightweight self-hosted Git service, similar to GitHub.
|
||||||
|
|
||||||
### [Home Assistant](https://github.com/home-assistant/home-assistant.io)
|
### [Immich](https://immich.app/)
|
||||||
Home Assistant is an open-source home automation platform.
|
Google Photos self-hosted alternative.
|
||||||
For your smart home, it is the software "hub" that allows you to control all your devices.
|
|
||||||
|
|
||||||
### [Homepage](./homepage/src/index.html)
|
### [Homepage](./homepage/src/index.html)
|
||||||
A simple homepage with links to all the services.
|
A simple homepage with links to all the services.
|
||||||
|
77
compose.yml
77
compose.yml
@ -1,4 +1,9 @@
|
|||||||
version: '3.8'
|
version: '3.8'
|
||||||
|
#
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
# Traefik is a reverse proxy and load balancer.
|
# Traefik is a reverse proxy and load balancer.
|
||||||
@ -27,10 +32,13 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "443:443"
|
- "443:443"
|
||||||
- "80:80"
|
- "80:80"
|
||||||
# - "8080:8080"
|
- "8080:8080"
|
||||||
volumes:
|
volumes:
|
||||||
- "./letsencrypt:/letsencrypt"
|
- "./letsencrypt:/letsencrypt"
|
||||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- default
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@ -44,12 +52,6 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./.volumes/uptime-kuma:/app/data
|
- ./.volumes/uptime-kuma:/app/data
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "curl", "-f", "${HOSTNAME_UPTIME_KUMA}" ]
|
|
||||||
interval: 1m
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@ -73,20 +75,14 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- PUID=1000
|
- PUID=1000
|
||||||
- PGID=1000
|
- PGID=1000
|
||||||
- TZ=Asia/Singapore
|
- TZ=${TIMEZONE}
|
||||||
volumes:
|
volumes:
|
||||||
- ./.volumes/transmission:/config
|
- ./.volumes/transmission:/config
|
||||||
- ${PATH_MOVIES}:/downloads
|
- ${PATH_MEDIA}:/downloads
|
||||||
ports:
|
ports:
|
||||||
- 51413:51413 # Default port for torrent traffic
|
- 51413:51413 # Default port for torrent traffic
|
||||||
- 51413:51413/udp # Default port for DHT
|
- 51413:51413/udp # Default port for DHT
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "curl", "-f", "${HOSTNAME_TORRENTS}" ]
|
|
||||||
interval: 1m
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@ -110,14 +106,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./.volumes/jellyfin:/config
|
- ./.volumes/jellyfin:/config
|
||||||
- ./.volumes/jellyfin/cache:/cache
|
- ./.volumes/jellyfin/cache:/cache
|
||||||
- ${PATH_MOVIES}:/media
|
- ${PATH_MEDIA}:/media
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "curl", "-f", "${HOSTNAME_MOVIES}" ]
|
|
||||||
interval: 1m
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@ -147,12 +137,6 @@ services:
|
|||||||
- USER_UID=1000
|
- USER_UID=1000
|
||||||
- USER_GID=1000
|
- USER_GID=1000
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "curl", "-f", "${HOSTNAME_GITEA}" ]
|
|
||||||
interval: 1m
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@ -168,37 +152,6 @@ services:
|
|||||||
- "traefik.http.routers.gitea.tls.certresolver=myresolver"
|
- "traefik.http.routers.gitea.tls.certresolver=myresolver"
|
||||||
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
|
||||||
|
|
||||||
# Home Assistant is an open-source home automation platform.
|
|
||||||
# For your smart home, it is the software "hub" that allows you to control all your devices.
|
|
||||||
home-assistant:
|
|
||||||
container_name: home-assistant
|
|
||||||
image: homeassistant/home-assistant:stable
|
|
||||||
volumes:
|
|
||||||
- ./.volumes/home-assistant:/config
|
|
||||||
environment:
|
|
||||||
- TZ=Asia/Singapore
|
|
||||||
restart: unless-stopped
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "curl", "-f", "${HOSTNAME_HOME_ASSISTANT}" ]
|
|
||||||
interval: 1m
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 512M
|
|
||||||
cpus: '0.25'
|
|
||||||
security_opt:
|
|
||||||
- no-new-privileges:true
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.home-assistant.rule=Host(`${HOSTNAME_HOME_ASSISTANT}`)"
|
|
||||||
- "traefik.http.routers.home-assistant.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.home-assistant.tls=true"
|
|
||||||
- "traefik.http.routers.home-assistant.tls.certresolver=myresolver"
|
|
||||||
- "traefik.http.services.home-assistant.loadbalancer.server.port=8123"
|
|
||||||
|
|
||||||
# A simple HTML page to display links to all the services.
|
# A simple HTML page to display links to all the services.
|
||||||
homepage:
|
homepage:
|
||||||
container_name: homepage
|
container_name: homepage
|
||||||
@ -206,12 +159,6 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./homepage/dist:/usr/share/nginx/html:ro
|
- ./homepage/dist:/usr/share/nginx/html:ro
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD", "curl", "-f", "${HOSTNAME_HOMEPAGE}" ]
|
|
||||||
interval: 1m
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
compose.yml
|
compose.yml
|
||||||
homepage/dist/***
|
homepage/***
|
||||||
|
immich/***
|
||||||
.env
|
.env
|
@ -46,7 +46,7 @@
|
|||||||
background-color: #2979ff;
|
background-color: #2979ff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<title>Home</title>
|
<title>Homelab</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@ -64,7 +64,31 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href="https://$HOSTNAME_AQS"
|
<a href="https://$HOSTNAME_AQS"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
🌬️ Air Quality Sensor
|
🌬️ Air Quality
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://$HOSTNAME_PHOTOS"
|
||||||
|
target="_blank">
|
||||||
|
📷 Photos
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://$HOSTNAME_MOVIES"
|
||||||
|
target="_blank">
|
||||||
|
🎬 Movies
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://$HOSTNAME_TORRENTS"
|
||||||
|
target="_blank">
|
||||||
|
⬇️ Torrents
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://$HOSTNAME_GITEA"
|
||||||
|
target="_blank">
|
||||||
|
📦 Gitea
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -79,30 +103,6 @@
|
|||||||
⏱️ Uptime Kuma
|
⏱️ Uptime Kuma
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href="https://$HOSTNAME_TORRENTS"
|
|
||||||
target="_blank">
|
|
||||||
⬇️ Torrents
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://$HOSTNAME_MOVIES"
|
|
||||||
target="_blank">
|
|
||||||
🎬 Movies
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://$HOSTNAME_GITEA"
|
|
||||||
target="_blank">
|
|
||||||
📦 Gitea
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://$HOSTNAME_HOME_ASSISTANT"
|
|
||||||
target="_blank">
|
|
||||||
⚡ Home Assistant
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
19
immich/.env.example
Normal file
19
immich/.env.example
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables
|
||||||
|
|
||||||
|
# TODO: make these vars to be used from ../.env
|
||||||
|
PATH_PHOTOS=~/ssd-2tb/media/photos
|
||||||
|
HOSTNAME_PHOTOS=photos.home.antonshubin.com
|
||||||
|
|
||||||
|
# The Immich version to use. You can pin this to a specific version like "v1.71.0"
|
||||||
|
IMMICH_VERSION=release
|
||||||
|
|
||||||
|
# Connection secret for postgres. You should change it to a random password
|
||||||
|
DB_PASSWORD=postgresS3cr3t
|
||||||
|
|
||||||
|
# The values below this line do not need to be changed
|
||||||
|
###################################################################################
|
||||||
|
DB_HOSTNAME=immich_postgres
|
||||||
|
DB_USERNAME=postgres
|
||||||
|
DB_DATABASE_NAME=immich
|
||||||
|
|
||||||
|
REDIS_HOSTNAME=immich_redis
|
119
immich/compose.yml
Normal file
119
immich/compose.yml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
#
|
||||||
|
# WARNING: Make sure to use the docker-compose.yml of the current release:
|
||||||
|
#
|
||||||
|
# https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
|
||||||
|
#
|
||||||
|
# The compose file on main may not be compatible with the latest release.
|
||||||
|
#
|
||||||
|
|
||||||
|
name: immich
|
||||||
|
|
||||||
|
services:
|
||||||
|
immich-server:
|
||||||
|
container_name: immich_server
|
||||||
|
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
|
||||||
|
command: [ "start.sh", "immich" ]
|
||||||
|
volumes:
|
||||||
|
- ${PATH_PHOTOS}:/usr/src/app/upload
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
- default
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
- database
|
||||||
|
restart: always
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 2048M
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.immich.rule=Host(`${HOSTNAME_PHOTOS}`)"
|
||||||
|
- "traefik.http.routers.immich.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.immich.tls=true"
|
||||||
|
- "traefik.http.routers.immich.tls.certresolver=myresolver"
|
||||||
|
- "traefik.http.services.immich.loadbalancer.server.port=3001"
|
||||||
|
|
||||||
|
immich-microservices:
|
||||||
|
container_name: immich_microservices
|
||||||
|
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
|
||||||
|
# extends:
|
||||||
|
# file: hwaccel.yml
|
||||||
|
# service: hwaccel
|
||||||
|
command: [ "start.sh", "microservices" ]
|
||||||
|
volumes:
|
||||||
|
- ${PATH_PHOTOS}:/usr/src/app/upload
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
- database
|
||||||
|
restart: always
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 2048M
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
immich-machine-learning:
|
||||||
|
container_name: immich_machine_learning
|
||||||
|
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
||||||
|
volumes:
|
||||||
|
- ../.volumes/immich/model-cache:/cache
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: always
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 2048M
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
redis:
|
||||||
|
container_name: immich_redis
|
||||||
|
image: redis:6.2-alpine@sha256:c5a607fb6e1bb15d32bbcf14db22787d19e428d59e31a5da67511b49bb0f1ccc
|
||||||
|
restart: always
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '0.25'
|
||||||
|
memory: 1024M
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
database:
|
||||||
|
container_name: immich_postgres
|
||||||
|
image: tensorchord/pgvecto-rs:pg14-v0.1.11@sha256:0335a1a22f8c5dd1b697f14f079934f5152eaaa216c09b61e293be285491f8ee
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_USER: ${DB_USERNAME}
|
||||||
|
POSTGRES_DB: ${DB_DATABASE_NAME}
|
||||||
|
volumes:
|
||||||
|
- ../.volumes/immich/postgres:/var/lib/postgresql/data
|
||||||
|
restart: always
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1'
|
||||||
|
memory: 2048M
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
Loading…
Reference in New Issue
Block a user