228 lines
7.1 KiB
YAML
228 lines
7.1 KiB
YAML
name: core
|
|
services:
|
|
# --- SECURITY LAYER ---
|
|
docker-socket-proxy:
|
|
image: tecnativa/docker-socket-proxy:v0.4.2
|
|
container_name: docker-socket-proxy
|
|
restart: unless-stopped
|
|
userns_mode: "host"
|
|
user: "0:0"
|
|
security_opt:
|
|
- apparmor=unconfined
|
|
privileged: true
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
networks:
|
|
- proxy-net
|
|
group_add:
|
|
- "988" # Ensure this matches 'stat -c %g /var/run/docker.sock' on heimdall
|
|
environment:
|
|
# Read Access (for Traefik)
|
|
- CONTAINERS=1
|
|
- SERVICES=1
|
|
- NETWORKS=1
|
|
- VOLUMES=1
|
|
- IMAGES=1
|
|
- INFO=1
|
|
- VERSION=1
|
|
- EVENTS=1
|
|
- PING=1
|
|
# Write Access (Required for Komodo/Portainer to deploy)
|
|
- POST=1
|
|
- ALLOW_START=1
|
|
- ALLOW_STOP=1
|
|
- ALLOW_RESTARTS=1
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: redis
|
|
restart: unless-stopped
|
|
ports:
|
|
- "6379:6379"
|
|
networks:
|
|
- proxy-net
|
|
volumes:
|
|
- redis-data:/data
|
|
command: redis-server --appendonly yes
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# --- NETWORKING ---
|
|
traefik:
|
|
image: traefik:v3.6.5
|
|
container_name: traefik
|
|
restart: unless-stopped
|
|
depends_on:
|
|
redis:
|
|
condition: service_healthy
|
|
docker-socket-proxy:
|
|
condition: service_started
|
|
networks:
|
|
- proxy-net
|
|
environment:
|
|
- DOCKER_HOST=tcp://docker-socket-proxy:2375
|
|
- CLOUDFLARE_DNS_API_TOKEN=${CF_API_TOKEN}
|
|
- CLOUDFLARE_ZONE_API_TOKEN=${CF_ZONE_TOKEN}
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- /mnt/appdata/traefik/traefik.yml:/traefik.yml:ro
|
|
- /mnt/appdata/traefik/dynamic:/dynamic:ro
|
|
- /mnt/appdata/traefik/certs:/certs
|
|
- /mnt/appdata/traefik/access-logs:/var/log/traefik
|
|
labels:
|
|
- "traefik.enable=true"
|
|
# Router for the Dashboard
|
|
- "traefik.http.routers.traefik-secure.rule=Host(`proxy.castaldifamily.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
|
|
- "traefik.http.routers.traefik-secure.entrypoints=websecure"
|
|
- "traefik.http.routers.traefik-secure.tls=true"
|
|
- "traefik.http.routers.traefik-secure.tls.certresolver=cloudflare"
|
|
- "traefik.http.routers.traefik-secure.service=api@internal"
|
|
# Root Redirect (Optional but nice)
|
|
- "traefik.http.routers.traefik-root.rule=Host(`proxy.castaldifamily.com`) && Path(`/`)"
|
|
- "traefik.http.routers.traefik-root.entrypoints=websecure"
|
|
- "traefik.http.routers.traefik-root.tls=true"
|
|
- "traefik.http.routers.traefik-root.service=api@internal"
|
|
- "traefik.http.routers.traefik-root.middlewares=traefik-redir"
|
|
- "traefik.http.middlewares.traefik-redir.redirectregex.regex=^https?://proxy.castaldifamily.com/$$"
|
|
- "traefik.http.middlewares.traefik-redir.redirectregex.replacement=https://proxy.castaldifamily.com/dashboard/"
|
|
|
|
goaccess:
|
|
image: nginx:alpine
|
|
container_name: goaccess
|
|
restart: unless-stopped
|
|
environment:
|
|
- TZ=America/New_York
|
|
volumes:
|
|
- /mnt/appdata/traefik/access-logs:/usr/share/nginx/html:ro
|
|
ports:
|
|
- "7890:80"
|
|
networks:
|
|
- proxy-net
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.docker.network=proxy-net"
|
|
- "traefik.http.routers.analytics.rule=Host(`analytics.castaldifamily.com`)"
|
|
- "traefik.http.routers.analytics.entrypoints=websecure"
|
|
- "traefik.http.routers.analytics.tls=true"
|
|
- "traefik.http.routers.analytics.tls.certresolver=cloudflare"
|
|
- "traefik.http.routers.analytics.middlewares=analytics-auth"
|
|
- "traefik.http.services.analytics.loadbalancer.server.port=80"
|
|
- "traefik.http.middlewares.analytics-auth.basicauth.users=admin:$$2y$$05$$SryuOROtX8i7TC50nXPw6ejsaeaLkTEX1KY8r4R/zgriOLZyzRIG2"
|
|
|
|
goaccess-cron:
|
|
image: allinurl/goaccess:1.10
|
|
container_name: goaccess-cron
|
|
restart: unless-stopped
|
|
environment:
|
|
- TZ=America/New_York
|
|
volumes:
|
|
- /mnt/appdata/traefik/access-logs:/opt/log
|
|
entrypoint: /bin/sh
|
|
# Regenerate report.html every 5 minutes
|
|
command:
|
|
- -c
|
|
- |
|
|
while true; do
|
|
goaccess /opt/log/access.log --output=/opt/log/report.html --log-format=COMBINED
|
|
sleep 300
|
|
done
|
|
|
|
# --- MANAGEMENT ---
|
|
komodo-db:
|
|
image: mongo:7.0
|
|
container_name: komodo-db
|
|
labels:
|
|
komodo.skip: # Prevent Komodo from stopping with StopAllContainers
|
|
command: --quiet --wiredTigerCacheSizeGB 0.25
|
|
restart: unless-stopped
|
|
networks:
|
|
- proxy-net
|
|
# ports:
|
|
# - 27017:27017
|
|
volumes:
|
|
- /mnt/appdata/komodo/mongo/db:/data/db
|
|
- /mnt/appdata/komodo/mongo/config:/data/configdb
|
|
environment:
|
|
MONGO_INITDB_ROOT_USERNAME: ${KOMODO_DATABASE_USERNAME}
|
|
MONGO_INITDB_ROOT_PASSWORD: ${KOMODO_DATABASE_PASSWORD}
|
|
healthcheck:
|
|
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand({ ping: 1 })"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
start_period: 30s
|
|
|
|
komodo-core:
|
|
image: ghcr.io/moghtech/komodo-core:2
|
|
init: true
|
|
container_name: komodo-core
|
|
restart: unless-stopped
|
|
depends_on:
|
|
komodo-db:
|
|
condition: service_healthy
|
|
networks:
|
|
- proxy-net
|
|
ports:
|
|
- 9120:9120
|
|
env_file: .env
|
|
environment:
|
|
KOMODO_DATABASE_ADDRESS: komodo-db:27017
|
|
volumes:
|
|
- /mnt/appdata/komodo/keys:/config/keys
|
|
- /mnt/appdata/komodo/backups:/backups
|
|
- /mnt/appdata/komodo/heimdall/repos:/etc/komodo/repos
|
|
labels:
|
|
- komodo.skip
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.komodo.entrypoints=websecure"
|
|
- "traefik.http.routers.komodo.rule=Host(`komodo.castaldifamily.com`)"
|
|
- "traefik.http.routers.komodo.tls=true"
|
|
- "traefik.http.routers.komodo.tls.certresolver=cloudflare"
|
|
- "traefik.http.services.komodo.loadbalancer.server.port=9120"
|
|
|
|
periphery:
|
|
image: ghcr.io/moghtech/komodo-periphery:2
|
|
init: true
|
|
container_name: komodo-periphery-heimdall
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- komodo-core
|
|
- docker-socket-proxy
|
|
networks:
|
|
- proxy-net
|
|
environment:
|
|
- DOCKER_HOST=tcp://docker-socket-proxy:2375
|
|
- PERIPHERY_CORE_ADDRESS=ws://komodo-core:9120
|
|
- PERIPHERY_CONNECT_AS=Heimdall
|
|
- PERIPHERY_ONBOARDING_KEY=${KOMODO_ONBOARDING_KEY_HEIMDALL}
|
|
volumes:
|
|
- /proc:/proc # Still needed for accurate system stats
|
|
# Map the internal /config/keys to a unique folder for this node
|
|
- /mnt/appdata/komodo/heimdall/keys:/config/keys
|
|
# Map the internal /etc/komodo to a unique work folder for this node
|
|
- /mnt/appdata/komodo/heimdall/work:/etc/komodo
|
|
# Map the repo clone directory (Critical for GitOps)
|
|
- /mnt/appdata/komodo/heimdall/repos:/etc/komodo/repos
|
|
|
|
networks:
|
|
proxy-net:
|
|
name: proxy-net
|
|
driver: bridge
|
|
attachable: true
|
|
internal: false
|
|
enable_ipv6: false
|
|
driver_opts:
|
|
com.docker.network.bridge.name: br-proxy
|
|
com.docker.network.driver.mtu: "1500"
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: 172.100.0.0/24
|
|
gateway: 172.100.0.1
|
|
|
|
volumes:
|
|
redis-data: |