Files
hcornet ac929c6878
build / Garde-fou (push) Successful in 10m21s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m48s
build / Images Harbor (web, Dockerfile) (push) Successful in 9m57s
Interface honnete sur l'acces aux comptes, fenetre de contribution
2026-09-11 14:05:32 +02:00

177 lines
7.3 KiB
YAML

# Deploiement de production, derriere le Traefik existant.
# Aucun port n'est publie : le trafic entre par le tunnel Cloudflare puis Traefik.
#
# cp .env.example .env puis renseigner ENCLUME_TAG et ENCLUME_DOMAINE
# docker compose pull && docker compose up -d
#
# Retour arriere : remettre l'ancienne valeur de ENCLUME_TAG, puis up -d.
name: enclume
services:
web:
image: ${ENCLUME_REGISTRY:-registry.tips-of-mine.com}/enclume/web:${ENCLUME_TAG:?definir ENCLUME_TAG dans .env}
restart: unless-stopped
environment:
# catalog-sync publie chaque revision a cote et fait basculer ce lien.
# Si le volume est vide, l'application se rabat sur le catalogue de l'image.
ENCLUME_CATALOG: /catalogue/actuel
GUNICORN_WORKERS: ${GUNICORN_WORKERS:-2}
TZ: ${TZ:-Europe/Paris}
ENCLUME_URL_PUBLIQUE: https://${ENCLUME_DOMAINE}
# Sessions. Sans cle, elles sont perdues a chaque redemarrage.
ENCLUME_SECRET_KEY: ${ENCLUME_SECRET_KEY:?definir ENCLUME_SECRET_KEY}
# Base : sans elle, ni partage ni comptes, l'editeur fonctionne quand meme.
# Elements separes plutot qu'une URL : un mot de passe contenant @ : / ?
# casserait une URL, ici il est encode par l'application.
ENCLUME_DB_HOTE: db
ENCLUME_DB_PORT: "5432"
ENCLUME_DB_NOM: enclume
ENCLUME_DB_UTILISATEUR: enclume
ENCLUME_DB_MOTDEPASSE: ${POSTGRES_PASSWORD:?definir POSTGRES_PASSWORD}
ENCLUME_PARTAGE_JOURS: ${ENCLUME_PARTAGE_JOURS:-90}
# Mentions legales. Sans ces valeurs, la page indique ce qui manque.
ENCLUME_EDITEUR: ${ENCLUME_EDITEUR:-}
ENCLUME_CONTACT: ${ENCLUME_CONTACT:-}
ENCLUME_HEBERGEUR: ${ENCLUME_HEBERGEUR:-}
ENCLUME_DEPOT: ${ENCLUME_DEPOT:-}
# Connexion optionnelle, deleguee a Authentik qui federe GitHub et Google.
ENCLUME_OIDC_METADATA: ${ENCLUME_OIDC_METADATA:-}
ENCLUME_OIDC_CLIENT_ID: ${ENCLUME_OIDC_CLIENT_ID:-}
ENCLUME_OIDC_CLIENT_SECRET: ${ENCLUME_OIDC_CLIENT_SECRET:-}
ENCLUME_INSCRIPTION_OUVERTE: ${ENCLUME_INSCRIPTION_OUVERTE:-0}
ENCLUME_ADMIN_GROUPE: ${ENCLUME_ADMIN_GROUPE:-enclume-admins}
ENCLUME_ADMIN_COMPTES: ${ENCLUME_ADMIN_COMPTES:-}
# Depot du catalogue : la moderation y ouvre des demandes de fusion.
ENCLUME_GITEA_URL: ${ENCLUME_GITEA_URL:-}
ENCLUME_GITEA_TOKEN: ${ENCLUME_GITEA_TOKEN:-}
ENCLUME_GITEA_PROPRIETAIRE: ${ENCLUME_GITEA_PROPRIETAIRE:-}
ENCLUME_GITEA_DEPOT: ${ENCLUME_GITEA_DEPOT:-}
depends_on:
db:
condition: service_healthy
# Gitea et ce conteneur sont souvent sur le meme reseau. Faire sortir la
# requete par un tunnel pour revenir chez soi l'expose aux protections
# placees devant lui, qui rejettent les clients non navigateurs. Decommenter
# et adapter : le nom reste le meme, donc le certificat aussi, seul le
# chemin reseau change.
# extra_hosts:
# - "gitea.exemple.com:192.168.1.10"
volumes:
- catalogue:/catalogue:ro
networks: [back_network_enclume, db_network_enclume, traefik_front_network]
read_only: true
tmpfs:
- /tmp:size=32m,mode=1777
- /app/.gunicorn:size=8m,mode=0700,uid=10001,gid=10001
security_opt: ["no-new-privileges:true"]
cap_drop: [ALL]
deploy:
resources:
limits: {cpus: "1.0", memory: 512M}
logging:
driver: json-file
options: {max-size: "10m", max-file: "3"}
labels:
# Watchtower volontairement absent : les versions sont epinglees dans .env
# et le retour arriere repose sur ce controle. Une mise a jour automatique
# le rendrait illusoire.
- "traefik.enable=true"
- "traefik.docker.network=traefik_front_network"
# HTTP
- "traefik.http.routers.enclume-http.rule=Host(`${ENCLUME_DOMAINE:?definir ENCLUME_DOMAINE}`)"
- "traefik.http.routers.enclume-http.entrypoints=http"
- "traefik.http.routers.enclume-http.priority=49"
# HTTPS
- "traefik.http.routers.enclume-https.rule=Host(`${ENCLUME_DOMAINE}`)"
- "traefik.http.routers.enclume-https.entrypoints=https"
- "traefik.http.routers.enclume-https.tls=true"
- "traefik.http.routers.enclume-https.priority=50"
- "traefik.http.routers.enclume-https.service=enclume-https-service"
- "traefik.http.routers.enclume-https.middlewares=enclume-middlewares,enclume-limite"
- "traefik.http.routers.enclume-https.observability.accesslogs=true"
- "traefik.http.routers.enclume-https.observability.metrics=true"
- "traefik.http.routers.enclume-https.observability.tracing=true"
# Middleware
- "traefik.http.middlewares.enclume-middlewares.headers.STSSeconds=15552000"
- "traefik.http.middlewares.enclume-middlewares.headers.forceSTSHeader=true"
- "traefik.http.middlewares.enclume-middlewares.headers.STSIncludeSubdomains=true"
- "traefik.http.middlewares.enclume-middlewares.headers.STSPreload=true"
- "traefik.http.middlewares.enclume-middlewares.headers.frameDeny=true"
# Site public : une limite de debit evite qu'un script ne monopolise la generation.
- "traefik.http.middlewares.enclume-limite.ratelimit.average=60"
- "traefik.http.middlewares.enclume-limite.ratelimit.burst=120"
# Service
- "traefik.http.services.enclume-https-service.loadbalancer.server.port=8080"
# Homepage
- "homepage.group=Supervision"
- "homepage.name=Enclume"
- "homepage.icon=centreon.png"
- "homepage.href=https://${ENCLUME_DOMAINE}"
- "homepage.description=Generateur CLAPI Centreon"
catalog-sync:
image: ${ENCLUME_REGISTRY:-registry.tips-of-mine.com}/enclume/catalog-sync:${ENCLUME_TAG:?definir ENCLUME_TAG dans .env}
restart: unless-stopped
environment:
CATALOG_REPO: ${CATALOG_REPO:-}
CATALOG_BRANCH: ${CATALOG_BRANCH:-main}
CATALOG_SUBDIR: ${CATALOG_SUBDIR:-catalog}
CATALOG_DEST: /catalogue
SYNC_INTERVAL: ${SYNC_INTERVAL:-300}
RELOAD_URL: http://web:8080/recharger
depends_on:
web:
condition: service_healthy
volumes:
- catalogue:/catalogue
networks: [back_network_enclume]
security_opt: ["no-new-privileges:true"]
deploy:
resources:
limits: {cpus: "0.25", memory: 128M}
logging:
driver: json-file
options: {max-size: "5m", max-file: "2"}
# Partages, projets enregistres et soumissions de packs.
# L'application demarre sans, tant que ENCLUME_DATABASE_URL n'est pas defini.
db:
image: postgres:16.4-alpine
restart: unless-stopped
environment:
POSTGRES_DB: enclume
POSTGRES_USER: enclume
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?definir POSTGRES_PASSWORD}
TZ: ${TZ:-Europe/Paris}
volumes:
- donnees:/var/lib/postgresql/data
networks: [db_network_enclume]
security_opt: ["no-new-privileges:true"]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U enclume -d enclume"]
interval: 20s
timeout: 5s
retries: 5
deploy:
resources:
limits: {cpus: "1.0", memory: 512M}
volumes:
catalogue:
donnees:
networks:
# Reseau du reverse proxy existant.
traefik_front_network:
external: true
# catalog-sync doit joindre Gitea : ce reseau a donc un acces sortant.
back_network_enclume:
driver: bridge
attachable: true
# La base n'a aucune raison de sortir : elle reste isolee avec l'application.
db_network_enclume:
internal: true