Stack di produzione
Requisiti
Sezione intitolata “Requisiti”- Un host Linux con Docker Engine e il plugin Docker Compose.
- Le porte 80 e 443 raggiungibili dai Suoi utenti (o qualsiasi altra porta, impostata in
.env). - Per i certificati Let’s Encrypt: un nome DNS che punti all’host e le porte 80 e 443 raggiungibili da Internet.
Che cosa viene installato
Sezione intitolata “Che cosa viene installato”Auditix è pubblicato come tre immagini (frontend, backend, updater) nel registry di Auditix,
rg.fr-par.scw.cloud/auditix, sempre distribuite con lo stesso tag. Il file compose aggiunge i servizi
su cui si basano:
| Servizio | Ruolo |
|---|---|
gateway |
L’unico servizio pubblicato: serve Auditix in HTTP e HTTPS. |
frontend |
L’interfaccia web. |
backend |
L’applicazione. Applica da sola le modifiche al database all’avvio. |
updater |
Applica gli aggiornamenti avviati da Impostazioni › Piattaforma › Aggiornamento. Facoltativo. |
orchestrator |
Avvia e arresta i container worker che eseguono le attività in background. |
developer |
Il riferimento dell’API esterna, su /developer. |
logs |
Inoltra i log ai server syslog di Impostazioni › Piattaforma › Log. |
rabbitmq |
Code delle attività in background. |
mercure |
Aggiornamenti in tempo reale dell’interfaccia. |
database |
PostgreSQL: tutti i dati risiedono qui. |
I servizi updater e orchestrator hanno accesso a Docker. Agiscono soltanto sui container
della propria installazione (il progetto compose distribuito dalla stessa cartella), mai su altri
container dell’host.
Installare
Sezione intitolata “Installare”-
Acceda al registry (salti questo passaggio se il registry è pubblico), con una chiave segreta API Scaleway autorizzata a leggere il registry:
Finestra del terminale docker login rg.fr-par.scw.cloud/auditix -u nologin# Password: your Scaleway API secret key -
Crei la cartella di installazione:
Finestra del terminale mkdir -p /opt/auditix && cd /opt/auditix -
Crei
compose.yamlcon il contenuto riportato più sotto. -
Crei
.env, leggibile solo da root (chmod 600 .env), e compili ogni segreto una sola volta conopenssl rand -hex 32:Finestra del terminale # "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= -
Avvii:
Finestra del terminale docker compose pulldocker compose up -ddocker compose ps # every service should be "healthy" -
Acceda a
http://<host>con l’amministratore predefinito,admin/password. Auditix chiede una nuova password prima di ogni altra cosa: la imposti subito, prima di esporre il servizio.
compose.yaml
Sezione intitolata “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:Primi passi dopo l’installazione
Sezione intitolata “Primi passi dopo l’installazione”- In Impostazioni › Piattaforma › Generale, imposti il Nome dell’istanza, il Fuso orario, la Lingua predefinita e, in Aspetto, il Tema predefinito e il Colore principale (vedere Impostazioni).
- Attivi la licenza.
- Configuri HTTPS.
- Crei i tenant e gli account.
Gli account possono essere creati anche dalla riga di comando (con Portainer, dalla console del container backend):
docker compose exec backend bin/console auditix:user:create jane@example.com \ --first-name=Jane --last-name=Doe --platform-admin --tenant="My company"Con Portainer
Sezione intitolata “Con Portainer”- Stacks › Add stack › Web editor: incolli
compose.yaml. - Inserisca le variabili di
.envnelle variabili d’ambiente dello stack, conAUDITIX_VERSION=latest. - Nel servizio
updater, rimuova il volume.:/install: Portainer conserva i file di uno stack nel proprio volume. I backup eseguiti prima degli aggiornamenti finiscono allora in un volume Docker chiamato<stack>_backups, creato dal programma di aggiornamento.
Non serve nient’altro: gli aggiornamenti non modificano mai lo stack, e i worker vengono avviati dal
servizio orchestrator, al di fuori dello stack.
Conservi la cartella di installazione (/opt/auditix): il programma di aggiornamento la monta su /install per salvare
in backups/ i backup eseguiti prima degli aggiornamenti, e per modificare .env quando AUDITIX_VERSION è una versione
fissa.
In Impostazioni › Piattaforma › Accesso web, indichi il Nome host dell’istanza (il suo DNS deve puntare al server), poi scelga il Certificato:
- Let’s Encrypt: gratuito, emesso e rinnovato automaticamente. Le porte 80 e 443 devono essere raggiungibili da Internet. Let’s Encrypt (test) verifica prima la configurazione, con certificati di cui i browser non si fidano, senza incorrere nei limiti di Let’s Encrypt.
- Il mio certificato: incolli il Certificato (PEM) (con i suoi certificati intermedi) e la Chiave privata (PEM). La chiave viene salvata cifrata e non viene mai più mostrata.
- Nessun HTTPS (solo HTTP): per un test, o dietro un reverse proxy che gestisce HTTPS.
Attivi poi Reindirizza HTTP a HTTPS e, una volta che HTTPS funziona, HTTPS rigoroso (HSTS). Le modifiche si applicano entro pochi secondi, senza riavvio. Se un’impostazione errata rende Auditix irraggiungibile in HTTPS, disattivi HTTPS dal server:
docker compose exec backend bin/console auditix:web:resetDietro un reverse proxy che gestisce già HTTPS, lasci HTTPS disattivato e inoltri il traffico alla porta HTTP del
gateway con le intestazioni X-Forwarded-Proto e X-Forwarded-For.
Attività in background
Sezione intitolata “Attività in background”Il servizio orchestrator avvia i container worker che eseguono le attività in background (attività
pianificate, controlli, importazioni…), come impostato in Impostazioni › Piattaforma › Worker › Pool: un numero fisso di
container, oppure un dimensionamento Automatico in base al numero di messaggi in attesa. Il pool predefinito esegue da 2 a 4
container. Senza l’orchestrator, il backend esegue comunque le attività pianificate ogni cinque minuti, ma
nient’altro viene elaborato in background.
I container worker non fanno parte del progetto compose, quindi docker compose down non li
rimuove. Per arrestare completamente l’installazione (auditix è il nome del progetto):
docker compose stop orchestratordocker rm -f $(docker ps -aq --filter label=io.auditix.orchestrator.project=auditix)docker compose downTutti i dati risiedono in PostgreSQL. Ne esegua il backup regolarmente, e sempre prima di un aggiornamento a mano:
docker compose exec -T database pg_dump -U auditix -Fc auditix > auditix-$(date +%F).dumpRipristino in un database vuoto:
docker compose exec -T database pg_restore -U auditix -d auditix --clean --if-exists < auditix-YYYY-MM-DD.dumpRecuperare un account amministratore
Sezione intitolata “Recuperare un account amministratore”Quando nessun amministratore riesce ad accedere, imposti una nuova password dal server:
docker compose exec backend bin/console auditix:user:password admin@example.com