From 373b822888cabfb99c414b7d6ec37151879ff732 Mon Sep 17 00:00:00 2001 From: Adrien Poupa Date: Sun, 21 Apr 2024 18:46:44 -0400 Subject: [PATCH] feat(immich): Add Immich --- .env.example | 6 +- README.md | 6 ++ immich/.gitignore | 4 ++ immich/README.md | 20 ++++++ immich/docker-compose.yml | 114 ++++++++++++++++++++++++++++++ immich/healthcheck/healthcheck.js | 28 ++++++++ 6 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 immich/.gitignore create mode 100644 immich/README.md create mode 100644 immich/docker-compose.yml create mode 100644 immich/healthcheck/healthcheck.js diff --git a/.env.example b/.env.example index 9835303..3374992 100644 --- a/.env.example +++ b/.env.example @@ -1,18 +1,20 @@ COMPOSE_PROFILES= COMPOSE_PATH_SEPARATOR=: -COMPOSE_FILE=docker-compose.yml:adguardhome/docker-compose.yml:tandoor/docker-compose.yml:joplin/docker-compose.yml:homeassistant/docker-compose.yml +COMPOSE_FILE=docker-compose.yml:adguardhome/docker-compose.yml:tandoor/docker-compose.yml:joplin/docker-compose.yml:homeassistant/docker-compose.yml:immich/docker-compose.yml USER_ID=1000 GROUP_ID=1000 TIMEZONE="America/New_York" CONFIG_ROOT="." DATA_ROOT="/mnt/data" DOWNLOAD_ROOT="/mnt/data/torrents" +IMMICH_UPLOAD_LOCATION="/mnt/data/photos" PIA_LOCATION=ca PIA_USER= PIA_PASS= PIA_LOCAL_NETWORK="192.168.0.0/16" HOSTNAME=localhost HOMEASSISTANT_HOSTNAME= +IMMICH_HOSTNAME= ADGUARD_HOSTNAME= ADGUARD_USERNAME= ADGUARD_PASSWORD= @@ -33,6 +35,7 @@ BAZARR_API_KEY= JELLYFIN_API_KEY= JELLYSEERR_API_KEY= SABNZBD_API_KEY= +IMMICH_API_KEY= HOMEASSISTANT_ACCESS_TOKEN= HOMEPAGE_VAR_TITLE="Docker-Compose NAS" HOMEPAGE_VAR_SEARCH_PROVIDER=google @@ -41,3 +44,4 @@ HOMEPAGE_VAR_WEATHER_CITY= HOMEPAGE_VAR_WEATHER_LAT= HOMEPAGE_VAR_WEATHER_LONG= HOMEPAGE_VAR_WEATHER_UNIT=metric +IMMICH_DB_PASSWORD=postgres \ No newline at end of file diff --git a/README.md b/README.md index 810d259..cd5c700 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ I am running it in Ubuntu Server 22.04; I also tested this setup on a [Synology * [Tandoor](#tandoor) * [Joplin](#joplin) * [Home Assistant](#home-assistant) + * [Immich](#immich) * [Customization](#customization) * [Optional: Using the VPN for *arr apps](#optional-using-the-vpn-for-arr-apps) * [Synology Quirks](#synology-quirks) @@ -77,6 +78,7 @@ I am running it in Ubuntu Server 22.04; I also tested this setup on a [Synology | [Tandoor](https://tandoor.dev) | Optional - Smart recipe management
Enable with `COMPOSE_PROFILES=tandoor` | [vabene1111/recipes](https://hub.docker.com/r/vabene1111/recipes) | /recipes | | [Joplin](https://joplinapp.org/) | Optional - Note taking application
Enable with `COMPOSE_PROFILES=joplin` | [joplin/server](https://hub.docker.com/r/joplin/server) | /joplin | | [Home Assistant](https://www.home-assistant.io/) | Optional - Open source home automation that puts local control and privacy first
Enable with `COMPOSE_PROFILES=homeassistant` | [home-assistant/home-assistant:stable](https://ghcr.io/home-assistant/home-assistant) | | +| [Immich](https://immich.app//) | Optional - Self-hosted photo and video management solution
Enable with `COMPOSE_PROFILES=immich` | [immich-app/immich-server:release](https://ghcr.io/immich-app/immich-server) | | Optional containers are not enabled by default, they need to be enabled, see [Optional Services](#optional-services) for more information. @@ -389,6 +391,10 @@ See [here](./joplin/README.md). See [here](./homeassistant/README.md). +### Immich + +See [here](./immich/README.md). + ## Customization You can override the configuration of a service or add new services by creating a new `docker-compose.override.yml` file, diff --git a/immich/.gitignore b/immich/.gitignore new file mode 100644 index 0000000..9a5f6bf --- /dev/null +++ b/immich/.gitignore @@ -0,0 +1,4 @@ +* +!README.md +!docker-compose.yml +!healthcheck \ No newline at end of file diff --git a/immich/README.md b/immich/README.md new file mode 100644 index 0000000..1ccd77e --- /dev/null +++ b/immich/README.md @@ -0,0 +1,20 @@ +# Immich + +Self-hosted photo and video management solution + +## Installation + +Enable Immich by setting `COMPOSE_PROFILES=immich`. + +Set the `IMMICH_HOSTNAME`, since it does not support +[running in a subfolder](https://github.com/immich-app/immich/discussions/1679#discussioncomment-7276351). +Add the necessary DNS records in your domain. + +## Environment Variables + +| Variable | Description | Default | +|--------------------------|------------------------------------------------------|--------------------| +| `IMMICH_HOSTNAME` | URL Immich will be accessible from | | +| `IMMICH_UPLOAD_LOCATION` | Path where the assets will be stored | `/mnt/data/photos` | +| `IMMICH_API_KEY` | Immich API key to show information in the homepage | `1000` | +| `IMMICH_DB_PASSWORD` | Postgres database password, change for more security | `postgres` | diff --git a/immich/docker-compose.yml b/immich/docker-compose.yml new file mode 100644 index 0000000..9a3f6c5 --- /dev/null +++ b/immich/docker-compose.yml @@ -0,0 +1,114 @@ +services: + immich-server: + container_name: immich_server + image: ghcr.io/immich-app/immich-server:release + environment: + DB_HOSTNAME: immich_postgres + DB_PASSWORD: ${IMMICH_DB_PASSWORD} + DB_USERNAME: postgres + DB_DATABASE_NAME: immich + command: ['start.sh', 'immich'] + volumes: + - ${IMMICH_UPLOAD_LOCATION}:/usr/src/app/upload + - /etc/localtime:/etc/localtime:ro + - ${CONFIG_ROOT:-.}/immich/healthcheck:/healthcheck + depends_on: + - immich-redis + - immich-database + restart: always + healthcheck: + test: [ "CMD", "node", "/healthcheck/healthcheck.js" ] + interval: 30s + retries: 10 + labels: + - traefik.enable=true + - traefik.http.routers.immich.rule=(Host(`${IMMICH_HOSTNAME}`)) + - traefik.http.routers.immich.tls=true + - traefik.http.routers.immich.tls.certresolver=myresolver + - traefik.http.services.immich.loadbalancer.server.port=3001 + - homepage.group=Apps + - homepage.name=immich + - homepage.icon=immich.png + - homepage.href=https://${IMMICH_HOSTNAME} + - homepage.description=Self-hosted photo and video management solution + - homepage.weight=4 + - homepage.widget.type=immich + - homepage.widget.url=http://immich:3001 + - homepage.widget.key=${IMMICH_API_KEY} + profiles: + - immich + + immich-microservices: + container_name: immich_microservices + image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} + environment: + DB_HOSTNAME: immich_postgres + DB_PASSWORD: ${IMMICH_DB_PASSWORD} + DB_USERNAME: postgres + DB_DATABASE_NAME: immich + devices: + - /dev/dri/renderD128:/dev/dri/renderD128 + - /dev/dri/card0:/dev/dri/card0 + command: ['start.sh', 'microservices'] + volumes: + - ${IMMICH_UPLOAD_LOCATION}:/usr/src/app/upload + - /etc/localtime:/etc/localtime:ro + depends_on: + - immich-redis + - immich-database + restart: always + healthcheck: + test: [ "CMD", "bash", "-c", "exec 5<>/dev/tcp/127.0.0.1/3002" ] + interval: 10s + timeout: 5s + retries: 5 + profiles: + - immich + + immich-machine-learning: + container_name: immich_machine_learning + image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} + volumes: + - immich-model-cache:/cache + restart: always + healthcheck: + test: [ "CMD", "bash", "-c", "exec 5<>/dev/tcp/127.0.0.1/3003" ] + interval: 10s + timeout: 5s + retries: 5 + profiles: + - immich + + immich-redis: + container_name: immich_redis + image: registry.hub.docker.com/library/redis:6.2-alpine@sha256:84882e87b54734154586e5f8abd4dce69fe7311315e2fc6d67c29614c8de2672 + restart: always + healthcheck: + test: [ "CMD", "redis-cli", "ping" ] + interval: 10s + timeout: 5s + retries: 5 + profiles: + - immich + + immich-database: + container_name: immich_postgres + image: registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 + environment: + DB_HOSTNAME: immich_postgres + POSTGRES_PASSWORD: ${IMMICH_DB_PASSWORD} + POSTGRES_USER: postgres + POSTGRES_DB: immich + volumes: + - ${CONFIG_ROOT:-.}/immich/postgresql:/var/lib/postgresql/data + restart: always + healthcheck: + test: [ "CMD-SHELL", "pg_isready" ] + interval: 10s + timeout: 5s + retries: 5 + profiles: + - immich + +volumes: + immich-model-cache: diff --git a/immich/healthcheck/healthcheck.js b/immich/healthcheck/healthcheck.js new file mode 100644 index 0000000..0e627ea --- /dev/null +++ b/immich/healthcheck/healthcheck.js @@ -0,0 +1,28 @@ +// Inspired by: https://anthonymineo.com/docker-healthcheck-for-your-node-js-app/ +const http = require('http'); +const options = { + host: '127.0.0.1', + port: 3001, + timeout: 2000, + path: '/api/server-info/ping', + headers: { + 'Host': process.env.HOSTNAME, + } +}; + +const healthCheck = http.request(options, (res) => { + console.log(`HEALTHCHECK STATUS: ${res.statusCode}`); + if (res.statusCode === 200) { + process.exit(0); + } + else { + process.exit(1); + } +}); + +healthCheck.on('error', function (err) { + console.error('ERROR:' + err); + process.exit(1); +}); + +healthCheck.end();