commit 61cb822c1994197d83b8b67e89051892edac15d2 Author: craisin Date: Mon Nov 24 12:51:29 2025 -0800 Initial commit diff --git a/compose.yml b/compose.yml new file mode 100755 index 0000000..1c32e30 --- /dev/null +++ b/compose.yml @@ -0,0 +1,286 @@ +name: lab +services: + #Networking + cloudflared: + container_name: cloudflared + image: cloudflare/cloudflared:latest + environment: + TUNNEL_TOKEN: ${TUNNEL_TOKEN} + command: tunnel --no-autoupdate run + restart: always + 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 + 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 + 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 + 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" + + 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 + 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 + 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 + + # 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 + +networks: + default: + driver: bridge + ipam: + config: + - subnet: 10.5.0.0/16 + gateway: 10.5.0.1