project-nomad/docker-compose.yml
copilot-swe-agent[bot] 935d0ab22b Add container stack, nginx config, NAS templates, and monitoring agent
Co-authored-by: DocwatZ <227472400+DocwatZ@users.noreply.github.com>
2026-03-13 17:32:28 +00:00

202 lines
6.5 KiB
YAML

# =============================================================================
# PROJECT N.O.M.A.D. — Homelab Edition
# Network Operations Monitoring and Automation Dashboard
# Docker Compose Stack for NAS and Homelab Environments
# =============================================================================
#
# Usage:
# 1. Copy .env.example to .env and configure
# 2. docker compose up -d
#
# Compatible with: Unraid, TrueNAS SCALE, standard Docker hosts
# =============================================================================
name: project-nomad
services:
# ---------------------------------------------------------------------------
# Nomad Application (Web UI + API)
# ---------------------------------------------------------------------------
nomad-app:
image: ghcr.io/crosstalk-solutions/project-nomad:latest
container_name: nomad-app
restart: unless-stopped
ports:
- "${PORT:-8080}:8080"
volumes:
- ${NOMAD_DATA_DIR:-./data}/storage:/app/storage
- /var/run/docker.sock:/var/run/docker.sock
- ./install/entrypoint.sh:/usr/local/bin/entrypoint.sh:ro
environment:
- NODE_ENV=${NODE_ENV:-production}
- PORT=8080
- HOST=0.0.0.0
- LOG_LEVEL=${LOG_LEVEL:-info}
- APP_KEY=${APP_KEY:?Set APP_KEY in .env}
- URL=${URL:-http://localhost:8080}
- DB_HOST=nomad-database
- DB_PORT=3306
- DB_DATABASE=${DB_DATABASE:-nomad}
- DB_USER=${DB_USER:-nomad}
- DB_PASSWORD=${DB_PASSWORD:?Set DB_PASSWORD in .env}
- DB_SSL=false
- REDIS_HOST=nomad-cache
- REDIS_PORT=6379
- NOMAD_STORAGE_PATH=/app/storage
- NOMAD_API_URL=${NOMAD_API_URL:-}
- INTERNET_STATUS_TEST_URL=${INTERNET_STATUS_TEST_URL:-}
entrypoint: ["/usr/local/bin/entrypoint.sh"]
depends_on:
nomad-database:
condition: service_healthy
nomad-cache:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
networks:
- nomad-internal
labels:
- "com.project-nomad.service=app"
- "com.project-nomad.description=Nomad Web Application"
# ---------------------------------------------------------------------------
# Nomad Worker (Background Job Processing)
# ---------------------------------------------------------------------------
nomad-worker:
image: ghcr.io/crosstalk-solutions/project-nomad:latest
container_name: nomad-worker
restart: unless-stopped
volumes:
- ${NOMAD_DATA_DIR:-./data}/storage:/app/storage
- /var/run/docker.sock:/var/run/docker.sock
environment:
- NODE_ENV=${NODE_ENV:-production}
- PORT=8081
- HOST=0.0.0.0
- LOG_LEVEL=${LOG_LEVEL:-info}
- APP_KEY=${APP_KEY}
- URL=${URL:-http://localhost:8080}
- DB_HOST=nomad-database
- DB_PORT=3306
- DB_DATABASE=${DB_DATABASE:-nomad}
- DB_USER=${DB_USER:-nomad}
- DB_PASSWORD=${DB_PASSWORD}
- DB_SSL=false
- REDIS_HOST=nomad-cache
- REDIS_PORT=6379
- NOMAD_STORAGE_PATH=/app/storage
command: ["node", "ace", "queue:work", "--all"]
depends_on:
nomad-database:
condition: service_healthy
nomad-cache:
condition: service_healthy
networks:
- nomad-internal
deploy:
resources:
limits:
memory: 2G
labels:
- "com.project-nomad.service=worker"
- "com.project-nomad.description=Nomad Background Worker"
# ---------------------------------------------------------------------------
# Database (MySQL 8.0)
# ---------------------------------------------------------------------------
nomad-database:
image: mysql:8.0
container_name: nomad-database
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:?Set MYSQL_ROOT_PASSWORD in .env}
- MYSQL_DATABASE=${DB_DATABASE:-nomad}
- MYSQL_USER=${DB_USER:-nomad}
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes:
- nomad-db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 15s
timeout: 5s
retries: 5
start_period: 30s
networks:
- nomad-internal
deploy:
resources:
limits:
memory: 1G
labels:
- "com.project-nomad.service=database"
- "com.project-nomad.description=Nomad MySQL Database"
# ---------------------------------------------------------------------------
# Cache / Queue (Redis 7)
# ---------------------------------------------------------------------------
nomad-cache:
image: redis:7-alpine
container_name: nomad-cache
restart: unless-stopped
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- ${NOMAD_DATA_DIR:-./data}/redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 15s
timeout: 5s
retries: 5
networks:
- nomad-internal
deploy:
resources:
limits:
memory: 512M
labels:
- "com.project-nomad.service=cache"
- "com.project-nomad.description=Nomad Redis Cache"
# ---------------------------------------------------------------------------
# Nginx Reverse Proxy
# ---------------------------------------------------------------------------
nomad-nginx:
image: nginx:alpine
container_name: nomad-nginx
restart: unless-stopped
ports:
- "${NGINX_HTTP_PORT:-80}:80"
- "${NGINX_HTTPS_PORT:-443}:443"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ${NOMAD_DATA_DIR:-./data}/logs/nginx:/var/log/nginx
depends_on:
nomad-app:
condition: service_healthy
networks:
- nomad-internal
labels:
- "com.project-nomad.service=nginx"
- "com.project-nomad.description=Nomad Reverse Proxy"
# =============================================================================
# Networks
# =============================================================================
networks:
nomad-internal:
driver: bridge
name: nomad-internal
# =============================================================================
# Volumes
# =============================================================================
# Database uses a named Docker volume for optimal I/O performance.
# This avoids NFS/SMB latency issues common on NAS systems.
# All other data uses bind mounts configured via NOMAD_DATA_DIR.
volumes:
nomad-db-data:
driver: local