diff --git a/.gitignore b/.gitignore index e9baea7..27366f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.deb *.kate-swp +.env +**/.env diff --git a/actual/compose.yml b/actual/compose.yml index 76cb1cc..f236e68 100644 --- a/actual/compose.yml +++ b/actual/compose.yml @@ -1,32 +1,23 @@ services: actual_server: - image: docker.io/actualbudget/actual-server:latest + image: actualbudget/actual-server@sha256:c34346f87725b9cce5dca5af1a2a9b989127d592cc4c6af5cf4652d4a86def90 + container_name: actual_server ports: - # This line makes Actual available at port 5006 of the device you run the server on, - # i.e. http://localhost:5006. You can change the first number to change the port, if you want. - '5006:5006' - #environment: - # Uncomment any of the lines below to set configuration options. - # - ACTUAL_HTTPS_KEY=/data/selfhost.key - # - ACTUAL_HTTPS_CERT=/data/selfhost.crt - # - ACTUAL_PORT=5006 - # - ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB=20 - # - ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB=50 - # - ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MB=20 - # See all options and more details at https://actualbudget.org/docs/config/ - # !! If you are not using any of these options, remove the 'environment:' tag entirely. volumes: - # Change './actual-data' below to the path to the folder you want Actual to store its data in on your server. - # '/data' is the path Actual will look for its files in by default, so leave that as-is. - /mnt/storage/apps/actual:/data healthcheck: - # Enable health check for the instance test: ['CMD-SHELL', 'node src/scripts/health-check.js'] interval: 60s timeout: 10s retries: 3 start_period: 20s restart: unless-stopped + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' networks: - network networks: diff --git a/authentik/compose.yml b/authentik/compose.yml new file mode 100644 index 0000000..4489069 --- /dev/null +++ b/authentik/compose.yml @@ -0,0 +1,109 @@ +services: + postgresql: + image: docker.io/library/postgres:16-alpine + container_name: authentik_postgres + 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: + - /mnt/storage/apps/authentik/postgres:/var/lib/postgresql/data + environment: + - POSTGRES_PASSWORD=${PG_PASS} + - POSTGRES_USER=authentik + - POSTGRES_DB=authentik + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' + + redis: + image: docker.io/library/redis:alpine + container_name: authentik_redis + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 3s + volumes: + - /mnt/storage/apps/authentik/redis:/data + deploy: + resources: + limits: + memory: 256M + cpus: '0.25' + + server: + image: ghcr.io/goauthentik/server:2025.2.4 + container_name: authentik_server + restart: unless-stopped + command: server + environment: + - AUTHENTIK_REDIS__HOST=redis + - AUTHENTIK_POSTGRESQL__HOST=postgresql + - AUTHENTIK_POSTGRESQL__USER=authentik + - AUTHENTIK_POSTGRESQL__NAME=authentik + - AUTHENTIK_POSTGRESQL__PASSWORD=${PG_PASS} + - AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY} + - AUTHENTIK_ERROR_REPORTING__ENABLED=false + volumes: + - /mnt/storage/apps/authentik/media:/media + - /mnt/storage/apps/authentik/custom-templates:/templates + depends_on: + postgresql: + condition: service_healthy + redis: + condition: service_healthy + healthcheck: + test: ["CMD", "ak", "healthcheck"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' + networks: + - default + - network + + worker: + image: ghcr.io/goauthentik/server:2025.2.4 + container_name: authentik_worker + restart: unless-stopped + command: worker + environment: + - AUTHENTIK_REDIS__HOST=redis + - AUTHENTIK_POSTGRESQL__HOST=postgresql + - AUTHENTIK_POSTGRESQL__USER=authentik + - AUTHENTIK_POSTGRESQL__NAME=authentik + - AUTHENTIK_POSTGRESQL__PASSWORD=${PG_PASS} + - AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY} + - AUTHENTIK_ERROR_REPORTING__ENABLED=false + volumes: + - /mnt/storage/apps/authentik/media:/media + - /mnt/storage/apps/authentik/certs:/certs + - /mnt/storage/apps/authentik/custom-templates:/templates + depends_on: + postgresql: + condition: service_healthy + redis: + condition: service_healthy + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' + +networks: + network: + name: proxy + external: true diff --git a/caddy/compose.yml b/caddy/compose.yml index 901bddb..de87391 100644 --- a/caddy/compose.yml +++ b/caddy/compose.yml @@ -5,11 +5,12 @@ services: restart: unless-stopped cap_add: - NET_ADMIN + env_file: + - .env environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles - - CLOUDFLARE_API_TOKEN=cfat_yPhy6H6v3Yr83YdNuJQeS4lgfxzd7X2U1OpMX4gp07cf50fe ports: - "80:80" - "443:443" @@ -20,6 +21,17 @@ services: - ./conf:/etc/caddy - /mnt/storage/apps/caddy/data:/data - /mnt/storage/apps/caddy/config:/config + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:80"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' networks: - proxy diff --git a/caddy/conf/Caddyfile b/caddy/conf/Caddyfile index 67fbe59..b1c16f4 100755 --- a/caddy/conf/Caddyfile +++ b/caddy/conf/Caddyfile @@ -20,6 +20,12 @@ reverse_proxy radarr:7878 } + @immich host photos.wampler.us + handle @immich { + encode gzip + reverse_proxy immich_server:2283 + } + @vaultwarden host vault.wampler.us handle @vaultwarden { encode gzip @@ -37,6 +43,30 @@ encode gzip reverse_proxy host.docker.internal:8112 } + + @dockge host dockge.wampler.us + handle @dockge { + encode gzip + reverse_proxy dockge:5001 + } + + @navidrome host music.wampler.us + handle @navidrome { + encode gzip + reverse_proxy navidrome:4533 + } + + @authentik host auth.wampler.us + handle @authentik { + encode gzip + reverse_proxy authentik_server:9000 + } + + @lidarr host lidarr.wampler.us + handle @lidarr { + encode gzip + reverse_proxy lidarr:8686 + } } localhost { diff --git a/calibre-web/compose.yml b/calibre-web/compose.yml index dbd6113..a7eb13b 100644 --- a/calibre-web/compose.yml +++ b/calibre-web/compose.yml @@ -1,22 +1,33 @@ services: calibre-web: - image: lscr.io/linuxserver/calibre-web:latest + image: lscr.io/linuxserver/calibre-web:0.6.26-ls374 container_name: calibre-web environment: - PUID=1000 - PGID=1000 - TZ=America/Los_Angeles - - DOCKER_MODS=linuxserver/mods:universal-calibre #optional - - OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional + - DOCKER_MODS=linuxserver/mods:universal-calibre + - OAUTHLIB_RELAX_TOKEN_SCOPE=1 volumes: - /mnt/storage/apps/calibre-web/data:/config - /mnt/storage/media/ebooks:/books ports: - 8083:8083 restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8083/login"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' networks: - network networks: - network: - name: proxy - external: true + network: + name: proxy + external: true diff --git a/cloudflare-ddns/compose.yml b/cloudflare-ddns/compose.yml index aef75dd..3fdba81 100644 --- a/cloudflare-ddns/compose.yml +++ b/cloudflare-ddns/compose.yml @@ -1,34 +1,19 @@ services: cloudflare-ddns: image: favonia/cloudflare-ddns:1 - # Prefer "1" or "1.x.y" in production. - # - # - "1" tracks the latest stable release whose major version is 1 - # - "1.x.y" pins one specific stable version - # - "latest" moves to each new stable release and may pick up breaking - # changes in a future major release, so it is not recommended in production - # - "edge" tracks the latest unreleased development build network_mode: host - # Optional. This bypasses network isolation and makes IPv6 easier. - # See "Use IPv6 without sharing the host network". restart: unless-stopped - # Restart the updater after reboot user: "1000:1000" - # Run the updater with specific user and group IDs (in that order). - # You can change the two numbers based on your need. read_only: true - # Make the container filesystem read-only (optional but recommended) cap_drop: [all] - # Drop all Linux capabilities (optional but recommended) - #security_opt: [no-new-privileges:true] - # Another protection to restrict superuser privileges (optional but recommended) + env_file: + - .env environment: - - CLOUDFLARE_API_TOKEN=cfat_yPhy6H6v3Yr83YdNuJQeS4lgfxzd7X2U1OpMX4gp07cf50fe - # Your Cloudflare API token - DOMAINS=wampler.us - # Your domains (separated by commas) - PROXIED=true - IP6_PROVIDER=none - # Use Cloudflare's proxy for these domains (optional) - # Existing DNS records in Cloudflare keep their current proxy setting - # Change them once manually if you want to switch them + deploy: + resources: + limits: + memory: 64M + cpus: '0.1' diff --git a/dockge/compose.yml b/dockge/compose.yml new file mode 100644 index 0000000..25d160a --- /dev/null +++ b/dockge/compose.yml @@ -0,0 +1,31 @@ +name: dockge + +services: + dockge: + container_name: dockge + image: louislam/dockge@sha256:335c6368b880ecc203236ed89e6e5232e0d6578e8ef5920e4a502390451502bf + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /mnt/storage/apps/dockge/data:/app/data + - /home/james/src/system-config:/home/james/src/system-config + environment: + - DOCKGE_STACKS_DIR=/home/james/src/system-config + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5001"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' + networks: + - proxy + +networks: + proxy: + name: proxy + external: true diff --git a/gitea/compose.yml b/gitea/compose.yml index e26671b..af8eb73 100644 --- a/gitea/compose.yml +++ b/gitea/compose.yml @@ -1,6 +1,6 @@ services: gitea: - image: gitea/gitea:latest + image: gitea/gitea:1.25.5 container_name: gitea restart: unless-stopped environment: @@ -10,8 +10,18 @@ services: volumes: - /mnt/storage/apps/gitea/data:/data ports: - - "3000:3000" - "2223:22" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' networks: - network networks: diff --git a/immich/compose.yml b/immich/compose.yml index db6fe51..d135c85 100644 --- a/immich/compose.yml +++ b/immich/compose.yml @@ -11,6 +11,7 @@ services: # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file - ${UPLOAD_LOCATION}:/data - /etc/localtime:/etc/localtime:ro + - /mnt/storage/media/temp-pix:/temp-pix environment: - PUID=1000 - PGID=1000 @@ -24,6 +25,9 @@ services: restart: unless-stopped healthcheck: disable: false + networks: + - default + - proxy immich-machine-learning: container_name: immich_machine_learning @@ -70,3 +74,8 @@ services: volumes: model-cache: + +networks: + proxy: + name: proxy + external: true diff --git a/lidarr/compose.yml b/lidarr/compose.yml new file mode 100644 index 0000000..4b2c76f --- /dev/null +++ b/lidarr/compose.yml @@ -0,0 +1,32 @@ +services: + lidarr: + image: lscr.io/linuxserver/lidarr:3.1.0.4875-ls22 + container_name: lidarr + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Los_Angeles + volumes: + - /mnt/storage/apps/lidarr/data:/config + - /mnt/storage/media/music:/music + - /mnt/storage/downloads/music:/downloads + restart: unless-stopped + extra_hosts: + - "host.docker.internal:host-gateway" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8686/ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' + networks: + - network +networks: + network: + name: proxy + external: true diff --git a/navidrome/compose.yml b/navidrome/compose.yml new file mode 100644 index 0000000..9bb7888 --- /dev/null +++ b/navidrome/compose.yml @@ -0,0 +1,32 @@ +services: + navidrome: + image: deluan/navidrome:0.61.0 + container_name: navidrome + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Los_Angeles + - ND_SCANSCHEDULE=1h + - ND_LOGLEVEL=info + - ND_MUSICFOLDER=/music + volumes: + - /mnt/storage/apps/navidrome/data:/data + - /mnt/storage/media/music:/music:ro + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:4533/ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' + networks: + - network +networks: + network: + name: proxy + external: true diff --git a/pia-qbittorrent/compose.yml b/pia-qbittorrent/compose.yml index 1a8ced2..7781861 100644 --- a/pia-qbittorrent/compose.yml +++ b/pia-qbittorrent/compose.yml @@ -1,32 +1,37 @@ services: - pia-qbittorrent: - image: j4ym0/pia-qbittorrent - container_name: pia-qbittorrent - cap_add: - - NET_ADMIN - environment: - - PUID=1000 - - PGID=1000 - - TZ=America/Los_Angeles - - PORT_FORWARDING=true - - PIA_REGION=ca_vancouver - - PIA_USERNAME=p4945400 - - PIA_PASSWORD=NmoPFuTDJt - - WEBUI_PORT=8112 - - DNS_SERVERS=1.1.1.1,1.0.0.1 - - UMASK=000 - volumes: - - /mnt/storage/apps/pia-qbittorrent/config:/config - - /mnt/storage/downloads:/downloads - ports: - - "8112:8112" - restart: unless-stopped - networks: - - pia - - proxy + pia-qbittorrent: + image: j4ym0/pia-qbittorrent@sha256:7f87f9e20ee400ea6a06e9ae9edb15b4dc8394c8dae460bd7dc1b9a4ffeed3f2 + container_name: pia-qbittorrent + cap_add: + - NET_ADMIN + env_file: + - .env + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Los_Angeles + - PORT_FORWARDING=true + - PIA_REGION=ca_vancouver + - WEBUI_PORT=8112 + - DNS_SERVERS=1.1.1.1,1.0.0.1 + - UMASK=000 + volumes: + - /mnt/storage/apps/pia-qbittorrent/config:/config + - /mnt/storage/downloads:/downloads + ports: + - "8112:8112" + restart: unless-stopped + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' + networks: + - pia + - proxy networks: - pia: - name: pia - proxy: - name: proxy - external: true + pia: + name: pia + proxy: + name: proxy + external: true diff --git a/prowlarr/compose.yml b/prowlarr/compose.yml index d8bb6a8..69022c4 100644 --- a/prowlarr/compose.yml +++ b/prowlarr/compose.yml @@ -1,6 +1,6 @@ services: prowlarr: - image: lscr.io/linuxserver/prowlarr:latest + image: lscr.io/linuxserver/prowlarr:2.3.0.5236-ls136 container_name: prowlarr environment: - PUID=1000 @@ -13,9 +13,20 @@ services: restart: unless-stopped extra_hosts: - "host.docker.internal:host-gateway" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9696/ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + deploy: + resources: + limits: + memory: 512M + cpus: '0.5' networks: - network networks: - network: - name: proxy - external: true + network: + name: proxy + external: true diff --git a/radarr/compose.yml b/radarr/compose.yml index 96194ac..c131bf2 100644 --- a/radarr/compose.yml +++ b/radarr/compose.yml @@ -1,6 +1,6 @@ services: radarr: - image: lscr.io/linuxserver/radarr:latest + image: lscr.io/linuxserver/radarr:6.0.4.10291-ls292 container_name: radarr environment: - PUID=1000 @@ -11,14 +11,23 @@ services: - /mnt/storage/media/Movies:/movies - /mnt/storage/media/KidsMovies:/kids - /mnt/storage/downloads/movies:/downloads - ports: - - 7878:7878 restart: unless-stopped extra_hosts: - "host.docker.internal:host-gateway" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:7878/ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' networks: - network networks: - network: - name: proxy - external: true + network: + name: proxy + external: true diff --git a/sonarr/compose.yml b/sonarr/compose.yml index aa8add9..63db129 100644 --- a/sonarr/compose.yml +++ b/sonarr/compose.yml @@ -1,6 +1,6 @@ services: sonarr: - image: lscr.io/linuxserver/sonarr:latest + image: lscr.io/linuxserver/sonarr:4.0.16.2944-ls302 container_name: sonarr environment: - PUID=1000 @@ -10,14 +10,23 @@ services: - /mnt/storage/apps/sonarr/data:/config - /mnt/storage/media/TV:/tv - /mnt/storage/downloads/tv:/downloads - ports: - - 8989:8989 restart: unless-stopped extra_hosts: - "host.docker.internal:host-gateway" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8989/ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + deploy: + resources: + limits: + memory: 1G + cpus: '1.0' networks: - network networks: - network: - name: proxy - external: true + network: + name: proxy + external: true diff --git a/stash/compose.yml b/stash/compose.yml index d0ff672..31cba56 100644 --- a/stash/compose.yml +++ b/stash/compose.yml @@ -1,44 +1,43 @@ services: stash: - image: stashapp/stash:latest + image: stashapp/stash@sha256:4cac18873ea052f03510602d9e1a9b29e6241a393a111479010292b7a1e28a5e container_name: stash + user: "1000:1000" restart: unless-stopped - ## the container's port must be the same with the STASH_PORT in the environment section ports: - "9999:9999" - ## If you intend to use stash's DLNA functionality uncomment the below network mode and comment out the above ports section - # network_mode: host logging: driver: "json-file" options: max-file: "10" max-size: "2m" environment: + - USER=stash + - HOME=/root - STASH_STASH=/data/ - STASH_GENERATED=/generated/ - STASH_METADATA=/metadata/ - STASH_CACHE=/cache/ - ## Adjust below to change default port (9999) - STASH_PORT=9999 volumes: - /etc/localtime:/etc/localtime:ro - ## Adjust below paths (the left part) to your liking. - ## E.g. you can change ./config:/root/.stash to ./stash:/root/.stash - ## The left part is the path on your host, the right part is the path in the stash container. - - ## Keep configs, scrapers, and plugins here. - /mnt/storage/apps/stash/.stash:/root/.stash - ## Point this at your collection. - ## The left side is where your collection is on your host, the right side is where it will be in stash. - /mnt/storage/media/Private:/data - ## This is where your stash's metadata lives - /mnt/storage/apps/stash/metadata:/metadata - ## Any other cache content. - /mnt/storage/apps/stash/cache:/cache - ## Where to store binary blob data (scene covers, images) - /mnt/storage/apps/stash/blobs:/blobs - ## Where to store generated content (screenshots,previews,transcodes,sprites) - /mnt/storage/apps/stash/generated:/generated + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9999/healthz"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + deploy: + resources: + limits: + memory: 4G + cpus: '2.0' networks: - network networks: diff --git a/vaultwarden/compose.yml b/vaultwarden/compose.yml index a29f378..30e7388 100644 --- a/vaultwarden/compose.yml +++ b/vaultwarden/compose.yml @@ -1,6 +1,6 @@ services: vaultwarden: - image: vaultwarden/server:latest + image: vaultwarden/server:1.35.4 container_name: vaultwarden environment: - PUID=1000 @@ -10,11 +10,20 @@ services: restart: unless-stopped volumes: - /mnt/storage/apps/vaultwarden/data/:/data/ - ports: - - 4444:80 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:80/alive"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s + deploy: + resources: + limits: + memory: 256M + cpus: '0.25' networks: - network networks: - network: - name: proxy - external: true + network: + name: proxy + external: true