Stack de production
Prérequis
Section intitulée « Prérequis »- Un hôte Linux avec Docker Engine et le plugin Docker Compose.
- Les ports 80 et 443 joignables par vos utilisateurs (ou tout autre port, défini dans
.env). - Pour les certificats Let’s Encrypt : un nom DNS qui pointe vers l’hôte, et les ports 80 et 443 joignables depuis Internet.
Ce qui est installé
Section intitulée « Ce qui est installé »Auditix est publié sous forme de trois images (frontend, backend, updater) sur le registre
Auditix, rg.fr-par.scw.cloud/auditix, toujours déployées avec le même tag. Le fichier compose
ajoute les services dont elles dépendent :
| Service | Rôle |
|---|---|
gateway |
Le seul service publié : sert Auditix en HTTP et en HTTPS. |
frontend |
L’interface web. |
backend |
L’application. Applique elle-même les modifications de la base de données à son démarrage. |
updater |
Applique les mises à jour lancées depuis Paramètres › Plateforme › Mise à jour. Facultatif. |
orchestrator |
Démarre et arrête les conteneurs workers qui exécutent les traitements en arrière-plan. |
developer |
La référence de l’API externe, sur /developer. |
logs |
Transmet les journaux aux serveurs syslog de Paramètres › Plateforme › Journaux. |
rabbitmq |
Files d’attente des traitements en arrière-plan. |
mercure |
Mises à jour en temps réel de l’interface. |
database |
PostgreSQL : toutes les données y sont stockées. |
Les services updater et orchestrator ont accès à Docker. Ils n’agissent jamais que sur les
conteneurs de leur propre installation (le projet compose déployé depuis le même dossier), jamais
sur les autres conteneurs de l’hôte.
Installer
Section intitulée « Installer »-
Connectez-vous au registre (ignorez cette étape si le registre est public), avec une clé secrète d’API Scaleway autorisée à lire le registre :
Fenêtre de terminal docker login rg.fr-par.scw.cloud/auditix -u nologin# Password: your Scaleway API secret key -
Créez le dossier d’installation :
Fenêtre de terminal mkdir -p /opt/auditix && cd /opt/auditix -
Créez
compose.yamlavec le contenu ci-dessous. -
Créez
.env, lisible par root uniquement (chmod 600 .env), et renseignez chaque secret une seule fois avecopenssl rand -hex 32:Fenêtre de terminal # "latest": updated from Settings › Platform › Update. Or a fixed release (vX.Y.Z).AUDITIX_VERSION=latestHTTP_PORT=80HTTPS_PORT=443# Generate each once with: openssl rand -hex 32APP_SECRET=POSTGRES_PASSWORD=MERCURE_JWT_SECRET=RABBITMQ_PASSWORD=GATEWAY_SECRET=UPDATER_SECRET= -
Démarrez :
Fenêtre de terminal docker compose pulldocker compose up -ddocker compose ps # every service should be "healthy" -
Connectez-vous sur
http://<host>avec l’administrateur par défaut,admin/password. Auditix demande un nouveau mot de passe avant toute chose : faites-le immédiatement, avant d’exposer le service.
compose.yaml
Section intitulée « compose.yaml »name: auditix
# Every service hands its output to Docker's syslog driver, towards the log collector, which# forwards it to the syslog servers of Settings › Platform › Logs.x-logging: &logging driver: syslog options: syslog-address: udp://127.0.0.1:15013 syslog-format: rfc5424 tag: "{{.Name}}"
services: # The only published service. HTTPS and the certificate are set in Settings › Platform › Web # access; the gateway reads them from the backend. gateway: logging: *logging image: traefik:v3.7 command: - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --entrypoints.web.forwardedHeaders.trustedIPs=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32 - --entrypoints.websecure.forwardedHeaders.trustedIPs=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32 - --providers.http.endpoint=http://backend:8080/internal/gateway - --providers.http.pollInterval=5s - --providers.http.headers.X-Gateway-Secret=${GATEWAY_SECRET:?Set GATEWAY_SECRET in .env} - --certificatesresolvers.letsencrypt.acme.storage=/data/acme.json - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web - --certificatesresolvers.letsencrypt-staging.acme.storage=/data/acme-staging.json - --certificatesresolvers.letsencrypt-staging.acme.httpchallenge.entrypoint=web - --certificatesresolvers.letsencrypt-staging.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory - --ping=true - --global.checkNewVersion=false - --global.sendAnonymousUsage=false ports: - "${HTTP_PORT:-80}:80" - "${HTTPS_PORT:-443}:443" volumes: - gateway:/data healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] interval: 10s timeout: 3s retries: 6 depends_on: backend: condition: service_healthy restart: unless-stopped
frontend: logging: *logging image: rg.fr-par.scw.cloud/auditix/frontend:${AUDITIX_VERSION:-latest} environment: BACKEND_URL: http://backend:8080 depends_on: backend: condition: service_healthy restart: unless-stopped
backend: logging: *logging image: rg.fr-par.scw.cloud/auditix/backend:${AUDITIX_VERSION:-latest} environment: &backend-environment APP_SECRET: ${APP_SECRET:?Set APP_SECRET in .env} DATABASE_URL: postgresql://auditix:${POSTGRES_PASSWORD}@database:5432/auditix?serverVersion=18&charset=utf8 MERCURE_URL: http://mercure/.well-known/mercure MERCURE_JWT_SECRET: ${MERCURE_JWT_SECRET:?Set MERCURE_JWT_SECRET in .env} MESSENGER_TRANSPORT_DSN: amqp://auditix:${RABBITMQ_PASSWORD:?Set RABBITMQ_PASSWORD in .env}@rabbitmq:5672/%2f GATEWAY_SECRET: ${GATEWAY_SECRET} UPDATER_SECRET: ${UPDATER_SECRET:-} LOGS_COLLECTOR_HOST: logs # Never published: the internal API is only for the frontend; integrations use the # external API (/api/v1) through the gateway. volumes: - logs-config:/app/var/logs-collector depends_on: database: condition: service_healthy rabbitmq: condition: service_healthy restart: unless-stopped
# Applies the updates started from Settings › Platform › Update. The only service with access to # Docker: it only acts on the services of this file (its own compose project), never on other # containers of the host. Optional: without it, update by hand (see Update below). updater: logging: *logging image: rg.fr-par.scw.cloud/auditix/updater:${AUDITIX_VERSION:-latest} environment: BACKEND_URL: http://backend:8080 UPDATER_SECRET: ${UPDATER_SECRET:?Set UPDATER_SECRET in .env} volumes: - /var/run/docker.sock:/var/run/docker.sock # The installation directory: the backups taken before updates in backups/, and its .env # when AUDITIX_VERSION is a fixed release. - .:/install depends_on: backend: condition: service_healthy restart: unless-stopped
# Runs the background work: starts and stops the worker containers (the backend image, started # with the "worker" command) as the pools of Settings › Platform › Workers ask, a fixed number or # following the backlog of their queues. Same image as the updater; it only acts on the worker # containers it creates for this installation. Without it, no worker runs (see Scale the workers). orchestrator: logging: *logging image: rg.fr-par.scw.cloud/auditix/updater:${AUDITIX_VERSION:-latest} entrypoint: ["auditix-orchestrator"] environment: BACKEND_URL: http://backend:8080 UPDATER_SECRET: ${UPDATER_SECRET:?Set UPDATER_SECRET in .env} volumes: - /var/run/docker.sock:/var/run/docker.sock depends_on: backend: condition: service_healthy restart: unless-stopped
# The developer portal: the reference of the external API, at /developer. developer: logging: *logging image: scalarapi/api-reference:0.6.12 environment: BASE_PATH: /developer/scalar API_REFERENCE_CONFIG: '{"sources":[{"url":"/api/v1/openapi.json","title":"Auditix API"}],"theme":"none","withDefaultFonts":false,"customCss":"@import url(\"/theme/developer\");","favicon":"/icon.svg","metaData":{"title":"Auditix API"},"defaultHttpClient":{"targetKey":"shell","clientKey":"curl"},"showDeveloperTools":"never","agent":{"disabled":true},"mcp":{"disabled":true}}' restart: unless-stopped
# The log collector: forwards the logs to the syslog servers of the settings. logs: image: timberio/vector:0.59.0-alpine command: ["--config-dir", "/etc/vector/auditix", "--watch-config"] ports: - "127.0.0.1:15013:5514/udp" volumes: - logs-config:/etc/vector/auditix:ro depends_on: backend: condition: service_healthy restart: unless-stopped
# Queues of the background work. rabbitmq: logging: *logging image: rabbitmq:4.3-management-alpine hostname: rabbitmq environment: RABBITMQ_DEFAULT_USER: auditix RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD} volumes: - rabbitmq:/var/lib/rabbitmq healthcheck: test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"] interval: 10s timeout: 10s retries: 12 restart: unless-stopped
# Real-time updates. Not published: the browsers reach it through the gateway. mercure: logging: *logging image: dunglas/mercure:v1.1 environment: SERVER_NAME: ":80" MERCURE_TRUSTED_ISSUERS: auditix MERCURE_PUBLISHER_JWT_KEY: ${MERCURE_JWT_SECRET} MERCURE_PUBLISHER_JWT_ALG: HS256 MERCURE_SUBSCRIBER_JWT_KEY: ${MERCURE_JWT_SECRET} MERCURE_SUBSCRIBER_JWT_ALG: HS256 MERCURE_EXTRA_DIRECTIVES: | resource_identifier http://mercure/.well-known/mercure cookie_name auditix_live transport bolt { path /data/mercure.db size 1000 cleanup_frequency 0.3 } heartbeat 15s volumes: - mercure:/data restart: unless-stopped
database: logging: *logging image: postgres:18-alpine environment: POSTGRES_DB: auditix POSTGRES_USER: auditix POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env} volumes: - database:/var/lib/postgresql healthcheck: test: ["CMD", "pg_isready", "-U", "auditix", "-d", "auditix"] interval: 5s timeout: 3s retries: 10 restart: unless-stopped
volumes: database: gateway: logs-config: mercure: rabbitmq:Premières étapes après l’installation
Section intitulée « Premières étapes après l’installation »- Dans Paramètres › Plateforme › Général, définissez le Nom de l’instance, le Fuseau horaire, la Langue par défaut et, dans Apparence, le Thème par défaut et la Couleur principale (voir Paramètres).
- Activez la licence.
- Configurez HTTPS.
- Créez les tenants et les comptes.
Les comptes peuvent aussi être créés en ligne de commande (avec Portainer, depuis la console du conteneur backend) :
docker compose exec backend bin/console auditix:user:create jane@example.com \ --first-name=Jane --last-name=Doe --platform-admin --tenant="My company"Avec Portainer
Section intitulée « Avec Portainer »- Stacks › Add stack › Web editor : collez
compose.yaml. - Placez les variables de
.envdans les variables d’environnement de la stack, avecAUDITIX_VERSION=latest. - Dans le service
updater, supprimez le volume.:/install: Portainer conserve les fichiers d’une stack dans son propre volume. Les sauvegardes effectuées avant les mises à jour sont alors stockées dans un volume Docker nommé<stack>_backups, créé par l’updater.
Rien d’autre n’est nécessaire : les mises à jour ne modifient jamais la stack, et les workers sont
démarrés par le service orchestrator, en dehors de la stack.
Conservez le dossier d’installation (/opt/auditix) : l’updater le monte sur /install pour
stocker dans backups/ les sauvegardes qu’il effectue avant les mises à jour, et pour modifier
.env lorsque AUDITIX_VERSION est une version fixe.
Dans Paramètres › Plateforme › Accès web, indiquez le Nom d’hôte de l’instance (son DNS doit pointer vers le serveur), puis choisissez le Certificat :
- Let’s Encrypt : gratuit, émis et renouvelé automatiquement. Les ports 80 et 443 doivent être joignables depuis Internet. Let’s Encrypt (test) vérifie d’abord la configuration, avec des certificats auxquels les navigateurs ne font pas confiance, sans atteindre les limites de Let’s Encrypt.
- Mon propre certificat : collez le Certificat (PEM) (avec ses certificats intermédiaires) et la Clé privée (PEM). La clé est stockée chiffrée et n’est plus jamais affichée.
- Pas de HTTPS (HTTP seul) : pour un essai, ou derrière un reverse proxy qui gère le HTTPS.
Activez ensuite Rediriger HTTP vers HTTPS et, une fois le HTTPS fonctionnel, HTTPS strict (HSTS). Les modifications s’appliquent en quelques secondes, sans redémarrage. Si un mauvais réglage rend Auditix injoignable en HTTPS, désactivez le HTTPS depuis le serveur :
docker compose exec backend bin/console auditix:web:resetDerrière un reverse proxy qui gère déjà le HTTPS, laissez le HTTPS désactivé et transmettez au port
HTTP de la gateway avec les en-têtes X-Forwarded-Proto et X-Forwarded-For.
Traitements en arrière-plan
Section intitulée « Traitements en arrière-plan »Le service orchestrator démarre les conteneurs workers qui effectuent les traitements en
arrière-plan (tâches planifiées, vérifications, imports…), selon les réglages de Paramètres ›
Plateforme › Workers › Pools : un nombre fixe de conteneurs, ou une mise à l’échelle
Automatique selon le nombre de messages en attente. Le pool par défaut exécute 2 à 4 conteneurs.
Sans l’orchestrateur, le backend exécute tout de même les tâches planifiées toutes les cinq minutes,
mais rien d’autre n’est traité en arrière-plan.
Les conteneurs workers ne font pas partie du projet compose : docker compose down ne les supprime
donc pas. Pour arrêter complètement l’installation (auditix étant le nom du projet) :
docker compose stop orchestratordocker rm -f $(docker ps -aq --filter label=io.auditix.orchestrator.project=auditix)docker compose downSauvegarder
Section intitulée « Sauvegarder »Toutes les données sont stockées dans PostgreSQL. Sauvegardez-les régulièrement, et toujours avant une mise à jour manuelle :
docker compose exec -T database pg_dump -U auditix -Fc auditix > auditix-$(date +%F).dumpRestaurez dans une base de données vide :
docker compose exec -T database pg_restore -U auditix -d auditix --clean --if-exists < auditix-YYYY-MM-DD.dumpRécupérer un compte administrateur
Section intitulée « Récupérer un compte administrateur »Lorsqu’aucun administrateur ne peut se connecter, définissez un nouveau mot de passe depuis le serveur :
docker compose exec backend bin/console auditix:user:password admin@example.com