From 0496aadad747dc0a643858dc47caf121b1757fea Mon Sep 17 00:00:00 2001 From: Dave the Dev Date: Sat, 4 Jul 2026 18:17:53 +0000 Subject: [PATCH] Initial commit --- .gitignore | 3 + AGENT.md | 48 +++++++++++ Authentik/docker-compose.yaml | 80 +++++++++++++++++ CFDevTunnelMapping/docker-compose.yaml | 18 ++++ Cloudflare/docker-compose.yaml | 7 ++ Cloudflare_dev_tunnel/docker-compose.yaml | 6 ++ Cloutflare_test_tunnel/docker-compose.yml | 8 ++ Firecrawl/docker-compose.yaml | 38 ++++++++ Gitea/docker-compose.yaml | 74 ++++++++++++++++ Immich/docker-compose.yml | 68 +++++++++++++++ Immich/hwaccel.yml | 25 ++++++ Jellyfin/docker-compose.yaml | 51 +++++++++++ Portainer Dev/docker-compose.yaml | 11 +++ Portainer/docker-compose.yaml | 16 ++++ README.md | 4 + Torrent-VPN/docker-compose.yml | 100 ++++++++++++++++++++++ 16 files changed, 557 insertions(+) create mode 100644 .gitignore create mode 100644 AGENT.md create mode 100644 Authentik/docker-compose.yaml create mode 100644 CFDevTunnelMapping/docker-compose.yaml create mode 100644 Cloudflare/docker-compose.yaml create mode 100644 Cloudflare_dev_tunnel/docker-compose.yaml create mode 100644 Cloutflare_test_tunnel/docker-compose.yml create mode 100644 Firecrawl/docker-compose.yaml create mode 100644 Gitea/docker-compose.yaml create mode 100644 Immich/docker-compose.yml create mode 100644 Immich/hwaccel.yml create mode 100644 Jellyfin/docker-compose.yaml create mode 100644 Portainer Dev/docker-compose.yaml create mode 100644 Portainer/docker-compose.yaml create mode 100644 README.md create mode 100644 Torrent-VPN/docker-compose.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..953b6d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.env +.idea/ +Gitlab/ \ No newline at end of file diff --git a/AGENT.md b/AGENT.md new file mode 100644 index 0000000..56c4693 --- /dev/null +++ b/AGENT.md @@ -0,0 +1,48 @@ +# HomeLabDocker Repository Agent Context + +This repository contains Docker Compose configurations for various self-hosted services. + +## Structure + +Each service has its own directory containing: +- `docker-compose.yaml` - The Docker Compose configuration +- `stack.env` - Environment variables (excluded from version control via .gitignore) + +## Guidelines for Adding New Services + +### 1. Environment Variables +- Always use environment variables in `docker-compose.yaml` for paths and sensitive values +- Environment variable format: `${VAR_NAME}` +- Define default values in `stack.env` +- Example: `${FIRECRAWL_DATA_DIR}` instead of hardcoded paths like `/usr/share/devhome/firecrawl/data` + +### 2. Container Naming +- Use environment suffix for container names: `container_name: service_${ENV}` +- This allows running multiple environments (dev, staging, prod) simultaneously +- Always include `ENV` as an environment variable in stack.env + +### 3. Health Checks +- Include healthcheck blocks for all services +- Use curl or wget for HTTP endpoints +- Example: + ```yaml + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3002/health || exit 1"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 30s + ``` + +### 4. Networks +- Do NOT define networks explicitly - Docker Compose automatically creates a default bridge network +- Other configs in this project (Gitea, Authentik, Cloudflare) do NOT define networks explicitly + +### 5. Volumes +- Use environment variables for volume paths +- Include timezone mount: `/etc/localtime:/etc/localtime:ro` + +### 6. Files to Create +When adding a new service, create: +- `/docker-compose.yaml` +- `/stack.env` (add to .gitignore) \ No newline at end of file diff --git a/Authentik/docker-compose.yaml b/Authentik/docker-compose.yaml new file mode 100644 index 0000000..8d85a53 --- /dev/null +++ b/Authentik/docker-compose.yaml @@ -0,0 +1,80 @@ +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 + ports: + - 5432:5432 + volumes: + - /home/hitanshu/authentik/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: + - /home/hitanshu/authentik/redis:/data + server: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.4} + 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: + - /home/hitanshu/authentik/media:/media + - /home/hitanshu/authentik/custom-templates:/templates + env_file: + - ../stack.env + ports: + - "${COMPOSE_PORT_HTTP:-9000}:9000" + - "${COMPOSE_PORT_HTTPS:-9443}:1443" + depends_on: + - postgresql + - redis + worker: + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.4} + 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 + - /home/hitanshu/authentik/media:/media + - /home/hitanshu/authentik/certs:/certs + - /home/hitanshu/authentik/custom-templates:/templates + env_file: + - ../stack.env + depends_on: + - postgresql + - redis diff --git a/CFDevTunnelMapping/docker-compose.yaml b/CFDevTunnelMapping/docker-compose.yaml new file mode 100644 index 0000000..43de63d --- /dev/null +++ b/CFDevTunnelMapping/docker-compose.yaml @@ -0,0 +1,18 @@ +services: + app: + build: . + image: kruti/cfdevtunnlemapping:latest + container_name: cfdevtunnlemapping + environment: + - USERNAME=${USERNAME} + - PASSWORD=${PASSWORD} + - PORT=5001 + - GUID=${GUID} + - ZONE_ID=${ZONE_ID} + - AUTH_EMAIL=${AUTH_EMAIL} + - AUTH_KEY=${AUTH_KEY} + ports: + - 5001:5001 + restart: unless-stopped + volumes: + - ${CONFIG_PATH}:/res/ \ No newline at end of file diff --git a/Cloudflare/docker-compose.yaml b/Cloudflare/docker-compose.yaml new file mode 100644 index 0000000..46c3d90 --- /dev/null +++ b/Cloudflare/docker-compose.yaml @@ -0,0 +1,7 @@ +version: '3.7' +services: + cloudflared: + container_name: cloudflared + image: cloudflare/cloudflared:latest + restart: unless-stopped + command: tunnel --no-autoupdate run --token ${TOKEN} \ No newline at end of file diff --git a/Cloudflare_dev_tunnel/docker-compose.yaml b/Cloudflare_dev_tunnel/docker-compose.yaml new file mode 100644 index 0000000..e9fb89e --- /dev/null +++ b/Cloudflare_dev_tunnel/docker-compose.yaml @@ -0,0 +1,6 @@ +services: + cloudflared: + container_name: cloudflared_dev + image: cloudflare/cloudflared:latest + restart: on-failure + command: tunnel --no-autoupdate run --token ${TOKEN} \ No newline at end of file diff --git a/Cloutflare_test_tunnel/docker-compose.yml b/Cloutflare_test_tunnel/docker-compose.yml new file mode 100644 index 0000000..fb73473 --- /dev/null +++ b/Cloutflare_test_tunnel/docker-compose.yml @@ -0,0 +1,8 @@ +services: + cloudflared: + container_name: cloudflare_test_tunnel + image: cloudflare/cloudflared:2022.3.2 + restart: "unless-stopped" + volumes: + - /etc/cloudflared/:/etc/cloudflared/ + command: tunnel --origincert /etc/cloudflared/cert.pem run ${GUID} diff --git a/Firecrawl/docker-compose.yaml b/Firecrawl/docker-compose.yaml new file mode 100644 index 0000000..da2ee79 --- /dev/null +++ b/Firecrawl/docker-compose.yaml @@ -0,0 +1,38 @@ +name: firecrawl + +# Firecrawl MCP Server - Self-hosted web scraping for LLM applications +# https://docs.firecrawl.dev/mcp +# +# This provides an MCP server for web scraping that can be used with: +# - Claude Desktop +# - Cursor +# - Windsurf +# - Other MCP-compatible clients +# +# To expose behind a reverse proxy (Cloudflare Tunnel), configure: +# - The service listens on port 3002 +# - HTTP endpoints enabled for remote MCP access +# +services: + firecrawl: + image: ghcr.io/firecrawl/firecrawl-mcp:latest + container_name: firecrawl_${ENV} + restart: always + environment: + - ENV=${ENV} + - FIRECRAWL_API_KEY=${FIRECRAWL_API_KEY} + # Enable HTTP endpoint for remote MCP access + - ENABLE_HTTP_STREAMABLE_ENDPOINT=true + - ENABLE_SSE_ENDPOINT=true + - PORT=3002 + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3002/health || exit 1"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 30s + ports: + - "3002:3002" + volumes: + - ${FIRECRAWL_DATA_DIR}:/data + - /etc/localtime:/etc/localtime:ro \ No newline at end of file diff --git a/Gitea/docker-compose.yaml b/Gitea/docker-compose.yaml new file mode 100644 index 0000000..6085d60 --- /dev/null +++ b/Gitea/docker-compose.yaml @@ -0,0 +1,74 @@ +networks: + gitea: + external: false + +services: + server: + image: docker.io/gitea/gitea:1.22.6 + container_name: gitea + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST=db:5432 + - GITEA__database__NAME=gitea + - GITEA__database__USER=gitea + - GITEA__database__PASSWD=${POSTGRES_PASSWD} + - GITEA__server__DOMAIN="gitea.hithomelabs.com" + - GITEA__server__HTTP_PORT=3000 + - GITEA__server__ROOT_URL="https://gitea.hithomelabs.com/" + - GITEA__server__DISABLE_SSH=false + - GITEA__server__SSH_LISTEN_PORT=22 + - GITEA__server__SSH_PORT=2423 + - GITEA__server__SSH_DOMAIN="sshgitea.hithomelabs.com" + - GITEA__mailer__ENABLED=true + - GITEA__mailer__SMTP_ADDR=smtp.gmail.com + - GITEA__mailer__SMTP_PORT=465 + - GITEA__mailer__FROM="No Reply " + - GITEA__mailer__USER="hithomelabs" + - GITEA__mailer__PASSWD=${GITEA__mailer__PASSWD} + - GITEA__mailer__PROTOCOL=smtps + - GITEA__openid__ENABLE_OPENID_SIGNIN=true + - GITEA__openid__ENABLE_OPENID_SIGNUP=true + - ENABLE_AUTO_REGISTRATION=true + - ALLOW_ONLY_EXTERNAL_REGISTRATION=true + restart: always + networks: + - gitea + volumes: + - /usr/share/devhome/gitea/data:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - "8928:3000" + - "2423:22" + depends_on: + - db + db: + image: docker.io/library/postgres:14 + restart: always + environment: + - POSTGRES_USER=gitea + - POSTGRES_PASSWORD=${POSTGRES_PASSWD} + - POSTGRES_DB=gitea + networks: + - gitea + volumes: + - /usr/share/devhome/gitea/postgres:/var/lib/postgresql/data + runner: + image: docker.io/gitea/act_runner:latest + restart: unless-stopped + environment: + - CONFIG_FILE=/config/config.yaml + - GITEA_INSTANCE_URL=${INSTANCE_URL} + - GITEA_RUNNER_REGISTRATION_TOKEN=${REGISTRATION_TOKEN} + - GITEA_RUNNER_NAME=${RUNNER_NAME} + - GITEA_RUNNER_LABELS=${RUNNER_LABELS} + volumes: + - /usr/share/devhome/gitea/runner/config:/config + - /usr/share/devhome/gitea/runner/data:/data + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - server + networks: + - gitea diff --git a/Immich/docker-compose.yml b/Immich/docker-compose.yml new file mode 100644 index 0000000..c06a60f --- /dev/null +++ b/Immich/docker-compose.yml @@ -0,0 +1,68 @@ +# +# 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} + extends: + file: hwaccel.yml + service: nvenc + volumes: + - ${UPLOAD_LOCATION}:/usr/src/app/upload + - ${EXTERNAL_PATH}:/usr/src/app/external + - /etc/localtime:/etc/localtime:ro + env_file: + - ../stack.env + ports: + - 2283:2283 + depends_on: + - redis + - database + restart: always + healthcheck: + disable: false + + 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 + healthcheck: + disable: false + + redis: + container_name: immich_redis + image: docker.io/valkey/valkey:8-bookworm + restart: always + healthcheck: + test: redis-cli ping || exit 1 + + database: + container_name: immich_postgres + image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0 + env_file: + - ../stack.env + environment: + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_USER: ${DB_USERNAME} + POSTGRES_DB: ${DB_DATABASE_NAME} + POSTGRES_INITDB_ARGS: '--data-checksums' + volumes: + - pgdata:/var/lib/postgresql/data + restart: always + shm_size: 128mb + +volumes: + pgdata: + model-cache: diff --git a/Immich/hwaccel.yml b/Immich/hwaccel.yml new file mode 100644 index 0000000..2592bef --- /dev/null +++ b/Immich/hwaccel.yml @@ -0,0 +1,25 @@ +version: "3.8" + +# Hardware acceleration for transcoding - Optional +# This is only needed if you want to use hardware acceleration for transcoding. +# Depending on your hardware, you should uncomment the relevant lines below. + +services: + hwaccel: + # devices: + # - /dev/dri:/dev/dri # If using Intel QuickSync or VAAPI + # volumes: + # - /usr/lib/wsl:/usr/lib/wsl # If using VAAPI in WSL2 + # environment: + # - LD_LIBRARY_PATH=/usr/lib/wsl/lib # If using VAAPI in WSL2 + # - LIBVA_DRIVER_NAME=d3d12 # If using VAAPI in WSL2 + deploy: # Uncomment this section if using NVIDIA GPU + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: + - gpu + - compute + - video diff --git a/Jellyfin/docker-compose.yaml b/Jellyfin/docker-compose.yaml new file mode 100644 index 0000000..ae6be20 --- /dev/null +++ b/Jellyfin/docker-compose.yaml @@ -0,0 +1,51 @@ +version: "3" +services: + jellyfin: + image: jellyfin/jellyfin:latest + container_name: jellyfin_gpu + network_mode: 'host' + volumes: + - /srv/jellyfin/cache:/cache + - /srv/jellyfin/config:/config + - /hdd2_500gb:/media:ro + - /ssd2_500gb/media:/media2:ro + environment: + - PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + - HEALTHCHECK_URL=http://localhost:8096/health + - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 + - LC_ALL=en_US.UTF-8 + - LANG=en_US.UTF-8 + - JELLYFIN_DATA_DIR=/config + - JELLYFIN_CACHE_DIR=/cache + - JELLYFIN_CONFIG_DIR=/config/config + - JELLYFIN_LOG_DIR=/config/log + - JELLYFIN_WEB_DIR=/jellyfin/jellyfin-web + - JELLYFIN_FFMPEG=/usr/lib/jellyfin-ffmpeg/ffmpeg + - MALLOC_TRIM_THRESHOLD_=131072 + - NVIDIA_VISIBLE_DEVICES=all + - NVIDIA_DRIVER_CAPABILITIES=compute,video,utility + restart: always + runtime: nvidia + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [compute,utility,video] + + jellyseerr: + image: krutiee/jellyseerr:latest + container_name: jellyseerr + network_mode: 'host' + depends_on: + - jellyfin + environment: + - LOG_LEVEL=debug + - TZ=Asia/Kolkata + - commitTag=${COMMIT_TAG} + ports: + - 5055:5055 + volumes: + - /home/$USER/jellyseerr:/app/config + restart: unless-stopped diff --git a/Portainer Dev/docker-compose.yaml b/Portainer Dev/docker-compose.yaml new file mode 100644 index 0000000..ed6f3e4 --- /dev/null +++ b/Portainer Dev/docker-compose.yaml @@ -0,0 +1,11 @@ +services: + portainer: + image: "portainer/portainer-ce:latest" + container_name: "portainer_dev" + ports: + - "7999:8999" + - "9442:9443" + restart: "always" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + - "/usr/share/devhome/PortainerDev/portainer-data/:/data/" \ No newline at end of file diff --git a/Portainer/docker-compose.yaml b/Portainer/docker-compose.yaml new file mode 100644 index 0000000..18e48b3 --- /dev/null +++ b/Portainer/docker-compose.yaml @@ -0,0 +1,16 @@ +version: "3.6" +services: + portainer: + image: "portainer/portainer-ce:latest" + container_name: "portainer" + ports: + - "8000:8000" + - "9443:9443" + restart: "always" + volumes: + - "/home/${USER}/HomeLabDocker:/envhome" + - "/var/run/docker.sock:/var/run/docker.sock" + - "portainer_data:/data" +volumes: + portainer_data: + external: true diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ead749 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# HomeLabDocker +Backing up docker compose configs of my homelab. +Agents should raise new PRs for issue against main of the organizational repo. +Test from developer agent via SSH \ No newline at end of file diff --git a/Torrent-VPN/docker-compose.yml b/Torrent-VPN/docker-compose.yml new file mode 100644 index 0000000..280cdf6 --- /dev/null +++ b/Torrent-VPN/docker-compose.yml @@ -0,0 +1,100 @@ +version: "3" +services: + gluetun: + image: qmcgaw/gluetun + container_name: gluetun + # line above must be uncommented to allow external containers to connect. + # See https://github.com/qdm12/gluetun-wiki/blob/main/setup/connect-a-container-to-gluetun.md#external-container-to-gluetun + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun:/dev/net/tun + ports: + - 6881:6881 + - 6881:6881/udp + - 8085:8085 # qbittorrent + - 7878:7878 # radarr + - 8989:8989 # Sonarr + - 9696:9696 # Prowlarr + - 6767:6767 # bazarr + volumes: + - /home/ubuntu/docker/arr-stack:/gluetun + environment: + - VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER} + - OPENVPN_USER=${OPENVPN_USER} + - OPENVPN_PASSWORD=${OPENVPN_PASSWORD} + restart: always + + qbittorrent: + image: lscr.io/linuxserver/qbittorrent + container_name: qbittorrent + network_mode: "service:gluetun" + environment: + - PUID=1000 + - PGID=1000 + - TZ=Asia/Kolkata + - WEBUI_PORT=8085 + volumes: + - /home/${USER}/arr/qbittorrent:/config + - ${DOWNLOADS}:/downloads + depends_on: + - gluetun + restart: always + + bazarr: + image: lscr.io/linuxserver/bazarr:latest + container_name: bazarr + network_mode: "service:gluetun" + environment: + - PUID=1000 + - PGID=1000 + - TZ=Asia/Kolkata + volumes: + - /home/${USER}/arr/bazarr:/config + - /ssd2_500gb/media/movies:/movies #optional + - /ssd2_500gb/media/series:/series #optional + depends_on: + - gluetun + restart: always + + sonarr: + image: lscr.io/linuxserver/sonarr:latest + container_name: sonarr + network_mode: "service:gluetun" + environment: + - PUID=1000 + - PGID=1000 + - TZ=Asia/Kolkata + volumes: + - /home/${USER}/arr/sonarr:/config + - /media/series:/series #optional + - /ssd2_500gb/media/series:/series2 + - ${DOWNLOADS}:/downloads #optional + restart: always + + radarr: + image: lscr.io/linuxserver/radarr:latest + container_name: radarr + network_mode: "service:gluetun" + environment: + - PUID=1000 + - PGID=1000 + - TZ=Asia/Kolkata + volumes: + - /home/${USER}/arr/radarr:/config + - /ssd2_500gb/media/movies:/movies #optional + - ${DOWNLOADS}:/downloads #optional + restart: always + + prowlarr: + image: lscr.io/linuxserver/prowlarr:latest + container_name: prowlarr + network_mode: "service:gluetun" + environment: + - PUID=1000 + - PGID=1000 + - TZ=Aisa/Kolkata + volumes: + - /home/${USER}/arr/prowlarr/data/:/config + restart: always +