Produktions-Stack
Voraussetzungen
Abschnitt betitelt „Voraussetzungen“- Ein Linux-Host mit Docker Engine und dem Docker-Compose-Plugin.
- Die Ports 80 und 443 für Ihre Benutzer erreichbar (oder beliebige andere Ports, in
.envfestgelegt). - Für Let’s-Encrypt-Zertifikate: ein DNS-Name, der auf den Host zeigt, und die Ports 80 und 443 aus dem Internet erreichbar.
Was installiert wird
Abschnitt betitelt „Was installiert wird“Auditix wird als drei Images (frontend, backend, updater) in der Auditix-Registry
rg.fr-par.scw.cloud/auditix veröffentlicht und immer mit demselben Tag bereitgestellt. Die
Compose-Datei ergänzt die Dienste, auf die sie angewiesen sind:
| Dienst | Aufgabe |
|---|---|
gateway |
Der einzige veröffentlichte Dienst: liefert Auditix über HTTP und HTTPS aus. |
frontend |
Die Weboberfläche. |
backend |
Die Anwendung. Wendet Datenbankänderungen beim Start selbst an. |
updater |
Spielt die Updates ein, die unter Einstellungen › Plattform › Update gestartet werden. Optional. |
orchestrator |
Startet und stoppt die Worker-Container, die die Hintergrundarbeit erledigen. |
developer |
Die Referenz der externen API, unter /developer. |
logs |
Leitet die Protokolle an die Syslog-Server von Einstellungen › Plattform › Protokolle weiter. |
rabbitmq |
Warteschlangen der Hintergrundarbeit. |
mercure |
Echtzeit-Updates der Oberfläche. |
database |
PostgreSQL: Hier liegen sämtliche Daten. |
Die Dienste updater und orchestrator haben Zugriff auf Docker. Sie wirken ausschließlich auf die
Container ihrer eigenen Installation (das aus demselben Ordner bereitgestellte Compose-Projekt), nie auf
andere Container des Hosts.
Installieren
Abschnitt betitelt „Installieren“-
Bei der Registry anmelden (überspringen Sie diesen Schritt, wenn die Registry öffentlich ist), mit einem geheimen Scaleway-API-Schlüssel, der die Registry lesen darf:
Terminal-Fenster docker login rg.fr-par.scw.cloud/auditix -u nologin# Password: your Scaleway API secret key -
Installationsordner anlegen:
Terminal-Fenster mkdir -p /opt/auditix && cd /opt/auditix -
compose.yamlanlegen, mit dem Inhalt weiter unten. -
.envanlegen, nur für root lesbar (chmod 600 .env), und jedes Geheimnis einmalig mitopenssl rand -hex 32füllen:Terminal-Fenster # "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= -
Starten:
Terminal-Fenster docker compose pulldocker compose up -ddocker compose ps # every service should be "healthy" -
Anmelden unter
http://<host>mit dem Standardadministratoradmin/password. Auditix verlangt vor allem anderen ein neues Passwort: Legen Sie es sofort fest, bevor Sie den Dienst zugänglich machen.
compose.yaml
Abschnitt betitelt „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:Erste Schritte nach der Installation
Abschnitt betitelt „Erste Schritte nach der Installation“- Legen Sie unter Einstellungen › Plattform › Allgemein den Namen der Instanz, die Zeitzone, die Standardsprache und unter Darstellung das Standarddesign und die Hauptfarbe fest (siehe Einstellungen).
- Aktivieren Sie die Lizenz.
- Richten Sie HTTPS ein.
- Erstellen Sie die Tenants und die Konten.
Konten lassen sich auch über die Befehlszeile anlegen (mit Portainer über die Konsole des Backend-Containers):
docker compose exec backend bin/console auditix:user:create jane@example.com \ --first-name=Jane --last-name=Doe --platform-admin --tenant="My company"Mit Portainer
Abschnitt betitelt „Mit Portainer“- Stacks › Add stack › Web editor: Fügen Sie
compose.yamlein. - Übernehmen Sie die Variablen aus
.envin die Umgebungsvariablen des Stacks, mitAUDITIX_VERSION=latest. - Entfernen Sie im Dienst
updaterdas Volume.:/install: Portainer speichert die Dateien eines Stacks in einem eigenen Volume. Die vor Updates erstellten Sicherungen landen dann in einem Docker-Volume namens<stack>_backups, das der Updater anlegt.
Mehr ist nicht nötig: Updates ändern den Stack nie, und die Worker werden vom Dienst orchestrator
außerhalb des Stacks gestartet.
Behalten Sie den Installationsordner (/opt/auditix): Der Updater bindet ihn unter /install ein, um
die vor Updates erstellten Sicherungen in backups/ abzulegen und .env zu ändern, wenn
AUDITIX_VERSION eine feste Version ist.
Geben Sie unter Einstellungen › Plattform › Webzugriff den Hostnamen der Instanz an (sein DNS muss auf den Server zeigen) und wählen Sie dann das Zertifikat:
- Let’s Encrypt: kostenlos, automatisch ausgestellt und erneuert. Die Ports 80 und 443 müssen aus dem Internet erreichbar sein. Let’s Encrypt (Test) prüft zuerst die Einrichtung, mit Zertifikaten, denen Browser nicht vertrauen, ohne an die Limits von Let’s Encrypt zu stoßen.
- Eigenes Zertifikat: Fügen Sie das Zertifikat (PEM) (mit seinen Zwischenzertifikaten) und den Privaten Schlüssel (PEM) ein. Der Schlüssel wird verschlüsselt gespeichert und nie wieder angezeigt.
- Kein HTTPS (nur HTTP): für einen Test oder hinter einem Reverse-Proxy, der HTTPS übernimmt.
Schalten Sie dann HTTP auf HTTPS umleiten ein und, sobald HTTPS funktioniert, Striktes HTTPS (HSTS). Änderungen greifen innerhalb weniger Sekunden, ohne Neustart. Wenn eine falsche Einstellung Auditix über HTTPS unerreichbar macht, schalten Sie HTTPS auf dem Server aus:
docker compose exec backend bin/console auditix:web:resetHinter einem Reverse-Proxy, der HTTPS bereits übernimmt, lassen Sie HTTPS ausgeschaltet und leiten mit
den Headern X-Forwarded-Proto und X-Forwarded-For an den HTTP-Port des Gateways weiter.
Hintergrundarbeit
Abschnitt betitelt „Hintergrundarbeit“Der Dienst orchestrator startet die Worker-Container, die die Hintergrundarbeit erledigen
(geplante Aufgaben, Prüfungen, Importe…), wie unter Einstellungen › Plattform › Workers › Pools
festgelegt: eine feste Anzahl von Containern oder eine automatische Skalierung nach der Anzahl
wartender Nachrichten. Der Standard-Pool betreibt 2 bis 4 Container. Ohne den Orchestrator führt das
Backend die geplanten Aufgaben weiterhin alle fünf Minuten aus, aber sonst wird nichts im Hintergrund
verarbeitet.
Die Worker-Container gehören nicht zum Compose-Projekt, daher entfernt docker compose down sie nicht.
Um die Installation vollständig herunterzufahren (auditix ist der Projektname):
docker compose stop orchestratordocker rm -f $(docker ps -aq --filter label=io.auditix.orchestrator.project=auditix)docker compose downSichern
Abschnitt betitelt „Sichern“Alle Daten liegen in PostgreSQL. Sichern Sie sie regelmäßig und immer vor einem Update von Hand:
docker compose exec -T database pg_dump -U auditix -Fc auditix > auditix-$(date +%F).dumpWiederherstellen in eine leere Datenbank:
docker compose exec -T database pg_restore -U auditix -d auditix --clean --if-exists < auditix-YYYY-MM-DD.dumpAdministratorkonto wiederherstellen
Abschnitt betitelt „Administratorkonto wiederherstellen“Wenn sich kein Administrator mehr anmelden kann, setzen Sie auf dem Server ein neues Passwort:
docker compose exec backend bin/console auditix:user:password admin@example.com