diff --git a/.env.example b/.env.example index 96fcf80..84fea4e 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,16 @@ CONTACT_EMAIL=your@email.com +TIMEZONE=Europe/Berlin SSH_TO_SERVER=user@server 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_TORRENTS=torrents.example.com HOSTNAME_MOVIES=movies.example.com +HOSTNAME_PHOTOS=photos.example.com HOSTNAME_GITEA=git.example.com -HOSTNAME_HOME_ASSISTANT=smart.example.com HOSTNAME_HOMEPAGE=ui.example.com HOSTNAME_SAGE=sage.example.com HOSTNAME_AQS=example.com \ No newline at end of file diff --git a/Makefile b/Makefile index 5873f77..e5fe535 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +.PHONY: * -include .env export $(shell sed 's/=.*//' .env) @@ -6,7 +7,25 @@ build-homepage: mkdir -p ./homepage/dist 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: make build-homepage - rsync -avz -e 'ssh' --include-from='deploy.files.txt' --exclude '*' ./ $(SSH_TO_SERVER):$(PATH_APPS) - ssh homelab "cd $(PATH_APPS) && docker compose up -d" \ No newline at end of file + make copy-files + make create-proxy-network + make up-homelab + make up-immich diff --git a/README.md b/README.md index c87e3a5..23b4e82 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,8 @@ Think of movies, TV shows, home videos, music, and pictures. ### [Gitea](https://github.com/go-gitea/gitea) Gitea is a lightweight self-hosted Git service, similar to GitHub. -### [Home Assistant](https://github.com/home-assistant/home-assistant.io) -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. +### [Immich](https://immich.app/) +Google Photos self-hosted alternative. ### [Homepage](./homepage/src/index.html) A simple homepage with links to all the services. diff --git a/compose.yml b/compose.yml index 4ded5cd..a10f681 100644 --- a/compose.yml +++ b/compose.yml @@ -1,4 +1,9 @@ version: '3.8' +# +networks: + proxy: + external: true + services: # Traefik is a reverse proxy and load balancer. @@ -27,10 +32,13 @@ services: ports: - "443:443" - "80:80" -# - "8080:8080" + - "8080:8080" volumes: - "./letsencrypt:/letsencrypt" - "/var/run/docker.sock:/var/run/docker.sock:ro" + networks: + - proxy + - default deploy: resources: limits: @@ -44,12 +52,6 @@ services: volumes: - ./.volumes/uptime-kuma:/app/data restart: unless-stopped - healthcheck: - test: [ "CMD", "curl", "-f", "${HOSTNAME_UPTIME_KUMA}" ] - interval: 1m - timeout: 10s - retries: 3 - start_period: 40s deploy: resources: limits: @@ -73,20 +75,14 @@ services: environment: - PUID=1000 - PGID=1000 - - TZ=Asia/Singapore + - TZ=${TIMEZONE} volumes: - ./.volumes/transmission:/config - - ${PATH_MOVIES}:/downloads + - ${PATH_MEDIA}:/downloads ports: - 51413:51413 # Default port for torrent traffic - 51413:51413/udp # Default port for DHT restart: unless-stopped - healthcheck: - test: [ "CMD", "curl", "-f", "${HOSTNAME_TORRENTS}" ] - interval: 1m - timeout: 10s - retries: 3 - start_period: 40s deploy: resources: limits: @@ -110,14 +106,8 @@ services: volumes: - ./.volumes/jellyfin:/config - ./.volumes/jellyfin/cache:/cache - - ${PATH_MOVIES}:/media + - ${PATH_MEDIA}:/media restart: unless-stopped - healthcheck: - test: [ "CMD", "curl", "-f", "${HOSTNAME_MOVIES}" ] - interval: 1m - timeout: 10s - retries: 3 - start_period: 40s deploy: resources: limits: @@ -147,12 +137,6 @@ services: - USER_UID=1000 - USER_GID=1000 restart: unless-stopped - healthcheck: - test: [ "CMD", "curl", "-f", "${HOSTNAME_GITEA}" ] - interval: 1m - timeout: 10s - retries: 3 - start_period: 40s deploy: resources: limits: @@ -168,37 +152,6 @@ services: - "traefik.http.routers.gitea.tls.certresolver=myresolver" - "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. homepage: container_name: homepage @@ -206,12 +159,6 @@ services: volumes: - ./homepage/dist:/usr/share/nginx/html:ro restart: unless-stopped - healthcheck: - test: [ "CMD", "curl", "-f", "${HOSTNAME_HOMEPAGE}" ] - interval: 1m - timeout: 10s - retries: 3 - start_period: 40s deploy: resources: limits: diff --git a/deploy.files.txt b/deploy.files.txt index 0820acc..c2093ce 100644 --- a/deploy.files.txt +++ b/deploy.files.txt @@ -1,3 +1,4 @@ compose.yml -homepage/dist/*** +homepage/*** +immich/*** .env \ No newline at end of file diff --git a/homepage/src/index.html b/homepage/src/index.html index 029cb94..1e1ec6d 100644 --- a/homepage/src/index.html +++ b/homepage/src/index.html @@ -46,7 +46,7 @@ background-color: #2979ff; } - Home + Homelab @@ -64,7 +64,31 @@
  • - 🌬️ Air Quality Sensor + 🌬️ Air Quality + +
  • +
  • + + 📷 Photos + +
  • +
  • + + 🎬 Movies + +
  • +
  • + + ⬇️ Torrents + +
  • +
  • + + 📦 Gitea
  • @@ -79,30 +103,6 @@ ⏱️ Uptime Kuma
  • -
  • - - ⬇️ Torrents - -
  • -
  • - - 🎬 Movies - -
  • -
  • - - 📦 Gitea - -
  • -
  • - - ⚡ Home Assistant - -
  • diff --git a/immich/.env.example b/immich/.env.example new file mode 100644 index 0000000..e8dfb30 --- /dev/null +++ b/immich/.env.example @@ -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 diff --git a/immich/compose.yml b/immich/compose.yml new file mode 100644 index 0000000..a9623da --- /dev/null +++ b/immich/compose.yml @@ -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