From 5a8d189c724f9a051db507c177586fa9f5033a64 Mon Sep 17 00:00:00 2001 From: SweetId <2630750+SweetId@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:35:10 -0500 Subject: [PATCH] add docker stacks --- Authentik/docker-compose.yaml | 104 ++++++++++++++++++++++++++ Authentik/stack.env | 7 ++ Gitea/docker-compose.yaml | 54 ++++++++++++++ Gitea/stack.env | 18 +++++ Immich/docker-compose.yaml | 98 ++++++++++++++++++++++++ Immich/stack.env | 13 ++++ Jellyfin/docker-compose.yaml | 34 +++++++++ Jellyfin/stack.env | 10 +++ Nextcloud/docker-compose.yaml | 135 ++++++++++++++++++++++++++++++++++ Nextcloud/stack.env | 36 +++++++++ README.md | 27 +++++++ Traefik/docker-compose.yaml | 33 +++++++++ Traefik/stack.env | 8 ++ 13 files changed, 577 insertions(+) create mode 100644 Authentik/docker-compose.yaml create mode 100644 Authentik/stack.env create mode 100644 Gitea/docker-compose.yaml create mode 100644 Gitea/stack.env create mode 100644 Immich/docker-compose.yaml create mode 100644 Immich/stack.env create mode 100644 Jellyfin/docker-compose.yaml create mode 100644 Jellyfin/stack.env create mode 100644 Nextcloud/docker-compose.yaml create mode 100644 Nextcloud/stack.env create mode 100644 README.md create mode 100644 Traefik/docker-compose.yaml create mode 100644 Traefik/stack.env diff --git a/Authentik/docker-compose.yaml b/Authentik/docker-compose.yaml new file mode 100644 index 0000000..ca60700 --- /dev/null +++ b/Authentik/docker-compose.yaml @@ -0,0 +1,104 @@ +--- +version: "3.4" + +services: + postgresql: + image: docker.io/library/postgres:12-alpine + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 5s + volumes: + - database:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: ${PG_PASS:?database password required} + POSTGRES_USER: ${PG_USER:-authentik} + POSTGRES_DB: ${PG_DB:-authentik} + env_file: + - stack.env + redis: + image: docker.io/library/redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 3s + volumes: + - redis:/data + server: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7} + restart: unless-stopped + command: server + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + volumes: + - ./media:/media + - ./custom-templates:/templates + env_file: + - stack.env + ports: + - "${AUTHENTIK_PORT_HTTP}:9000" + - "${AUTHENTIK_PORT_HTTPS}:9443" + depends_on: + - postgresql + - redis + labels: + - traefik.enable=true + + # HTTP redirection to HTTPS + - traefik.http.routers.authentik.entrypoints=web + - traefik.http.routers.authentik.rule=Host(`${AUTHENTIK_URL}`) + - traefik.http.middlewares.authentik-https-redirect.redirectscheme.scheme=https + - traefik.http.routers.authentik.middlewares=authentik-https-redirect + + # HTTPS config + - traefik.http.routers.authentik-secure.entrypoints=websecure + - traefik.http.routers.authentik-secure.rule=Host(`${AUTHENTIK_URL}`) + - traefik.http.routers.authentik-secure.tls=true + - traefik.http.routers.authentik-secure.tls.certresolver=myresolver + - traefik.http.services.authentik-secure.loadbalancer.server.port=9000 + + - traefik.docker.network=proxy + worker: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7} + restart: unless-stopped + command: worker + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgresql + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} + # `user: root` and the docker socket volume are optional. + # See more for the docker socket integration here: + # https://goauthentik.io/docs/outposts/integrations/docker + # Removing `user: root` also prevents the worker from fixing the permissions + # on the mounted folders, so when removing this make sure the folders have the correct UID/GID + # (1000:1000 by default) + user: root + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./media:/media + - ./certs:/certs + - ./custom-templates:/templates + env_file: + - stack.env + depends_on: + - postgresql + - redis + +volumes: + database: + driver: local + redis: + driver: local diff --git a/Authentik/stack.env b/Authentik/stack.env new file mode 100644 index 0000000..b137c7a --- /dev/null +++ b/Authentik/stack.env @@ -0,0 +1,7 @@ +PG_PASS=YOUR_VERY_LONG_DB_PASSWORD +AUTHENTIK_SECRET_KEY=YOUR_VERY_LONG_SECRET_KEY +AUTHENTIK_ERROR_REPORTING__ENABLED=true +AUTHENTIK_PORT_HTTP=9000 +AUTHENTIK_PORT_HTTPS=9443 + +AUTHENTIK_URL=auth.example.com \ No newline at end of file diff --git a/Gitea/docker-compose.yaml b/Gitea/docker-compose.yaml new file mode 100644 index 0000000..adddcb7 --- /dev/null +++ b/Gitea/docker-compose.yaml @@ -0,0 +1,54 @@ +version: "3" + +services: + server: + image: gitea/gitea:1.21.4 + container_name: gitea + restart: always + networks: + - gitea + - backend + env_file: + - stack.env + volumes: + - ${GITEA_DIR}:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - ${GITEA_PORT_HTTP}:3000 + - ${GITEA_PORT_SSH}:22 + depends_on: + - db + labels: + - traefik.enable=true + + # HTTP redirection to HTTPS + - traefik.http.routers.gitea.entrypoints=web + - traefik.http.routers.gitea.rule=Host(`${GITEA_URL}`) + - traefik.http.middlewares.gitea-https-redirect.redirectscheme.scheme=https + - traefik.http.routers.gitea.middlewares=gitea-https-redirect + + # HTTPS config + - traefik.http.routers.gitea-secure.entrypoints=websecure + - traefik.http.routers.gitea-secure.rule=Host(`${GITEA_URL}`) + - traefik.http.routers.gitea-secure.tls=true + - traefik.http.routers.gitea-secure.tls.certresolver=myresolver + - traefik.http.services.gitea-secure.loadbalancer.server.port=3000 + + - traefik.docker.network=proxy + + db: + image: postgres:14 + restart: always + env_file: + - stack.env + networks: + - gitea + volumes: + - ${GITEA_DB_DIR}:/var/lib/postgresql/data + +networks: + gitea: + external: false + backend: + external: true \ No newline at end of file diff --git a/Gitea/stack.env b/Gitea/stack.env new file mode 100644 index 0000000..779676a --- /dev/null +++ b/Gitea/stack.env @@ -0,0 +1,18 @@ +USER_UID=1000 +USER_GID=1000 + +GITEA_PORT_HTTP=3000 +GITEA_PORT_SSH=22 +GITEA_URL=git.example.com + +GITEA_DIR=/path/to/gitea +GITEA_DB_DIR=/path/to/gitea/db + +GITEA__database__DB_TYPE=postgres +GITEA__database__HOST=db:5432 +GITEA__database__NAME=gitea +GITEA__database__USER=gitea +GITEA__database__PASSWD=YOUR_DB_PASSWORD +POSTGRES_USER=gitea +POSTGRES_PASSWORD=YOUR_DB_PASSWORD +POSTGRES_DB=gitea \ No newline at end of file diff --git a/Immich/docker-compose.yaml b/Immich/docker-compose.yaml new file mode 100644 index 0000000..047932a --- /dev/null +++ b/Immich/docker-compose.yaml @@ -0,0 +1,98 @@ +version: "3.8" + +# +# 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: + - ${IMMICH_UPLOAD_DIR}:/usr/src/app/upload + - /etc/localtime:/etc/localtime:ro + - ${IMMICH_EXTERNAL_DIR}:/mnt/media:ro + env_file: + - stack.env + ports: + - ${IMMICH_PORT_HTTP}:3001 + - ${IMMICH_PORT_HTTPS}:443 + expose: + - ${IMMICH_PORT_HTTP} + - ${IMMICH_PORT_HTTPS} + depends_on: + - redis + - database + restart: always + labels: + - traefik.enable=true + + - traefik.http.routers.immich.entrypoints=web + - traefik.http.routers.immich.rule=Host(`${IMMICH_URL}`) + - traefik.http.routers.immich.middlewares=immich-https-redirect + - traefik.http.middlewares.immich-https-redirect.redirectscheme.scheme=https + + - traefik.http.routers.immich-secure.entrypoints=websecure + - traefik.http.routers.immich-secure.rule=Host(`${IMMICH_URL}`) + - traefik.http.routers.immich-secure.tls=true + - traefik.http.routers.immich-secure.tls.certresolver=myresolver + - traefik.http.services.immich-secure.loadbalancer.server.port=3001 + - traefik.http.services.immich-secure.loadbalancer.server.scheme=http + + - traefik.docker.network=proxy + + 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: + - ${IMMICH_UPLOAD_DIR}:/usr/src/app/upload + - ${IMMICH_EXTERNAL_DIR}:/mnt/media:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - stack.env + 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: + - stack.env + restart: always + + redis: + container_name: immich_redis + image: redis:6.2-alpine@sha256:c5a607fb6e1bb15d32bbcf14db22787d19e428d59e31a5da67511b49bb0f1ccc + restart: always + + database: + container_name: immich_postgres + image: tensorchord/pgvecto-rs:pg14-v0.1.11@sha256:0335a1a22f8c5dd1b697f14f079934f5152eaaa216c09b61e293be285491f8ee + env_file: + - stack.env + environment: + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_USER: ${DB_USERNAME} + POSTGRES_DB: ${DB_DATABASE_NAME} + volumes: + - pgdata:/var/lib/postgresql/data + restart: always + +volumes: + pgdata: + model-cache: diff --git a/Immich/stack.env b/Immich/stack.env new file mode 100644 index 0000000..19a8430 --- /dev/null +++ b/Immich/stack.env @@ -0,0 +1,13 @@ +IMMICH_PORT_HTTP=3001 +IMMICH_PORT_HTTPS=443 + +IMMICH_URL=immich.example.com +IMMICH_EXTERNAL_DIR=/path/to/external/libraries +IMMICH_UPLOAD_DIR=/path/to/immich/upload + +IMMICH_VERSION=release +DB_PASSWORD=YOUR_DB_PASSWORD +DB_HOSTNAME=immich_postgres +DB_USERNAME=postgres +DB_DATABASE_NAME=immich +REDIS_HOSTNAME=immich_redis \ No newline at end of file diff --git a/Jellyfin/docker-compose.yaml b/Jellyfin/docker-compose.yaml new file mode 100644 index 0000000..76f1863 --- /dev/null +++ b/Jellyfin/docker-compose.yaml @@ -0,0 +1,34 @@ +version: '3' + +services: + jellyfin: + image: jellyfin/jellyfin:latest + restart: unless-stopped + ports: + - 1900:1900 + - 7359:7359 + - ${JELLYFIN_PORT_HTTP}:8096 + - ${JELLYFIN_PORT_HTTPS}:8920 + volumes: + - ./cache:/cache + - ${JELLYFIN_DIR}:/config:r + - ${JELLYFIN_MEDIA_DIR}:/data/media:ro + env_file: + - stack.env + labels: + - traefik.enable=true + + # HTTP redirection to HTTPS + - traefik.http.routers.jellyfin.entrypoints=web + - traefik.http.routers.jellyfin.rule=Host(`${JELLYFIN_URL}`) + - traefik.http.middlewares.jellyfin-https-redirect.redirectscheme.scheme=https + - traefik.http.routers.jellyfin.middlewares=jellyfin-https-redirect + + # HTTPS config + - traefik.http.routers.jellyfin-secure.entrypoints=websecure + - traefik.http.routers.jellyfin-secure.rule=Host(`${JELLYFIN_URL}`) + - traefik.http.routers.jellyfin-secure.tls=true + - traefik.http.routers.jellyfin-secure.tls.certresolver=myresolver + - traefik.http.services.jellyfin-secure.loadbalancer.server.port=8096 + + - traefik.docker.network=proxy diff --git a/Jellyfin/stack.env b/Jellyfin/stack.env new file mode 100644 index 0000000..005df5e --- /dev/null +++ b/Jellyfin/stack.env @@ -0,0 +1,10 @@ +JELLYFIN_PORT_HTTP=8096 +JELLYFIN_PORT_HTTPS=8920 +JELLYFIN_URL=jellyfin.example.com + +JELLYFIN_DIR=/path/to/jelly +JELLYFIN_MEDIA_DIR=/path/to/media + +TZ=America/Toronto +PUID=1000 +PGID=1000 \ No newline at end of file diff --git a/Nextcloud/docker-compose.yaml b/Nextcloud/docker-compose.yaml new file mode 100644 index 0000000..e4fa2c4 --- /dev/null +++ b/Nextcloud/docker-compose.yaml @@ -0,0 +1,135 @@ +services: + aio-apache: + depends_on: + aio-nextcloud: + condition: service_started + required: false + aio-notify-push: + condition: service_started + required: false + image: nextcloud/aio-apache:latest + init: true + ports: + - ${APACHE_IP_BINDING}:${APACHE_PORT}:${APACHE_PORT}/tcp + - ${APACHE_IP_BINDING}:${APACHE_PORT}:${APACHE_PORT}/udp + env_file: + - stack.env + volumes: + - nextcloud_aio_nextcloud:/var/www/html:ro + - nextcloud_aio_apache:/mnt/data:rw + restart: unless-stopped + networks: + - nextcloud-aio + read_only: true + tmpfs: + - /var/log/supervisord + - /var/run/supervisord + - /usr/local/apache2/logs + - /tmp + - /home/www-data + labels: + - traefik.enable=true + + # HTTP redirection to HTTPS + - traefik.http.routers.nextcloud.entrypoints=web + - traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_URL}`) + - traefik.http.middlewares.nextcloud-https-redirect.redirectscheme.scheme=https + - traefik.http.routers.nextcloud.middlewares=nextcloud-https-redirect + + # HTTPS config + - traefik.http.routers.nextcloud-secure.entrypoints=websecure + - traefik.http.routers.nextcloud-secure.rule=Host(`${NEXTCLOUD_URL}`) + - traefik.http.routers.nextcloud-secure.tls=true + - traefik.http.routers.nextcloud-secure.tls.certresolver=myresolver + - traefik.http.services.nextcloud-secure.loadbalancer.server.port=21000 + + - traefik.docker.network=proxy + + aio-database: + image: nextcloud/aio-postgresql:latest + init: true + expose: + - "5432" + volumes: + - nextcloud_aio_database:/var/lib/postgresql/data:rw + - nextcloud_aio_database_dump:/mnt/data:rw + env_file: + - stack.env + stop_grace_period: 1800s + restart: unless-stopped + shm_size: 268435456 + networks: + - nextcloud-aio + read_only: true + tmpfs: + - /var/run/postgresql + + aio-nextcloud: + depends_on: + aio-database: + condition: service_started + required: false + aio-redis: + condition: service_started + required: false + image: nextcloud/aio-nextcloud:latest + init: true + expose: + - "9000" + - "9001" + volumes: + - nextcloud_aio_nextcloud:/var/www/html:rw + - ${NEXTCLOUD_USER_DIR}:/mnt/ncdata:rw + - ${NEXTCLOUD_DOCKER_DIR}:/mnt:rw + - ${NEXTCLOUD_TRUSTED_CACERTS_DIR}:/usr/local/share/ca-certificates:ro + env_file: + - stack.env + stop_grace_period: 600s + restart: unless-stopped + networks: + - nextcloud-aio + + aio-notify-push: + image: nextcloud/aio-notify-push:latest + init: true + expose: + - "7867" + volumes: + - nextcloud_aio_nextcloud:/nextcloud:ro + env_file: + - stack.env + restart: unless-stopped + networks: + - nextcloud-aio + read_only: true + + aio-redis: + image: nextcloud/aio-redis:latest + init: true + expose: + - "6379" + env_file: + - stack.env + volumes: + - nextcloud_aio_redis:/data:rw + restart: unless-stopped + networks: + - nextcloud-aio + read_only: true + +volumes: + nextcloud_aio_apache: + name: nextcloud_aio_apache + nextcloud_aio_database: + name: nextcloud_aio_database + nextcloud_aio_database_dump: + name: nextcloud_aio_database_dump + nextcloud_aio_nextcloud: + name: nextcloud_aio_nextcloud + nextcloud_aio_redis: + name: nextcloud_aio_redis + +networks: + nextcloud-aio: + name: nextcloud-aio + driver: bridge \ No newline at end of file diff --git a/Nextcloud/stack.env b/Nextcloud/stack.env new file mode 100644 index 0000000..e4842ba --- /dev/null +++ b/Nextcloud/stack.env @@ -0,0 +1,36 @@ +NEXTCLOUD_URL=nextcloud.example.com +TZ=America/Toronto + +NEXTCLOUD_DOCKER_DIR=/path/to/nextcloud +NEXTCLOUD_DATA_DIR=/path/to/users/data +NEXTCLOUD_TRUSTED_CACERTS_DIR=./certificates + +ADMIN_USER=admin +ADMIN_PASSWORD=YOUR_ADMIN_PASSWORD + +APACHE_IP_BINDING=0.0.0.0 +APACHE_PORT=21000 +APACHE_MAX_TIME=3600 +APACHE_MAX_SIZE=10737418240 + +NEXTCLOUD_UPLOAD_LIMIT=10G +POSTGRES_DB=nextcloud_database +POSTGRES_HOST=aio-database +POSTGRES_PASSWORD=YOUR_DB_PASSWORD +POSTGRES_USER=nextcloud + +CLAMAV_ENABLED=false +COLLABORA_ENABLED=false +FULLTEXTSEARCH_ENABLED=false +IMAGINARY_ENABLED=false +TALK_ENABLED=false +ONLYOFFICE_ENABLED=false + +NEXTCLOUD_HOST=aio-nextcloud +NOTIFY_PUSH_HOST=aio-notify-push +REDIS_HOST=aio-redis +REDIS_HOST_PASSWORD=YOUR_REDIS_PASSWORD + +NC_DOMAIN=${NEXTCLOUD_URL} +OVERWRITEHOST=${NC_DOMAIN} +OVERWRITEPROTOCOL=https \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ea005b0 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# Docker Services + +## Traefik + +Traefik is the routing point between user request and backend services. It also handles SSL certificates automatically. +It forwards requests from service.example.com to your service running behind. +Make sure that TRAEFIK_CERT_DIR exists on disk otherwise Traefik will requests certificates to your subdomains every time it restarts and you will get timed out by Letsencrypt. + +## Authentik + +Authentik is the credentials provider used by all the services. You just need to create accounts and assign permissions through authentik UI, then all accounts will be able to access your services without having to manage users for each. + +## Gitea + +A small, nice Git server. + +## Jellyfin + +At-home netflix + +## Nextcloud + +Google drive replacement + +## Immich + +Google photos replacement \ No newline at end of file diff --git a/Traefik/docker-compose.yaml b/Traefik/docker-compose.yaml new file mode 100644 index 0000000..b2333a2 --- /dev/null +++ b/Traefik/docker-compose.yaml @@ -0,0 +1,33 @@ +version: '3.3' + +services: + reverse-proxy: + # The official v2 Traefik docker image + image: traefik:v2.10 + # Enables the web UI and tells Traefik to listen to docker + command: + #- "--log.level=DEBUG" + - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--providers.file.directory=/traefik/conf" + - "--providers.file.watch=true" + - "--entrypoints.websecure.address=:443" + - "--entrypoints.web.address=:80" + - "--certificatesresolvers.myresolver.acme.tlschallenge=true" + - "--certificatesresolvers.myresolver.acme.email=${TRAEFIK_ADMIN_EMAIL}" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + networks: + - backend + ports: + - ${TRAEFIK_PORT_HTTP}:80 # The HTTP port + - ${TRAEFIK_PORT_HTTPS}:443 # The HTTP port + - ${TRAEFIK_BACKEND_PORT}:8080 # The Web UI (enabled by --api.insecure=true) + volumes: + - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events + - ${TRAEFIK_DIR}:/traefik + - ${TRAEFIK_CERT_DIR}:/letsencrypt # For SSL certificates + +networks: + backend: + external: true \ No newline at end of file diff --git a/Traefik/stack.env b/Traefik/stack.env new file mode 100644 index 0000000..40fcf0c --- /dev/null +++ b/Traefik/stack.env @@ -0,0 +1,8 @@ +TRAEFIK_PORT_HTTP=80 +TRAEFIK_PORT_HTTPS=443 +TRAEFIK_BACKEND_PORT=8080 + +TRAEFIK_ADMIN_EMAIL=admin@example.com + +TRAEFIK_DIR=/path/to/traefik +TRAEFIK_CERT_DIR=/path/to/traefik/certs \ No newline at end of file