Files
homelab-compose/compose.yml
craisin 99023f4408
All checks were successful
Update Compose File / build (push) Successful in 7s
add path
2025-11-29 12:48:18 -08:00

336 lines
10 KiB
YAML
Executable File

name: lab
services:
#Networking
cloudflared:
container_name: cloudflared
image: cloudflare/cloudflared:latest
environment:
TUNNEL_TOKEN: ${TUNNEL_TOKEN}
command: tunnel --no-autoupdate run
restart: always
dns:
- ${DNS_SERVER}
networks:
default:
ipv4_address: 10.5.1.0
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "8000:443"
environment:
TZ: ${TZ}
FTLCONF_webserver_api_password: ${PIHOLE_PASS}
FTLCONF_dns_listeningMode: 'all'
volumes:
- ${DATA}/pihole:/etc/pihole
restart: always
networks:
default:
ipv4_address: ${DNS_SERVER}
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.pihole.rule=Host(`pihole.${DOMAIN}`)"
- "traefik.http.routers.pihole.entrypoints=https"
- "traefik.http.routers.pihole.tls=true"
- "traefik.http.services.pihole.loadbalancer.server.port=80"
traefik:
container_name: traefik
image: traefik:v3.0
ports:
- 80:80
- 443:443
environment:
CF_DNS_API_TOKEN: ${DNS_API_TOKEN}
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ${DATA}/traefik/traefik.yml:/traefik.yml:ro
- ${DATA}/traefik/acme.json:/acme.json
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_PASS}"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.${DOMAIN}`)"
- "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare"
- "traefik.http.routers.traefik-secure.tls.domains[0].main=${DOMAIN}"
- "traefik.http.routers.traefik-secure.tls.domains[0].sans=*.${DOMAIN}"
- "traefik.http.routers.traefik-secure.service=api@internal"
# Productivity
crontab-guru:
container_name: crontab-guru
image: gitea.craisin.tech/craisin/crontab_guru:latest
environment:
CRONITOR_USERNAME: ${CRONTAB_USER}
CRONITOR_PASSWORD: ${CRONTAB_PASS}
volumes:
- /var/spool/cron/crontabs:/var/spool/cron/crontabs
- /etc/crontab:/etc/crontab
restart: always
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.crontab.rule=Host(`crontab.${DOMAIN}`)"
- "traefik.http.routers.crontab.entrypoints=https"
- "traefik.http.routers.crontab.tls=true"
- "traefik.http.services.crontab.loadbalancer.server.port=9000"
code-server:
container_name: code-server
image: lscr.io/linuxserver/code-server:latest
environment:
PUID: ${PUID}
PGID: ${PGID}
TZ: ${TZ}
SUDO_PASSWORD: ${SUDO_PASS}
DOCKER_MODS: "linuxserver/mods:code-server-python3|linuxserver/mods:universal-docker-in-docker"
volumes:
- ${DATA}/code-server:/config
dns:
- ${DNS_SERVER}
privileged: true
restart: always
gitea:
container_name: gitea
image: docker.gitea.com/gitea:latest
environment:
USER_UID: ${PUID}
USER_GID: ${PGID}
volumes:
- ${DATA}/gitea:/data
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`gitea.${DOMAIN}`)"
- "traefik.http.routers.gitea.entrypoints=https"
- "traefik.http.routers.gitea.tls=true"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
gitea-act-runner:
container_name: gitea-act-runner
image: docker.io/gitea/act_runner:latest
environment:
CONFIG_FILE: /config.yaml
GITEA_INSTANCE_URL: "https://gitea.${DOMAIN}"
GITEA_RUNNER_REGISTRATION_TOKEN: "${ACT_RUNNER_TOKEN}"
GITEA_RUNNER_NAME: "Homelab CI CD Pipeline"
dns:
- ${DNS_SERVER}
volumes:
- ${DATA}/gitea-runner/config.yaml:/config.yaml
- ${DATA}/gitea-runner/data:/data
home-assistant:
container_name: home-assistant
image: "ghcr.io/home-assistant/home-assistant:stable"
environment:
TZ: ${TZ}
volumes:
- ${DATA}/home-assistant:/config
- /etc/localtime:/etc/localtime:ro
- /run/dbus:/run/dbus:ro
- ${DRIVE}/music:/media/music
privileged: true
network_mode: host # WebUI is Port 8123
restart: unless-stopped
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:release
ports:
- 2283:2283
environment:
UPLOAD_LOCATION: ${DRIVE}/images
DB_DATA_LOCATION: ${DATA}/immich/db
TZ: ${TZ}
DB_USERNAME: ${IMMICH_DB_USER}
DB_PASSWORD: ${IMMICH_DB_PASS}
DB_DATABASE_NAME: ${IMMICH_DB_NAME}
DB_HOSTNAME: "immich-database"
REDIS_HOSTNAME: "immich-redis"
volumes:
- ${DRIVE}/images:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
depends_on:
- immich-redis
- immich-database
restart: unless-stopped
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.immich.rule=Host(`immich.${DOMAIN}`)"
- "traefik.http.routers.immich.entrypoints=https"
- "traefik.http.routers.immich.tls=true"
- "traefik.http.services.immich.loadbalancer.server.port=2283"
immich-redis:
container_name: immich-redis
image: docker.io/valkey/valkey:8@sha256:81db6d39e1bba3b3ff32bd3a1b19a6d69690f94a3954ec131277b9a26b95b3aa
restart: unless-stopped
immich-database:
container_name: immich-postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23
environment:
POSTGRES_PASSWORD: ${IMMICH_DB_PASS}
POSTGRES_USER: ${IMMICH_DB_USER}
POSTGRES_DB: ${IMMICH_DB_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
volumes:
- ${DATA}/immich/db:/var/lib/postgresql/data
shm_size: 128mb
restart: unless-stopped
navidrome:
container_name: navidrome
image: deluan/navidrome:latest
restart: unless-stopped
volumes:
- ${DATA}/navidrome:/data
- ${DRIVE}/music:/music
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.navidrome.rule=Host(`navidrome.${DOMAIN}`)"
- "traefik.http.routers.navidrome.entrypoints=https"
- "traefik.http.routers.navidrome.tls=true"
- "traefik.http.services.navidrome.loadbalancer.server.port=4533"
metube:
container_name: metube
image: ghcr.io/alexta69/metube:latest
restart: unless-stopped
volumes:
- ${DRIVE}/music:/downloads
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.metube.rule=Host(`metube.${DOMAIN}`)"
- "traefik.http.routers.metube.entrypoints=https"
- "traefik.http.routers.metube.tls=true"
- "traefik.http.services.metube.loadbalancer.server.port=8081"
picard:
container_name: picard
image: mikenye/picard:latest
volumes:
- ${DATA}/picard/config:/config
- ${DRIVE}/music:/music
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.picard.rule=Host(`picard.${DOMAIN}`)"
- "traefik.http.routers.picard.entrypoints=https"
- "traefik.http.routers.picard.tls=true"
- "traefik.http.services.picard.loadbalancer.server.port=5800"
nextcloud:
container_name: nextcloud
image: lscr.io/linuxserver/nextcloud:latest
environment:
PUID: ${PUID}
PGID: ${PGID}
TZ: ${TZ}
volumes:
- ${DATA}/nextcloud/config:/config
- ${DATA}/nextcloud/data:/data
- ${DRIVE}/docs:/docs
- ${DRIVE}/notes:/notes
restart: always
labels: #traefik
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`nextcloud.${DOMAIN}`)"
- "traefik.http.routers.nextcloud.entrypoints=https"
- "traefik.http.routers.nextcloud.tls=true"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
syncthing:
container_name: syncthing
image: lscr.io/linuxserver/syncthing:latest
environment:
PUID: ${PUID}
PGID: ${PGID}
TZ: ${TZ}
volumes:
- ${DATA}/syncthing:/config
- ${DRIVE}/notes/vault:/vault
ports:
- 22000:22000/tcp
- 22000:22000/udp
- 21027:21027/udp
restart: always
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.syncthing.rule=Host(`syncthing.${DOMAIN}`)"
- "traefik.http.routers.syncthing.entrypoints=https"
- "traefik.http.routers.syncthing.tls=true"
- "traefik.http.services.syncthing.loadbalancer.server.port=8384"
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
environment:
DOMAIN: "https://vault.${DOMAIN}"
volumes:
- ${DATA}/vaultwarden:/data
restart: unless-stopped
watchtower:
container_name: watchtower
image: containrrr/watchtower:latest
environment:
WATCHTOWER_CLEANUP: true
WATCHTOWER_POLL_INTERVAL: 30
WATCHTOWER_DISABLE_CONTAINERS: "cloudflared pihole vaultwarden"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
# Personal Websites
craisin-cove:
container_name: craisin-cove
image: gitea.craisin.tech/craisin/craisin_cove:latest
restart: unless-stopped
shape-ai:
container_name: shape-ai
image: gitea.craisin.tech/craisin/shape_ai:latest
restart: unless-stopped
obsidian:
image: lscr.io/linuxserver/obsidian:latest
container_name: obsidian
environment:
PUID: ${PUID}
PGID: ${PGID}
TZ: ${TZ}
volumes:
- ${DATA}/obsidian:/config
- ${DRIVE}/notes/vault:/obsidian
restart: unless-stopped
labels: # traefik
- "traefik.enable=true"
- "traefik.http.routers.obsidian.rule=Host(`obsidian.${DOMAIN}`)"
- "traefik.http.routers.obsidian.entrypoints=https"
- "traefik.http.routers.obsidian.tls=true"
- "traefik.http.services.obsidian.loadbalancer.server.port=3000"
networks:
default:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16
gateway: 10.5.0.1