Absorbs the separate control-panel git repo as a subdirectory. Instances and backups directories excluded via .gitignore. Bunker Admin
659 lines
21 KiB
Handlebars
659 lines
21 KiB
Handlebars
# Changemaker Lite — Instance: {{name}}
|
|
# Compose project: {{composeProject}}
|
|
# Generated by CCP
|
|
|
|
services:
|
|
# ─── Core Infrastructure ───────────────────────────────────
|
|
|
|
v2-postgres:
|
|
image: postgres:16-alpine
|
|
container_name: {{containerPrefix}}-postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: changemaker
|
|
POSTGRES_PASSWORD: {{secrets.postgresPassword}}
|
|
POSTGRES_DB: changemaker_v2
|
|
volumes:
|
|
- {{containerPrefix}}-postgres-data:/var/lib/postgresql/data
|
|
- ./api/prisma/init-nocodb-db.sh:/docker-entrypoint-initdb.d/10-init-nocodb.sh:ro
|
|
- ./api/prisma/init-gancio-db.sh:/docker-entrypoint-initdb.d/20-init-gancio.sh:ro
|
|
ports:
|
|
- "127.0.0.1:{{ports.postgres}}:5432"
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U changemaker -d changemaker_v2"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: {{containerPrefix}}-redis
|
|
restart: unless-stopped
|
|
command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy noeviction --requirepass {{secrets.redisPassword}}
|
|
volumes:
|
|
- {{containerPrefix}}-redis-data:/data
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "-a", "{{secrets.redisPassword}}", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '1'
|
|
memory: 512M
|
|
reservations:
|
|
cpus: '0.25'
|
|
memory: 256M
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "5m"
|
|
max-file: "2"
|
|
|
|
# ─── Application Services ──────────────────────────────────
|
|
|
|
api:
|
|
build:
|
|
context: ./api
|
|
dockerfile: Dockerfile
|
|
target: development
|
|
container_name: {{containerPrefix}}-api
|
|
restart: unless-stopped
|
|
depends_on:
|
|
v2-postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
env_file: .env
|
|
environment:
|
|
DATABASE_URL: postgresql://changemaker:{{secrets.postgresPassword}}@{{containerPrefix}}-postgres:5432/changemaker_v2
|
|
REDIS_URL: redis://:{{secrets.redisPassword}}@{{containerPrefix}}-redis:6379
|
|
PORT: "4000"
|
|
NAR_DATA_DIR: /data
|
|
LISTMONK_URL: http://{{containerPrefix}}-listmonk:9000
|
|
ADMIN_URL: https://app.{{domain}}
|
|
API_URL: https://api.{{domain}}
|
|
{{#if enableGancio}}
|
|
GANCIO_URL: http://{{containerPrefix}}-gancio:13120
|
|
{{/if}}
|
|
ports:
|
|
- "{{ports.api}}:4000"
|
|
volumes:
|
|
- ./api:/app
|
|
- /app/node_modules
|
|
- ./assets/uploads:/app/uploads
|
|
- ./mkdocs:/mkdocs:rw
|
|
- ./data:/data:ro
|
|
- ./configs:/app/configs:ro
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://localhost:4000/api/health"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '2'
|
|
memory: 1G
|
|
reservations:
|
|
cpus: '0.25'
|
|
memory: 256M
|
|
|
|
admin:
|
|
build:
|
|
context: ./admin
|
|
target: development
|
|
container_name: {{containerPrefix}}-admin
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- api
|
|
environment:
|
|
DOMAIN: {{domain}}
|
|
NODE_ENV: production
|
|
VITE_API_URL: http://{{containerPrefix}}-api:4000
|
|
VITE_MKDOCS_URL: http://{{containerPrefix}}-mkdocs:8000
|
|
{{#if enableMedia}}
|
|
VITE_MEDIA_API_URL: http://{{containerPrefix}}-media-api:4100
|
|
{{/if}}
|
|
volumes:
|
|
- ./admin:/app
|
|
- /app/node_modules
|
|
ports:
|
|
- "{{ports.admin}}:3000"
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000/"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 20s
|
|
|
|
{{#if enableMedia}}
|
|
media-api:
|
|
build:
|
|
context: ./api
|
|
dockerfile: Dockerfile.media
|
|
target: development
|
|
container_name: {{containerPrefix}}-media-api
|
|
restart: unless-stopped
|
|
depends_on:
|
|
v2-postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
env_file: .env
|
|
environment:
|
|
DATABASE_URL: postgresql://changemaker:{{secrets.postgresPassword}}@{{containerPrefix}}-postgres:5432/changemaker_v2
|
|
REDIS_URL: redis://:{{secrets.redisPassword}}@{{containerPrefix}}-redis:6379
|
|
MEDIA_API_PORT: "4100"
|
|
CORS_ORIGINS: https://app.{{domain}},http://localhost:{{ports.admin}}
|
|
ENABLE_MEDIA_FEATURES: "true"
|
|
MEDIA_ROOT: /media/local
|
|
MEDIA_UPLOADS: /media/uploads
|
|
volumes:
|
|
- ./api:/app
|
|
- /app/node_modules
|
|
- ./media:/media:ro
|
|
- ./media/local/inbox:/media/local/inbox:rw
|
|
- ./media/local/thumbnails:/media/local/thumbnails:rw
|
|
- ./media/local/photos:/media/local/photos:rw
|
|
- ./media/public:/media/public:rw
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:4100/health"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '2'
|
|
memory: 1G
|
|
reservations:
|
|
cpus: '0.25'
|
|
memory: 256M
|
|
{{/if}}
|
|
|
|
# ─── Reverse Proxy ─────────────────────────────────────────
|
|
|
|
nginx:
|
|
image: nginx:alpine
|
|
container_name: {{containerPrefix}}-nginx
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- api
|
|
- admin
|
|
volumes:
|
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
|
ports:
|
|
- "{{ports.nginx}}:80"
|
|
- "{{math ports.embed "+" 0}}:8881" # NocoDB embed proxy
|
|
- "{{math ports.embed "+" 1}}:8882" # n8n embed proxy
|
|
- "{{math ports.embed "+" 2}}:8883" # Gitea embed proxy
|
|
- "{{math ports.embed "+" 3}}:8884" # MailHog embed proxy
|
|
- "{{math ports.embed "+" 4}}:8885" # Mini QR embed proxy
|
|
- "{{math ports.embed "+" 5}}:8886" # Excalidraw embed proxy
|
|
- "{{math ports.embed "+" 6}}:8887" # Homepage embed proxy
|
|
- "{{math ports.embed "+" 7}}:8888" # Code Server embed proxy
|
|
- "{{math ports.embed "+" 8}}:8889" # MkDocs embed proxy
|
|
- "{{math ports.embed "+" 9}}:8890" # Vaultwarden embed proxy
|
|
- "{{math ports.embed "+" 10}}:8891" # Rocket.Chat embed proxy
|
|
- "{{math ports.embed "+" 11}}:8892" # Gancio embed proxy
|
|
- "{{math ports.embed "+" 12}}:8893" # Grafana embed proxy
|
|
- "{{math ports.embed "+" 13}}:8894" # Listmonk embed proxy
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:80/"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
# ─── Supporting Services ───────────────────────────────────
|
|
|
|
nocodb-v2:
|
|
image: nocodb/nocodb:latest
|
|
container_name: {{containerPrefix}}-nocodb
|
|
restart: unless-stopped
|
|
depends_on:
|
|
v2-postgres:
|
|
condition: service_healthy
|
|
environment:
|
|
NC_DB: pg://{{containerPrefix}}-postgres:5432?u=changemaker&p={{secrets.postgresPassword}}&d=nocodb_meta
|
|
NC_ADMIN_EMAIL: {{secrets.adminEmail}}
|
|
NC_ADMIN_PASSWORD: {{secrets.nocodbAdminPassword}}
|
|
volumes:
|
|
- {{containerPrefix}}-nocodb-data:/usr/app/data
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
mailhog:
|
|
image: mailhog/mailhog:latest
|
|
container_name: {{containerPrefix}}-mailhog
|
|
restart: unless-stopped
|
|
networks:
|
|
- {{networkName}}
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "5m"
|
|
max-file: "2"
|
|
|
|
mkdocs:
|
|
image: squidfunk/mkdocs-material:latest
|
|
container_name: {{containerPrefix}}-mkdocs
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./mkdocs:/docs:rw
|
|
- ./assets/images:/docs/assets/images:rw
|
|
user: "1000:1000"
|
|
environment:
|
|
SITE_URL: https://{{domain}}
|
|
ADMIN_PORT: "{{ports.admin}}"
|
|
ADMIN_URL: https://app.{{domain}}
|
|
BASE_DOMAIN: https://{{domain}}
|
|
API_URL: https://api.{{domain}}
|
|
API_PORT: "{{ports.api}}"
|
|
{{#if enableMedia}}
|
|
MEDIA_API_PUBLIC_URL: https://media.{{domain}}
|
|
MEDIA_API_PORT: "4100"
|
|
{{/if}}
|
|
{{#if enableGancio}}
|
|
GANCIO_URL: http://{{containerPrefix}}-gancio:13120
|
|
GANCIO_PORT: "8092"
|
|
{{/if}}
|
|
command: serve --dev-addr=0.0.0.0:8000 --watch-theme --livereload
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
{{#if enableListmonk}}
|
|
listmonk-db:
|
|
image: postgres:17-alpine
|
|
container_name: {{containerPrefix}}-listmonk-db
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: listmonk
|
|
POSTGRES_PASSWORD: {{secrets.listmonkAdminPassword}}
|
|
POSTGRES_DB: listmonk
|
|
volumes:
|
|
- {{containerPrefix}}-listmonk-data:/var/lib/postgresql/data
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U listmonk"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 6
|
|
|
|
listmonk-app:
|
|
image: listmonk/listmonk:latest
|
|
container_name: {{containerPrefix}}-listmonk
|
|
restart: unless-stopped
|
|
depends_on:
|
|
listmonk-db:
|
|
condition: service_healthy
|
|
command: [sh, -c, "./listmonk --install --idempotent --yes --config '' && ./listmonk --upgrade --yes --config '' && ./listmonk --config ''"]
|
|
environment:
|
|
LISTMONK_app__address: "0.0.0.0:9000"
|
|
LISTMONK_db__host: {{containerPrefix}}-listmonk-db
|
|
LISTMONK_db__port: "5432"
|
|
LISTMONK_db__user: listmonk
|
|
LISTMONK_db__password: {{secrets.listmonkAdminPassword}}
|
|
LISTMONK_db__database: listmonk
|
|
LISTMONK_db__ssl_mode: disable
|
|
TZ: Etc/UTC
|
|
LISTMONK_ADMIN_USER: admin
|
|
LISTMONK_ADMIN_PASSWORD: {{secrets.listmonkAdminPassword}}
|
|
volumes:
|
|
- ./assets/uploads:/listmonk/uploads:rw
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://localhost:9000/"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
listmonk-init:
|
|
image: postgres:17-alpine
|
|
container_name: {{containerPrefix}}-listmonk-init
|
|
depends_on:
|
|
listmonk-app:
|
|
condition: service_started
|
|
restart: "no"
|
|
environment:
|
|
PGPASSWORD: {{secrets.listmonkAdminPassword}}
|
|
LISTMONK_API_USER: v2-api
|
|
LISTMONK_API_TOKEN: {{secrets.listmonkApiToken}}
|
|
LISTMONK_SMTP_HOST: {{containerPrefix}}-mailhog
|
|
LISTMONK_SMTP_PORT: "1025"
|
|
entrypoint: ["/bin/sh", "-c"]
|
|
command:
|
|
- |
|
|
echo "[listmonk-init] Waiting for Listmonk tables..."
|
|
for i in $$(seq 1 30); do
|
|
if psql -h {{containerPrefix}}-listmonk-db -U listmonk -d listmonk -c "SELECT 1 FROM users LIMIT 1" >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
if [ -n "$$LISTMONK_API_TOKEN" ]; then
|
|
echo "[listmonk-init] Upserting API user '$$LISTMONK_API_USER'..."
|
|
psql -h {{containerPrefix}}-listmonk-db -U listmonk -d listmonk -q <<SQL
|
|
INSERT INTO users (username, password, password_login, email, name, type, user_role_id, status)
|
|
VALUES ('$$LISTMONK_API_USER', '$$LISTMONK_API_TOKEN', true, '$$LISTMONK_API_USER@api.internal', '$$LISTMONK_API_USER', 'api', 1, 'enabled')
|
|
ON CONFLICT (username) DO UPDATE SET password = EXCLUDED.password, status = 'enabled', user_role_id = 1;
|
|
SQL
|
|
echo "[listmonk-init] API user configured"
|
|
else
|
|
echo "[listmonk-init] LISTMONK_API_TOKEN not set, skipping API user"
|
|
fi
|
|
|
|
MAILHOG_ENTRY='{"host":"{{containerPrefix}}-mailhog","port":1025,"username":"","password":"","tls_type":"none","auth_protocol":"none","enabled":true,"max_conns":5,"idle_timeout":"15s","wait_timeout":"5s","max_msg_retries":2,"tls_skip_verify":false,"email_headers":[],"hello_hostname":""}'
|
|
SMTP_VALUE="[$$MAILHOG_ENTRY]"
|
|
psql -h {{containerPrefix}}-listmonk-db -U listmonk -d listmonk -q <<SQL
|
|
UPDATE settings SET value = '$$SMTP_VALUE' WHERE key = 'smtp';
|
|
SQL
|
|
echo "[listmonk-init] SMTP configured"
|
|
echo "[listmonk-init] Done"
|
|
networks:
|
|
- {{networkName}}
|
|
{{/if}}
|
|
|
|
{{#if enableGancio}}
|
|
gancio:
|
|
image: cisti/gancio:latest
|
|
container_name: {{containerPrefix}}-gancio
|
|
restart: unless-stopped
|
|
depends_on:
|
|
v2-postgres:
|
|
condition: service_healthy
|
|
environment:
|
|
GANCIO_DATA: /home/node/data
|
|
NODE_ENV: production
|
|
GANCIO_DB_DIALECT: postgres
|
|
GANCIO_DB_HOST: {{containerPrefix}}-postgres
|
|
GANCIO_DB_PORT: "5432"
|
|
GANCIO_DB_DATABASE: gancio
|
|
GANCIO_DB_USERNAME: changemaker
|
|
GANCIO_DB_PASSWORD: {{secrets.postgresPassword}}
|
|
server__baseurl: https://events.{{domain}}
|
|
volumes:
|
|
- {{containerPrefix}}-gancio-data:/home/node/data
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "node", "-e", "require('http').get('http://localhost:13120/', r => process.exit(r.statusCode < 400 ? 0 : 1)).on('error', () => process.exit(1))"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 5
|
|
start_period: 60s
|
|
{{/if}}
|
|
|
|
{{#if enableChat}}
|
|
nats-rocketchat:
|
|
image: nats:2.11-alpine
|
|
container_name: {{containerPrefix}}-nats
|
|
restart: unless-stopped
|
|
command: --http_port 8222
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
mongodb-rocketchat:
|
|
image: mongo:6.0
|
|
container_name: {{containerPrefix}}-mongodb
|
|
restart: unless-stopped
|
|
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
|
|
volumes:
|
|
- {{containerPrefix}}-mongodb-data:/data/db
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "mongosh", "--quiet", "--eval", "try { rs.status().ok } catch(e) { rs.initiate({_id:'rs0',members:[{_id:0,host:'{{containerPrefix}}-mongodb:27017'}]}).ok }"]
|
|
interval: 10s
|
|
timeout: 10s
|
|
retries: 10
|
|
start_period: 30s
|
|
|
|
rocketchat:
|
|
image: rocketchat/rocket.chat:7.9.7
|
|
container_name: {{containerPrefix}}-rocketchat
|
|
restart: unless-stopped
|
|
depends_on:
|
|
mongodb-rocketchat:
|
|
condition: service_healthy
|
|
nats-rocketchat:
|
|
condition: service_started
|
|
environment:
|
|
ROOT_URL: http://chat.{{domain}}
|
|
MONGO_URL: mongodb://{{containerPrefix}}-mongodb:27017/rocketchat?replicaSet=rs0
|
|
MONGO_OPLOG_URL: mongodb://{{containerPrefix}}-mongodb:27017/local?replicaSet=rs0
|
|
TRANSPORTER: monolith+nats://{{containerPrefix}}-nats:4222
|
|
PORT: "3000"
|
|
ADMIN_USERNAME: rcadmin
|
|
ADMIN_NAME: Admin
|
|
ADMIN_EMAIL: {{secrets.adminEmail}}
|
|
ADMIN_PASS: {{secrets.nocodbAdminPassword}}
|
|
CREATE_TOKENS_FOR_USERS: "true"
|
|
OVERWRITE_SETTING_Iframe_Integration_send_enable: "true"
|
|
OVERWRITE_SETTING_Iframe_Integration_receive_enable: "true"
|
|
OVERWRITE_SETTING_Iframe_Integration_receive_origin: http://app.{{domain}},https://app.{{domain}}
|
|
volumes:
|
|
- {{containerPrefix}}-rocketchat-uploads:/app/uploads
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000/api/info"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 10
|
|
start_period: 90s
|
|
{{/if}}
|
|
|
|
# ─── Pangolin Tunnel ───────────────────────────────────────
|
|
|
|
newt:
|
|
image: fosrl/newt:latest
|
|
container_name: {{containerPrefix}}-newt
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- nginx
|
|
environment:
|
|
PANGOLIN_ENDPOINT: ${PANGOLIN_ENDPOINT}
|
|
NEWT_ID: ${PANGOLIN_NEWT_ID}
|
|
NEWT_SECRET: ${PANGOLIN_NEWT_SECRET}
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
# ─── Always-On Utilities ──────────────────────────────────
|
|
|
|
mini-qr:
|
|
image: ghcr.io/lyqht/mini-qr:latest
|
|
container_name: {{containerPrefix}}-mini-qr
|
|
restart: unless-stopped
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
mkdocs-site-server:
|
|
image: nginx:alpine
|
|
container_name: {{containerPrefix}}-mkdocs-site
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./mkdocs/site:/usr/share/nginx/html:ro
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
{{#if enableDevTools}}
|
|
# ─── Dev Tools ────────────────────────────────────────────
|
|
|
|
code-server:
|
|
image: lscr.io/linuxserver/code-server:latest
|
|
container_name: {{containerPrefix}}-code-server
|
|
restart: unless-stopped
|
|
environment:
|
|
PASSWORD: {{secrets.nocodbAdminPassword}}
|
|
SUDO_PASSWORD: {{secrets.nocodbAdminPassword}}
|
|
volumes:
|
|
- .:/config/workspace:rw
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
gitea:
|
|
image: gitea/gitea:latest
|
|
container_name: {{containerPrefix}}-gitea
|
|
restart: unless-stopped
|
|
depends_on:
|
|
v2-postgres:
|
|
condition: service_healthy
|
|
environment:
|
|
GITEA__database__DB_TYPE: postgres
|
|
GITEA__database__HOST: {{containerPrefix}}-postgres:5432
|
|
GITEA__database__NAME: gitea
|
|
GITEA__database__USER: changemaker
|
|
GITEA__database__PASSWD: {{secrets.postgresPassword}}
|
|
GITEA__server__ROOT_URL: https://git.{{domain}}
|
|
GITEA__server__DOMAIN: git.{{domain}}
|
|
GITEA__security__INSTALL_LOCK: "true"
|
|
volumes:
|
|
- {{containerPrefix}}-gitea-data:/data
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-fsSL", "http://localhost:3000/api/healthz"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 5
|
|
start_period: 30s
|
|
|
|
n8n:
|
|
image: n8nio/n8n:latest
|
|
container_name: {{containerPrefix}}-n8n
|
|
restart: unless-stopped
|
|
environment:
|
|
N8N_ENCRYPTION_KEY: {{secrets.n8nEncryptionKey}}
|
|
WEBHOOK_URL: https://n8n.{{domain}}
|
|
N8N_HOST: n8n.{{domain}}
|
|
N8N_PROTOCOL: https
|
|
volumes:
|
|
- {{containerPrefix}}-n8n-data:/home/node/.n8n
|
|
networks:
|
|
- {{networkName}}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://localhost:5678/healthz"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
homepage:
|
|
image: ghcr.io/gethomepage/homepage:latest
|
|
container_name: {{containerPrefix}}-homepage
|
|
restart: unless-stopped
|
|
volumes:
|
|
- {{containerPrefix}}-homepage-data:/app/config
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
excalidraw:
|
|
image: excalidraw/excalidraw:latest
|
|
container_name: {{containerPrefix}}-excalidraw
|
|
restart: unless-stopped
|
|
networks:
|
|
- {{networkName}}
|
|
{{/if}}
|
|
|
|
{{#if enableMonitoring}}
|
|
# ─── Monitoring Stack ──────────────────────────────────────
|
|
|
|
prometheus:
|
|
image: prom/prometheus:latest
|
|
container_name: {{containerPrefix}}-prometheus
|
|
restart: unless-stopped
|
|
command:
|
|
- '--config.file=/etc/prometheus/prometheus.yml'
|
|
- '--storage.tsdb.path=/prometheus'
|
|
- '--storage.tsdb.retention.time=30d'
|
|
volumes:
|
|
- ./configs/prometheus:/etc/prometheus:ro
|
|
- {{containerPrefix}}-prometheus-data:/prometheus
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
grafana:
|
|
image: grafana/grafana:latest
|
|
container_name: {{containerPrefix}}-grafana
|
|
restart: unless-stopped
|
|
environment:
|
|
GF_SECURITY_ADMIN_PASSWORD: {{secrets.grafanaAdminPassword}}
|
|
GF_USERS_ALLOW_SIGN_UP: "false"
|
|
GF_SERVER_ROOT_URL: https://grafana.{{domain}}
|
|
GF_SECURITY_ALLOW_EMBEDDING: "true"
|
|
volumes:
|
|
- {{containerPrefix}}-grafana-data:/var/lib/grafana
|
|
- ./configs/grafana:/etc/grafana/provisioning
|
|
depends_on:
|
|
- prometheus
|
|
networks:
|
|
- {{networkName}}
|
|
|
|
alertmanager:
|
|
image: prom/alertmanager:latest
|
|
container_name: {{containerPrefix}}-alertmanager
|
|
restart: unless-stopped
|
|
command:
|
|
- '--config.file=/etc/alertmanager/alertmanager.yml'
|
|
- '--storage.path=/alertmanager'
|
|
volumes:
|
|
- ./configs/alertmanager:/etc/alertmanager:ro
|
|
- {{containerPrefix}}-alertmanager-data:/alertmanager
|
|
networks:
|
|
- {{networkName}}
|
|
{{/if}}
|
|
|
|
# ─── Volumes ──────────────────────────────────────────────
|
|
|
|
volumes:
|
|
{{containerPrefix}}-postgres-data:
|
|
{{containerPrefix}}-redis-data:
|
|
{{containerPrefix}}-nocodb-data:
|
|
{{#if enableListmonk}}
|
|
{{containerPrefix}}-listmonk-data:
|
|
{{/if}}
|
|
{{#if enableGancio}}
|
|
{{containerPrefix}}-gancio-data:
|
|
{{/if}}
|
|
{{#if enableChat}}
|
|
{{containerPrefix}}-mongodb-data:
|
|
{{containerPrefix}}-rocketchat-uploads:
|
|
{{/if}}
|
|
{{#if enableDevTools}}
|
|
{{containerPrefix}}-gitea-data:
|
|
{{containerPrefix}}-n8n-data:
|
|
{{containerPrefix}}-homepage-data:
|
|
{{/if}}
|
|
{{#if enableMonitoring}}
|
|
{{containerPrefix}}-prometheus-data:
|
|
{{containerPrefix}}-grafana-data:
|
|
{{containerPrefix}}-alertmanager-data:
|
|
{{/if}}
|
|
|
|
# ─── Networks ─────────────────────────────────────────────
|
|
|
|
networks:
|
|
{{networkName}}:
|
|
driver: bridge
|