2025-11-15 17:00:36 +01:00
|
|
|
services:
|
|
|
|
|
# Traefik - Reverse proxy and load balancer
|
|
|
|
|
traefik:
|
|
|
|
|
image: ${NET_PROXY_DOCKER_IMAGE}
|
|
|
|
|
container_name: ${NET_COMPOSE_PROJECT_NAME}_traefik
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
command:
|
|
|
|
|
# API & Dashboard
|
|
|
|
|
- '--api.dashboard=true'
|
|
|
|
|
- '--api.insecure=false'
|
|
|
|
|
|
|
|
|
|
# Ping endpoint for healthcheck
|
|
|
|
|
- '--ping=true'
|
|
|
|
|
|
|
|
|
|
# Experimental plugins
|
|
|
|
|
- '--experimental.plugins.sablier.modulename=github.com/acouvreur/sablier'
|
|
|
|
|
- '--experimental.plugins.sablier.version=v1.8.0'
|
|
|
|
|
|
|
|
|
|
# Logging
|
|
|
|
|
- '--log.level=${NET_PROXY_LOG_LEVEL:-INFO}'
|
|
|
|
|
- '--accesslog=true'
|
|
|
|
|
|
|
|
|
|
# Global
|
|
|
|
|
- '--global.sendAnonymousUsage=false'
|
|
|
|
|
- '--global.checkNewVersion=true'
|
|
|
|
|
|
|
|
|
|
# Docker Provider
|
|
|
|
|
- '--providers.docker=true'
|
|
|
|
|
- '--providers.docker.exposedbydefault=false'
|
|
|
|
|
- '--providers.docker.network=${NETWORK_NAME}'
|
|
|
|
|
|
|
|
|
|
# File Provider for dynamic configuration
|
|
|
|
|
- '--providers.file.directory=/etc/traefik/dynamic'
|
|
|
|
|
- '--providers.file.watch=true'
|
|
|
|
|
|
|
|
|
|
# Entrypoints
|
|
|
|
|
- '--entrypoints.web.address=:${NET_PROXY_PORT_HTTP:-80}'
|
|
|
|
|
- '--entrypoints.web-secure.address=:${NET_PROXY_PORT_HTTPS:-443}'
|
|
|
|
|
|
|
|
|
|
# Global HTTP to HTTPS redirect
|
|
|
|
|
- '--entrypoints.web.http.redirections.entryPoint.to=web-secure'
|
|
|
|
|
- '--entrypoints.web.http.redirections.entryPoint.scheme=https'
|
|
|
|
|
- '--entrypoints.web.http.redirections.entryPoint.permanent=true'
|
|
|
|
|
|
|
|
|
|
# Security Headers (applied globally)
|
|
|
|
|
- '--entrypoints.web-secure.http.middlewares=security-headers@file'
|
|
|
|
|
|
|
|
|
|
# Let's Encrypt
|
|
|
|
|
- '--certificatesresolvers.resolver.acme.tlschallenge=true'
|
|
|
|
|
- '--certificatesresolvers.resolver.acme.email=${ADMIN_EMAIL}'
|
|
|
|
|
- '--certificatesresolvers.resolver.acme.storage=/letsencrypt/acme.json'
|
|
|
|
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
test: ["CMD", "traefik", "healthcheck", "--ping"]
|
|
|
|
|
interval: 30s
|
|
|
|
|
timeout: 5s
|
|
|
|
|
retries: 3
|
|
|
|
|
start_period: 10s
|
|
|
|
|
|
|
|
|
|
environment:
|
|
|
|
|
AUTH_USERS: ${AUTH_USERS}
|
|
|
|
|
|
|
|
|
|
networks:
|
|
|
|
|
- compose_network
|
2025-11-15 17:28:32 +01:00
|
|
|
- coolify
|
2025-11-15 17:00:36 +01:00
|
|
|
|
|
|
|
|
ports:
|
|
|
|
|
- "${NET_PROXY_PORT_HTTP:-80}:80"
|
|
|
|
|
- "${NET_PROXY_PORT_HTTPS:-443}:443"
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
- letsencrypt_data:/letsencrypt
|
|
|
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
|
|
|
- ./dynamic:/etc/traefik/dynamic:ro
|
|
|
|
|
|
|
|
|
|
labels:
|
|
|
|
|
- 'traefik.enable=true'
|
|
|
|
|
# HTTP to HTTPS redirect
|
|
|
|
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-traefik-redirect-web-secure.redirectscheme.scheme=https'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web.middlewares=${NET_COMPOSE_PROJECT_NAME}-traefik-redirect-web-secure'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web.rule=Host(`${NET_PROXY_TRAEFIK_HOST}`)'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web.entrypoints=web'
|
|
|
|
|
# HTTPS router with auth
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web-secure.rule=Host(`${NET_PROXY_TRAEFIK_HOST}`)'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web-secure.tls.certresolver=resolver'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web-secure.entrypoints=web-secure'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web-secure.service=api@internal'
|
|
|
|
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-traefik-auth.basicauth.users=${AUTH_USERS}'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-traefik-web-secure.middlewares=${NET_COMPOSE_PROJECT_NAME}-traefik-auth'
|
|
|
|
|
- 'traefik.http.services.${NET_COMPOSE_PROJECT_NAME}-traefik-web-secure.loadbalancer.server.port=8080'
|
|
|
|
|
- 'traefik.docker.network=${NETWORK_NAME}'
|
|
|
|
|
|
|
|
|
|
# Netdata - Real-time monitoring
|
|
|
|
|
netdata:
|
|
|
|
|
build:
|
|
|
|
|
context: .
|
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
|
image: ${NET_NETDATA_IMAGE:-netdata/netdata:latest}
|
|
|
|
|
container_name: ${NET_COMPOSE_PROJECT_NAME}_netdata
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
hostname: ${NET_NETDATA_HOSTNAME:-netdata.pivoine.art}
|
|
|
|
|
cap_add:
|
|
|
|
|
- SYS_PTRACE
|
|
|
|
|
- SYS_ADMIN
|
|
|
|
|
security_opt:
|
|
|
|
|
- apparmor:unconfined
|
|
|
|
|
volumes:
|
|
|
|
|
- netdata_config:/etc/netdata
|
|
|
|
|
- netdata_lib:/var/lib/netdata
|
|
|
|
|
- netdata_cache:/var/cache/netdata
|
|
|
|
|
- ./go.d/postgres.conf:/etc/netdata/go.d/postgres.conf:ro
|
|
|
|
|
- ./go.d/filecheck.conf:/etc/netdata/go.d/filecheck.conf:ro
|
|
|
|
|
- ./health_alarm_notify.conf:/etc/netdata/health_alarm_notify.conf:ro
|
|
|
|
|
- ./msmtprc:/etc/netdata/msmtprc:ro
|
|
|
|
|
- /mnt/hidrive/users/valknar/Backup:/mnt/hidrive/users/valknar/Backup:ro
|
|
|
|
|
- /etc/passwd:/host/etc/passwd:ro
|
|
|
|
|
- /etc/group:/host/etc/group:ro
|
|
|
|
|
- /etc/localtime:/etc/localtime:ro
|
|
|
|
|
- /proc:/host/proc:ro
|
|
|
|
|
- /sys:/host/sys:ro
|
|
|
|
|
- /etc/os-release:/host/etc/os-release:ro
|
|
|
|
|
- /var/log:/host/var/log:ro
|
|
|
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
|
|
|
environment:
|
|
|
|
|
- NETDATA_CLAIM_TOKEN=${NETDATA_CLAIM_TOKEN:-}
|
|
|
|
|
- NETDATA_CLAIM_URL=${NETDATA_CLAIM_URL:-}
|
|
|
|
|
- NETDATA_CLAIM_ROOMS=${NETDATA_CLAIM_ROOMS:-}
|
|
|
|
|
- MATTERMOST_WEBHOOK_URL=${MATTERMOST_WEBHOOK_URL:-}
|
|
|
|
|
networks:
|
|
|
|
|
- compose_network
|
|
|
|
|
labels:
|
|
|
|
|
- 'traefik.enable=${NET_TRAEFIK_ENABLED}'
|
|
|
|
|
# HTTP to HTTPS redirect
|
|
|
|
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-netdata-redirect-web-secure.redirectscheme.scheme=https'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-netdata-web.middlewares=${NET_COMPOSE_PROJECT_NAME}-netdata-redirect-web-secure'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-netdata-web.rule=Host(`${NET_NETDATA_TRAEFIK_HOST}`)'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-netdata-web.entrypoints=web'
|
|
|
|
|
# HTTPS router
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-netdata-web-secure.rule=Host(`${NET_NETDATA_TRAEFIK_HOST}`)'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-netdata-web-secure.tls.certresolver=resolver'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-netdata-web-secure.entrypoints=web-secure'
|
|
|
|
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-netdata-compress.compress=true'
|
|
|
|
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-netdata-auth.basicauth.users=${AUTH_USERS}'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-netdata-web-secure.middlewares=${NET_COMPOSE_PROJECT_NAME}-netdata-auth,${NET_COMPOSE_PROJECT_NAME}-netdata-compress,security-headers@file'
|
|
|
|
|
# Service
|
|
|
|
|
- 'traefik.http.services.${NET_COMPOSE_PROJECT_NAME}-netdata.loadbalancer.server.port=19999'
|
|
|
|
|
- 'traefik.docker.network=${NETWORK_NAME}'
|
|
|
|
|
# Watchtower
|
|
|
|
|
- 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}'
|
|
|
|
|
|
|
|
|
|
# Watchtower - Automatic container updates
|
|
|
|
|
watchtower:
|
|
|
|
|
image: containrrr/watchtower:latest
|
|
|
|
|
container_name: ${NET_COMPOSE_PROJECT_NAME}_watchtower
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
volumes:
|
|
|
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
|
|
|
environment:
|
|
|
|
|
# Check for updates every 5 minutes (300 seconds)
|
|
|
|
|
WATCHTOWER_POLL_INTERVAL: ${WATCHTOWER_POLL_INTERVAL:-300}
|
|
|
|
|
# Only update containers with the watchtower label
|
|
|
|
|
WATCHTOWER_LABEL_ENABLE: ${WATCHTOWER_LABEL_ENABLE:-true}
|
|
|
|
|
# Clean up old images after update
|
|
|
|
|
WATCHTOWER_CLEANUP: ${WATCHTOWER_CLEANUP:-true}
|
|
|
|
|
# Include stopped containers
|
|
|
|
|
WATCHTOWER_INCLUDE_STOPPED: ${WATCHTOWER_INCLUDE_STOPPED:-false}
|
|
|
|
|
# Include restarting containers
|
|
|
|
|
WATCHTOWER_INCLUDE_RESTARTING: ${WATCHTOWER_INCLUDE_RESTARTING:-true}
|
|
|
|
|
# Run once and exit (set to false for continuous monitoring)
|
|
|
|
|
WATCHTOWER_RUN_ONCE: ${WATCHTOWER_RUN_ONCE:-false}
|
|
|
|
|
# Notifications via Shoutrrr
|
|
|
|
|
WATCHTOWER_NOTIFICATIONS: ${WATCHTOWER_NOTIFICATIONS:-}
|
|
|
|
|
WATCHTOWER_NOTIFICATION_URL: ${WATCHTOWER_NOTIFICATION_URL:-}
|
|
|
|
|
# Log level (trace, debug, info, warn, error, fatal, panic)
|
|
|
|
|
WATCHTOWER_LOG_LEVEL: ${WATCHTOWER_LOG_LEVEL:-info}
|
|
|
|
|
# Rolling restart (update one container at a time)
|
|
|
|
|
WATCHTOWER_ROLLING_RESTART: ${WATCHTOWER_ROLLING_RESTART:-false}
|
|
|
|
|
labels:
|
|
|
|
|
# Allow watchtower to update itself
|
|
|
|
|
- com.centurylinklabs.watchtower.enable=true
|
|
|
|
|
|
|
|
|
|
# Umami - Web analytics
|
|
|
|
|
umami:
|
|
|
|
|
image: ${NET_TRACK_DOCKER_IMAGE}
|
|
|
|
|
container_name: ${NET_COMPOSE_PROJECT_NAME}_umami
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
environment:
|
|
|
|
|
TZ: ${TIMEZONE:-Europe/Amsterdam}
|
|
|
|
|
|
|
|
|
|
# Database Configuration
|
|
|
|
|
DATABASE_URL: postgresql://${DB_USER}:${DB_PASSWORD}@${CORE_DB_HOST}:${CORE_DB_PORT}/${NET_TRACK_DB_NAME}
|
|
|
|
|
DATABASE_TYPE: postgresql
|
|
|
|
|
|
|
|
|
|
# Application Secret
|
|
|
|
|
APP_SECRET: ${TRACK_APP_SECRET}
|
|
|
|
|
|
|
|
|
|
# Redis Cache Integration
|
|
|
|
|
REDIS_URL: redis://${CORE_REDIS_HOST}:${CORE_REDIS_PORT}
|
|
|
|
|
CACHE_ENABLED: true
|
|
|
|
|
|
|
|
|
|
networks:
|
|
|
|
|
- compose_network
|
|
|
|
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat || exit 1"]
|
|
|
|
|
interval: 30s
|
|
|
|
|
timeout: 10s
|
|
|
|
|
retries: 5
|
|
|
|
|
start_period: 40s
|
|
|
|
|
|
|
|
|
|
labels:
|
|
|
|
|
# Traefik Configuration
|
|
|
|
|
- 'traefik.enable=${NET_TRAEFIK_ENABLED}'
|
|
|
|
|
|
|
|
|
|
# HTTP to HTTPS redirect
|
|
|
|
|
- 'traefik.http.middlewares.${NET_COMPOSE_PROJECT_NAME}-umami-redirect-web-secure.redirectscheme.scheme=https'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-umami-web.middlewares=${NET_COMPOSE_PROJECT_NAME}-umami-redirect-web-secure'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-umami-web.rule=Host(`${NET_TRACK_TRAEFIK_HOST}`)'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-umami-web.entrypoints=web'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-umami-web-secure.rule=Host(`${NET_TRACK_TRAEFIK_HOST}`)'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-umami-web-secure.tls.certresolver=resolver'
|
|
|
|
|
- 'traefik.http.routers.${NET_COMPOSE_PROJECT_NAME}-umami-web-secure.entrypoints=web-secure'
|
|
|
|
|
- 'traefik.http.services.${NET_COMPOSE_PROJECT_NAME}-umami-web-secure.loadbalancer.server.port=3000'
|
|
|
|
|
- 'traefik.docker.network=${NETWORK_NAME}'
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
letsencrypt_data:
|
|
|
|
|
name: ${NET_COMPOSE_PROJECT_NAME}_letsencrypt_data
|
|
|
|
|
netdata_config:
|
|
|
|
|
name: ${NET_COMPOSE_PROJECT_NAME}_netdata_config
|
|
|
|
|
netdata_lib:
|
|
|
|
|
name: ${NET_COMPOSE_PROJECT_NAME}_netdata_lib
|
|
|
|
|
netdata_cache:
|
|
|
|
|
name: ${NET_COMPOSE_PROJECT_NAME}_netdata_cache
|
|
|
|
|
|
|
|
|
|
networks:
|
|
|
|
|
compose_network:
|
|
|
|
|
name: ${NETWORK_NAME}
|
|
|
|
|
external: true
|
2025-11-15 17:28:32 +01:00
|
|
|
coolify:
|
|
|
|
|
name: coolify
|
|
|
|
|
external: true
|