409 lines
11 KiB
YAML
409 lines
11 KiB
YAML
version: '3.8'
|
|
|
|
networks:
|
|
traefik-public:
|
|
external: true
|
|
homelab-backend:
|
|
driver: overlay
|
|
|
|
volumes:
|
|
paperless_data:
|
|
paperless_media:
|
|
paperless_db:
|
|
paperless_redis:
|
|
openwebui_data:
|
|
stirling_pdf_data:
|
|
searxng_data:
|
|
n8n_data:
|
|
|
|
secrets:
|
|
paperless_db_password:
|
|
external: true
|
|
paperless_secret_key:
|
|
external: true
|
|
|
|
services:
|
|
n8n:
|
|
image: n8nio/n8n:latest
|
|
volumes:
|
|
- n8n_data:/home/node/.n8n
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
networks:
|
|
- traefik-public
|
|
environment:
|
|
- N8N_HOST=n8n.sj98.duckdns.org
|
|
- N8N_PROTOCOL=https
|
|
- NODE_ENV=production
|
|
- WEBHOOK_URL=https://n8n.sj98.duckdns.org/
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -q --spider http://localhost:5678/healthz || exit 1"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.role == manager
|
|
resources:
|
|
limits:
|
|
memory: 1G
|
|
cpus: '0.5'
|
|
reservations:
|
|
memory: 256M
|
|
cpus: '0.1'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.n8n.rule=Host(`n8n.sj98.duckdns.org`)"
|
|
- "traefik.http.routers.n8n.entrypoints=websecure"
|
|
- "traefik.http.routers.n8n.tls.certresolver=leresolver"
|
|
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
|
|
- "traefik.docker.network=traefik-public"
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
openwebui:
|
|
image: ghcr.io/open-webui/open-webui:0.3.32
|
|
volumes:
|
|
- openwebui_data:/app/backend/data
|
|
networks:
|
|
- traefik-public
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 60s
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.labels.heavy == true
|
|
resources:
|
|
limits:
|
|
memory: 4G
|
|
cpus: '4.0'
|
|
reservations:
|
|
memory: 2G
|
|
cpus: '1.0'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
update_config:
|
|
parallelism: 1
|
|
delay: 10s
|
|
failure_action: rollback
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.openwebui.rule=Host(`ai.sj98.duckdns.org`)"
|
|
- "traefik.http.routers.openwebui.entrypoints=websecure"
|
|
- "traefik.http.routers.openwebui.tls.certresolver=leresolver"
|
|
- "traefik.http.services.openwebui.loadbalancer.server.port=8080"
|
|
- "traefik.docker.network=traefik-public"
|
|
- "tsdproxy.enable=true"
|
|
- "tsdproxy.name=openwebui"
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
paperless-redis:
|
|
image: redis:7-alpine
|
|
volumes:
|
|
- paperless_redis:/data
|
|
networks:
|
|
- homelab-backend
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 30s
|
|
timeout: 3s
|
|
retries: 3
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.labels.leader == true
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
cpus: '0.5'
|
|
reservations:
|
|
memory: 64M
|
|
cpus: '0.1'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
paperless-db:
|
|
image: postgres:15-alpine
|
|
volumes:
|
|
- paperless_db:/var/lib/postgresql/data
|
|
networks:
|
|
- homelab-backend
|
|
environment:
|
|
- POSTGRES_DB=paperless
|
|
- POSTGRES_USER=paperless
|
|
- POSTGRES_PASSWORD_FILE=/run/secrets/paperless_db_password
|
|
secrets:
|
|
- paperless_db_password
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U paperless"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.labels.leader == true
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
cpus: '1.0'
|
|
reservations:
|
|
memory: 256M
|
|
cpus: '0.25'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
paperless:
|
|
image: ghcr.io/paperless-ngx/paperless-ngx:2.19.3
|
|
volumes:
|
|
- paperless_data:/usr/src/paperless/data
|
|
- paperless_media:/usr/src/paperless/media
|
|
environment:
|
|
- PAPERLESS_REDIS=redis://paperless-redis:6379
|
|
- PAPERLESS_DBHOST=paperless-db
|
|
- PAPERLESS_DBNAME=paperless
|
|
- PAPERLESS_DBUSER=paperless
|
|
- PAPERLESS_DBPASS_FILE=/run/secrets/paperless_db_password
|
|
- PAPERLESS_URL=https://paperless.sj98.duckdns.org
|
|
- PAPERLESS_SECRET_KEY_FILE=/run/secrets/paperless_secret_key
|
|
- TZ=America/Chicago
|
|
secrets:
|
|
- paperless_db_password
|
|
- paperless_secret_key
|
|
depends_on:
|
|
- paperless-redis
|
|
- paperless-db
|
|
networks:
|
|
- traefik-public
|
|
- homelab-backend
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/api/"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 90s
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.labels.leader == true
|
|
resources:
|
|
limits:
|
|
memory: 1536M
|
|
cpus: '2.0'
|
|
reservations:
|
|
memory: 768M
|
|
cpus: '0.5'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 10s
|
|
max_attempts: 3
|
|
update_config:
|
|
parallelism: 1
|
|
delay: 10s
|
|
failure_action: rollback
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.paperless.rule=Host(`paperless.sj98.duckdns.org`)"
|
|
- "traefik.http.routers.paperless.entrypoints=websecure"
|
|
- "traefik.http.routers.paperless.tls.certresolver=leresolver"
|
|
- "traefik.http.services.paperless.loadbalancer.server.port=8000"
|
|
- "traefik.docker.network=traefik-public"
|
|
- "tsdproxy.enable=true"
|
|
- "tsdproxy.name=paperless"
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
stirling-pdf:
|
|
image: frooodle/s-pdf:0.18.1
|
|
volumes:
|
|
- stirling_pdf_data:/configs
|
|
environment:
|
|
- DOCKER_ENABLE_SECURITY=false
|
|
- INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
|
|
- LANGS=en_US
|
|
networks:
|
|
- traefik-public
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 30s
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.labels.leader == true
|
|
resources:
|
|
limits:
|
|
memory: 1536M
|
|
cpus: '2.0'
|
|
reservations:
|
|
memory: 768M
|
|
cpus: '0.5'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
update_config:
|
|
parallelism: 1
|
|
delay: 10s
|
|
failure_action: rollback
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.pdf.rule=Host(`pdf.sj98.duckdns.org`)"
|
|
- "traefik.http.routers.pdf.entrypoints=websecure"
|
|
- "traefik.http.routers.pdf.tls.certresolver=leresolver"
|
|
- "traefik.http.services.pdf.loadbalancer.server.port=8080"
|
|
- "traefik.docker.network=traefik-public"
|
|
- "tsdproxy.enable=true"
|
|
- "tsdproxy.name=pdf"
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
searxng:
|
|
image: searxng/searxng:2024.11.20-e9f6095cc
|
|
volumes:
|
|
- searxng_data:/etc/searxng
|
|
environment:
|
|
- SEARXNG_BASE_URL=https://search.sj98.duckdns.org/
|
|
networks:
|
|
- traefik-public
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/healthz"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 30s
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.labels.leader == true
|
|
resources:
|
|
limits:
|
|
memory: 1536M
|
|
cpus: '2.0'
|
|
reservations:
|
|
memory: 512M
|
|
cpus: '0.5'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
update_config:
|
|
parallelism: 1
|
|
delay: 10s
|
|
failure_action: rollback
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.searxng.rule=Host(`search.sj98.duckdns.org`)"
|
|
- "traefik.http.routers.searxng.entrypoints=websecure"
|
|
- "traefik.http.routers.searxng.tls.certresolver=leresolver"
|
|
- "traefik.http.services.searxng.loadbalancer.server.port=8080"
|
|
- "traefik.docker.network=traefik-public"
|
|
- "tsdproxy.enable=true"
|
|
- "tsdproxy.name=search"
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
watchtower:
|
|
image: containrrr/watchtower:1.7.1
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
environment:
|
|
- DOCKER_API_VERSION=1.44
|
|
command: --cleanup --interval 86400
|
|
deploy:
|
|
placement:
|
|
constraints:
|
|
- node.role == manager
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
cpus: '0.25'
|
|
reservations:
|
|
memory: 64M
|
|
cpus: '0.05'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
tsdproxy:
|
|
image: almeidapaulopt/tsdproxy:v0.5.1
|
|
networks:
|
|
- traefik-public
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- /srv/tsdproxy/config/tsdproxy.yaml:/config/tsdproxy.yaml:ro
|
|
- /srv/tsdproxy/data:/data
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
cpus: '0.25'
|
|
reservations:
|
|
memory: 64M
|
|
cpus: '0.05'
|
|
restart_policy:
|
|
condition: on-failure
|
|
delay: 5s
|
|
max_attempts: 3
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.tsdproxy.rule=Host(`tsdproxy.sj98.duckdns.org`)"
|
|
- "traefik.http.routers.tsdproxy.entrypoints=websecure"
|
|
- "traefik.http.routers.tsdproxy.tls.certresolver=leresolver"
|
|
- "traefik.http.services.tsdproxy.loadbalancer.server.port=8080"
|
|
- "traefik.docker.network=traefik-public"
|
|
- "tsdproxy.enable=true"
|
|
- "tsdproxy.name=tsdproxy"
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3" |