Author SHA1 Message Date
git-hermes bb8fdc64ba docs(n8n-sandbox): clarify post-install setup
Test / test (pull_request) Canceled after 0s
2026-09-03 10:03:59 +02:00
git-hermes 349adb2b95 fix(n8n-sandbox): secure runner and expose shared API key (#3)
Test / test (push) Canceled after 0s
Use mandatory HTTPS runner transport, expose the shared n8n API key in Runtipi, and publish tipi_version 2.
2026-09-02 16:07:13 +00:00
Hermes Agent cf81405a3f fix(n8n-sandbox): publish Runtipi update version
Test / test (pull_request) Canceled after 0s
2026-09-02 18:04:57 +02:00
Hermes Agent 95dd642243 feat(n8n-sandbox): expose shared API key in install form
Test / test (pull_request) Canceled after 0s
2026-09-02 17:58:07 +02:00
Hermes Agent 7df02cccdf fix(n8n-sandbox): secure runner HTTP endpoint 2026-09-02 17:46:56 +02:00
Guillaume 05e1056a36 chore(apps): remove macOS metadata (#2)
Test / test (push) Canceled after 0s
Remove tracked apps metadata and prevent it from returning.
2026-09-02 15:34:20 +00:00
Hermes Agent e91b993cad chore(apps): remove macOS metadata
Test / test (pull_request) Canceled after 0s
2026-09-02 17:32:07 +02:00
Guillaume cab772403d fix(apps): place n8n sandbox in app directory (#1)
Test / test (push) Canceled after 0s
Preserve the modern Runtipi YAML compose format and validate both modern and legacy app definitions.
2026-09-02 15:31:38 +00:00
Hermes Agent 0ded9c3a4d fix(apps): preserve modern n8n compose format
Test / test (pull_request) Canceled after 0s
2026-09-02 17:27:56 +02:00
Hermes Agent d24d0c194b fix(apps): normalize environment mappings
Test / test (pull_request) Canceled after 0s
2026-09-02 17:23:48 +02:00
Hermes Agent 8f3b7b3b2b fix(apps): place n8n sandbox in app directory
Test / test (pull_request) Canceled after 0s
2026-09-02 17:22:03 +02:00
13 changed files with 240 additions and 297 deletions
+1
View File
@@ -1 +1,2 @@
node_modules/ node_modules/
/apps/.DS_Store
+62 -6
View File
@@ -3,6 +3,7 @@ import { appInfoSchema, dynamicComposeSchema } from '@runtipi/common/schemas'
import { fromError } from 'zod-validation-error'; import { fromError } from 'zod-validation-error';
import fs from 'node:fs' import fs from 'node:fs'
import path from 'node:path' import path from 'node:path'
import YAML from 'yaml'
const getApps = async () => { const getApps = async () => {
const appsDir = await fs.promises.readdir(path.join(process.cwd(), 'apps')) const appsDir = await fs.promises.readdir(path.join(process.cwd(), 'apps'))
@@ -29,7 +30,7 @@ describe("each app should have the required files", async () => {
const apps = await getApps() const apps = await getApps()
for (const app of apps) { for (const app of apps) {
const files = ['config.json', 'docker-compose.json', 'metadata/logo.jpg', 'metadata/description.md'] const files = ['config.json', 'metadata/logo.jpg', 'metadata/description.md']
for (const file of files) { for (const file of files) {
test(`app ${app} should have ${file}`, async () => { test(`app ${app} should have ${file}`, async () => {
@@ -37,6 +38,12 @@ describe("each app should have the required files", async () => {
expect(fileContent).not.toBeNull() expect(fileContent).not.toBeNull()
}) })
} }
test(`app ${app} should have a compose file`, async () => {
const legacyCompose = await getFile(app, 'docker-compose.json')
const modernCompose = await getFile(app, 'docker-compose.yml')
expect(legacyCompose || modernCompose).not.toBeNull()
})
} }
}) })
@@ -58,17 +65,66 @@ describe("each app should have a valid config.json", async () => {
} }
}) })
describe("each app should have a valid docker-compose.json", async () => { describe("n8n-sandbox installation secrets", () => {
test("exposes the shared API key as a password field", async () => {
const fileContent = await getFile('n8n-sandbox', 'config.json')
const config = JSON.parse(fileContent || '{}')
const apiKey = config.form_fields?.find((field: { env_variable?: string }) => field.env_variable === 'SANDBOX_API_KEYS')
expect(apiKey?.type).toBe('password')
expect(apiKey?.required).toBe(true)
expect(apiKey?.min).toBeGreaterThanOrEqual(48)
expect(config.tipi_version).toBeGreaterThanOrEqual(2)
})
})
describe("n8n-sandbox post-install documentation", () => {
test("documents the actual n8n override and optional SearXNG JSON setup", async () => {
const description = await getFile('n8n-sandbox', 'metadata/description.md')
expect(description).toContain('services:\n n8n-2:\n environment:')
expect(description).toContain('N8N_SANDBOX_SERVICE_URL=http://sandbox-api:8080')
expect(description).not.toContain('sandbox-api:<PORT')
expect(description).toContain('N8N_SANDBOX_SERVICE_API_KEY=<clé choisie lors de linstallation>')
expect(description).toContain('/opt/runtipi/app-data/migrated/searxng/data/settings.yml')
expect(description).toContain('- json')
})
})
describe("modern compose files preserve runtime semantics", () => {
test("n8n-sandbox keeps its one-shot certificate service", async () => {
const fileContent = await getFile('n8n-sandbox', 'docker-compose.yml')
expect(fileContent).not.toBeNull()
const parsed = YAML.parse(fileContent || '')
expect(parsed['x-runtipi']?.schema_version).toBe(2)
expect(parsed.services?.['sandbox-certs']?.restart).toBe('no')
expect(parsed.services?.['sandbox-api']?.['x-runtipi']?.is_main).toBe(true)
expect(parsed.services?.['sandbox-runner-1']?.environment?.SANDBOX_RUNNER_HTTP_BASE_URL).toBe('https://sandbox-runner-1:8080')
expect(parsed.services?.['sandbox-runner-1']?.healthcheck?.test).toContain('https://localhost:8080/readyz')
})
})
describe("each app should have a valid compose file", async () => {
const apps = await getApps() const apps = await getApps()
for (const app of apps) { for (const app of apps) {
test(`app ${app} should have a valid docker-compose.json`, async () => { test(`app ${app} should have a valid compose file`, async () => {
const fileContent = await getFile(app, 'docker-compose.json') const legacyCompose = await getFile(app, 'docker-compose.json')
const parsed = dynamicComposeSchema.safeParse(JSON.parse(fileContent || '{}')) const modernCompose = await getFile(app, 'docker-compose.yml')
if (modernCompose) {
const parsed = YAML.parse(modernCompose)
expect(parsed['x-runtipi']?.schema_version).toBeTypeOf('number')
expect(parsed.services).toBeTypeOf('object')
return
}
const parsed = dynamicComposeSchema.safeParse(JSON.parse(legacyCompose || '{}'))
if (!parsed.success) { if (!parsed.success) {
const validationError = fromError(parsed.error); const validationError = fromError(parsed.error);
console.error(`Error parsing docker-compose.json for app ${app}:`, validationError.toString()); console.error(`Error parsing compose file for app ${app}:`, validationError.toString());
} }
expect(parsed.success).toBe(true) expect(parsed.success).toBe(true)
BIN
View File
Binary file not shown.
-49
View File
@@ -1,49 +0,0 @@
# n8n Sandbox Service
Sandbox auto-hébergé pour l'**AI Assistant** de n8n (setup « Self-host the sandbox manually » de la doc n8n). L'app déploie les trois services de la stack officielle :
| Service | Rôle |
|---|---|
| `sandbox-certs` | Job one-shot : génère la CA privée et les certificats mTLS, puis s'arrête. |
| `sandbox-api` | Point d'entrée HTTP (`:8080`) que n8n appelle pour exécuter du code. |
| `sandbox-runner-1` | Docker-in-Docker **privileged** : crée et exécute les conteneurs sandbox. |
## Après l'installation
Dans l'app **n8n** (paramètres ou `app.env`), ajouter :
```
N8N_ENABLED_MODULES=instance-ai
N8N_INSTANCE_AI_SANDBOX_ENABLED=true
N8N_INSTANCE_AI_SANDBOX_PROVIDER=n8n-sandbox
N8N_INSTANCE_AI_SANDBOX_IMAGE=n8nio/n8n-sandbox-service-sandbox:1.3.0
N8N_SANDBOX_SERVICE_URL=http://sandbox-api:8080
N8N_SANDBOX_SERVICE_API_KEY=<valeur du champ « Clé API sandbox »>
```
Puis redémarrer n8n et vérifier depuis son conteneur :
```
wget -qO- http://sandbox-api:8080/healthz # {"status":"ok"}
```
## Données persistantes
Tout est sous `app-data/<store>/n8n-sandbox/data/` :
- `tls/` : certificats mTLS (contient la clé de la CA, à traiter comme un secret)
- `api/` : base SQLite de l'API
- `runner-state/` : base SQLite du runner
- `runner-docker/` : `/var/lib/docker` du DinD (cache de l'image sandbox, peut peser plusieurs Go ; vidable sans perte)
## Sécurité
- Aucun port n'est publié sur l'hôte. `sandbox-api:8080` est joignable par les autres apps Runtipi via `tipi_main_network`, protégé uniquement par la clé API.
- Le runner est `privileged` : équivalent root sur l'hôte. Ne jamais l'exposer.
- n8n recommande cette stack pour le développement/test et Daytona pour la production.
## Notes
- Les noms `sandbox-api` et `sandbox-runner-1` sont les SAN des certificats : ne pas les renommer.
- Les certificats ne se renouvellent pas seuls. Pour les régénérer, supprimer `data/tls/` et redémarrer l'app.
- L'image sandbox est téléchargée par le runner au premier usage.
+16 -58
View File
@@ -7,64 +7,22 @@
"hostname": "mediamtx", "hostname": "mediamtx",
"isMain": true, "isMain": true,
"internalPort": "8889", "internalPort": "8889",
"environment": [ "environment": {
{ "MTX_PROTOCOLS": "tcp",
"key": "MTX_PROTOCOLS", "MTX_LOGLEVEL": "info",
"value": "tcp" "MTX_LOGDESTINATIONS": "stdout",
}, "MTX_RTSPADDRESS": ":8554",
{ "MTX_RTMPADDRESS": ":1935",
"key": "MTX_LOGLEVEL", "MTX_HLSADDRESS": ":8888",
"value": "info" "MTX_WEBRTCADDRESS": ":8889",
}, "MTX_SRTADDRESS": ":8890",
{ "MTX_APIADDRESS": ":9997",
"key": "MTX_LOGDESTINATIONS", "MTX_METRICSADDRESS": ":9998",
"value": "stdout" "MTX_AUTHINTERNALUSERS": "${MTX_API_USERNAME:+${MTX_API_USERNAME}:${MTX_API_PASSWORD}}",
}, "MTX_PATHDEFAULTS_RECORD": "${MTX_RECORD_ENABLED:-false}",
{ "MTX_PATHDEFAULTS_RECORDPATH": "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f",
"key": "MTX_RTSPADDRESS", "MTX_PATHDEFAULTS_RECORDFORMAT": "fmp4"
"value": ":8554" },
},
{
"key": "MTX_RTMPADDRESS",
"value": ":1935"
},
{
"key": "MTX_HLSADDRESS",
"value": ":8888"
},
{
"key": "MTX_WEBRTCADDRESS",
"value": ":8889"
},
{
"key": "MTX_SRTADDRESS",
"value": ":8890"
},
{
"key": "MTX_APIADDRESS",
"value": ":9997"
},
{
"key": "MTX_METRICSADDRESS",
"value": ":9998"
},
{
"key": "MTX_AUTHINTERNALUSERS",
"value": "${MTX_API_USERNAME:+${MTX_API_USERNAME}:${MTX_API_PASSWORD}}"
},
{
"key": "MTX_PATHDEFAULTS_RECORD",
"value": "${MTX_RECORD_ENABLED:-false}"
},
{
"key": "MTX_PATHDEFAULTS_RECORDPATH",
"value": "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f"
},
{
"key": "MTX_PATHDEFAULTS_RECORDFORMAT",
"value": "fmp4"
}
],
"addPorts": [ "addPorts": [
{ {
"containerPort": 8554, "containerPort": 8554,
@@ -6,7 +6,7 @@
"no_gui": true, "no_gui": true,
"dynamic_config": true, "dynamic_config": true,
"port": 8080, "port": 8080,
"tipi_version": 1, "tipi_version": 3,
"min_tipi_version": "4.7.0", "min_tipi_version": "4.7.0",
"version": "1.3.0", "version": "1.3.0",
"author": "n8n", "author": "n8n",
@@ -18,11 +18,11 @@
"supported_architectures": ["amd64", "arm64"], "supported_architectures": ["amd64", "arm64"],
"form_fields": [ "form_fields": [
{ {
"type": "random", "type": "password",
"encoding": "hex",
"min": 48, "min": 48,
"label": "Cle API sandbox (SANDBOX_API_KEYS)", "max": 128,
"hint": "A recopier dans l'app n8n : N8N_SANDBOX_SERVICE_API_KEY. Plusieurs cles possibles, separees par des virgules.", "label": "Clé API partagée avec n8n (SANDBOX_API_KEYS)",
"hint": "Choisir une clé forte, puis recopier cette même valeur dans N8N_SANDBOX_SERVICE_API_KEY dans les paramètres de l'app n8n officielle.",
"required": true, "required": true,
"env_variable": "SANDBOX_API_KEYS" "env_variable": "SANDBOX_API_KEYS"
}, },
@@ -115,11 +115,10 @@ services:
SANDBOX_RUNNER_REGISTRATION_TOKEN: "${SANDBOX_REGISTRATION_TOKEN}" SANDBOX_RUNNER_REGISTRATION_TOKEN: "${SANDBOX_REGISTRATION_TOKEN}"
SANDBOX_RUNNER_API_GRPC_ADDR: sandbox-api:9090 SANDBOX_RUNNER_API_GRPC_ADDR: sandbox-api:9090
# http:// et non https:// : le mTLS ne couvre que le gRPC # Le listener HTTP du runner sert obligatoirement TLS avec le certificat
# (enregistrement + SandboxControl). Le trafic proxy exec/files de # SandboxControl. Son SAN sandbox-runner-1 est genere par sandbox-certs.
# l'API vers le runner reste en HTTP clair authentifie par X-Api-Key # HTTP est refuse depuis la version 1.3.0 pour ne pas exposer X-Api-Key.
# (docs/configuration.md du depot et compose officiel n8n). SANDBOX_RUNNER_HTTP_BASE_URL: https://sandbox-runner-1:8080
SANDBOX_RUNNER_HTTP_BASE_URL: http://sandbox-runner-1:8080
SANDBOX_RUNNER_CONTROL_GRPC_LISTEN_ADDR: ":9091" SANDBOX_RUNNER_CONTROL_GRPC_LISTEN_ADDR: ":9091"
SANDBOX_RUNNER_CONTROL_GRPC_ADVERTISE_ADDR: sandbox-runner-1:9091 SANDBOX_RUNNER_CONTROL_GRPC_ADVERTISE_ADDR: sandbox-runner-1:9091
@@ -148,8 +147,9 @@ services:
healthcheck: healthcheck:
# /readyz passe au vert une fois le runner enregistre aupres de l'API # /readyz passe au vert une fois le runner enregistre aupres de l'API
# (meme check que le compose du depot upstream). # Le probe local ignore uniquement la verification du certificat ; le
test: "wget -qO- http://localhost:8080/readyz" # trafic API -> runner reste verifie avec la CA et le SAN partages.
test: "wget -qO- --no-check-certificate https://localhost:8080/readyz"
interval: 5s interval: 5s
timeout: 5s timeout: 5s
retries: 24 retries: 24
+96
View File
@@ -0,0 +1,96 @@
# n8n Sandbox Service
Sandbox auto-hébergé pour l'**AI Assistant** de n8n (configuration « Self-host the sandbox manually » de la documentation n8n). L'app déploie les trois services de la stack officielle :
| Service | Rôle |
|---|---|
| `sandbox-certs` | Job one-shot : génère la CA privée et les certificats mTLS, puis s'arrête. |
| `sandbox-api` | Point d'entrée HTTP interne (`:8080`) que n8n appelle pour exécuter du code. |
| `sandbox-runner-1` | Docker-in-Docker **privileged** : crée et exécute les conteneurs sandbox. |
## Après l'installation
Pendant l'installation, choisir une clé forte dans le champ **Clé API partagée avec n8n** et la conserver dans un gestionnaire de mots de passe.
Dans l'application officielle **n8n**, activer la **configuration utilisateur Docker Compose**, puis ajouter :
```yaml
# Add your docker-compose overrides here.
# The overrides will be merged with the generated docker-compose.yml file.
# Heure de Paris
services:
n8n-2:
environment:
- GENERIC_TIMEZONE=Europe/Paris
# AI Assistant et Sandbox externe
- N8N_ENABLED_MODULES=instance-ai
- N8N_INSTANCE_AI_SANDBOX_ENABLED=true
- N8N_INSTANCE_AI_SANDBOX_PROVIDER=n8n-sandbox
- N8N_INSTANCE_AI_SANDBOX_IMAGE=n8nio/n8n-sandbox-service-sandbox:1.3.0
- N8N_SANDBOX_SERVICE_URL=http://sandbox-api:8080
- N8N_SANDBOX_SERVICE_API_KEY=<clé choisie lors de linstallation>
```
Remplacer entièrement `<clé choisie lors de linstallation>` par la vraie clé, sans conserver les caractères `<` et `>`. Ne jamais publier cette valeur.
Le port de `N8N_SANDBOX_SERVICE_URL` reste `8080` : il s'agit du port interne du service Docker, pas du port éventuellement choisi dans l'interface Runtipi.
Enregistrer la configuration, puis redémarrer l'application **n8n**. Pour vérifier la communication depuis son conteneur :
```sh
wget -qO- http://sandbox-api:8080/healthz
```
La réponse attendue est `{"status":"ok"}`.
## Recherche web avec SearXNG (facultatif)
SearXNG est une application séparée et n'est pas nécessaire au fonctionnement du sandbox. L'installer seulement si les workflows ou outils IA de n8n doivent effectuer des recherches web.
Pour autoriser les réponses JSON de SearXNG, modifier :
```sh
sudo nano /opt/runtipi/app-data/migrated/searxng/data/settings.yml
```
Conserver les autres réglages existants et vérifier que le fichier contient :
```yaml
use_default_settings: true
search:
formats:
- html
- json
```
Contrôle facultatif du contenu et des fins de ligne :
```sh
sudo cat -A /opt/runtipi/app-data/migrated/searxng/data/settings.yml
```
Redémarrer ensuite l'application **SearXNG**, puis redémarrer **n8n** si sa configuration a également été modifiée.
## Données persistantes
Tout est sous `app-data/<store>/n8n-sandbox/data/` :
- `tls/` : certificats mTLS (contient la clé de la CA, à traiter comme un secret)
- `api/` : base SQLite de l'API
- `runner-state/` : base SQLite du runner
- `runner-docker/` : `/var/lib/docker` du DinD (cache de l'image sandbox, peut peser plusieurs Go ; vidable sans perte)
## Sécurité
- Aucun port n'est publié sur l'hôte. `sandbox-api:8080` est joignable par les autres apps Runtipi via `tipi_main_network`, protégé uniquement par la clé API.
- Le runner est `privileged` : équivalent root sur l'hôte. Ne jamais l'exposer.
- n8n recommande cette stack pour le développement/test et Daytona pour la production.
## Notes
- Les noms `sandbox-api` et `sandbox-runner-1` sont les SAN des certificats : ne pas les renommer.
- Les certificats ne se renouvellent pas seuls. Pour les régénérer, supprimer `data/tls/` et redémarrer l'app.
- L'image sandbox est téléchargée par le runner au premier usage.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

+4 -10
View File
@@ -29,16 +29,10 @@
"readOnly": true "readOnly": true
} }
], ],
"environment": [ "environment": {
{ "NGINX_HOST": "${NGINX_SERVER_NAME:-localhost}",
"key": "NGINX_HOST", "TZ": "${TZ:-Europe/Paris}"
"value": "${NGINX_SERVER_NAME:-localhost}" },
},
{
"key": "TZ",
"value": "${TZ:-Europe/Paris}"
}
],
"healthCheck": { "healthCheck": {
"test": "curl --fail http://localhost:80 || exit 1", "test": "curl --fail http://localhost:80 || exit 1",
"interval": "30s", "interval": "30s",
+46 -160
View File
@@ -9,12 +9,9 @@
"sh", "sh",
"/scripts/init-certs.sh" "/scripts/init-certs.sh"
], ],
"environment": [ "environment": {
{ "CERT_TOOL_VERSION": "4.14"
"key": "CERT_TOOL_VERSION", },
"value": "4.14"
}
],
"volumes": [ "volumes": [
{ {
"hostPath": "${APP_DATA_DIR}/data/config", "hostPath": "${APP_DATA_DIR}/data/config",
@@ -74,48 +71,18 @@
"condition": "service_healthy" "condition": "service_healthy"
} }
}, },
"environment": [ "environment": {
{ "OPENSEARCH_JAVA_OPTS": "-Xms1g -Xmx1g -Dlog4j2.formatMsgNoLookups=true",
"key": "OPENSEARCH_JAVA_OPTS", "DISABLE_INSTALL_DEMO_CONFIG": "true",
"value": "-Xms1g -Xmx1g -Dlog4j2.formatMsgNoLookups=true" "bootstrap.memory_lock": "true",
}, "network.host": "wazuh.indexer",
{ "node.name": "wazuh.indexer",
"key": "DISABLE_INSTALL_DEMO_CONFIG", "cluster.initial_cluster_manager_nodes": "wazuh.indexer",
"value": "true" "node.max_local_storage_nodes": "1",
}, "plugins.security.allow_default_init_securityindex": "true",
{ "NODES_DN": "CN=wazuh.indexer,OU=Wazuh,O=Wazuh,L=California,C=US",
"key": "bootstrap.memory_lock", "plugins.security.ssl.http.clientauth_mode": "OPTIONAL"
"value": "true" },
},
{
"key": "network.host",
"value": "wazuh.indexer"
},
{
"key": "node.name",
"value": "wazuh.indexer"
},
{
"key": "cluster.initial_cluster_manager_nodes",
"value": "wazuh.indexer"
},
{
"key": "node.max_local_storage_nodes",
"value": "1"
},
{
"key": "plugins.security.allow_default_init_securityindex",
"value": "true"
},
{
"key": "NODES_DN",
"value": "CN=wazuh.indexer,OU=Wazuh,O=Wazuh,L=California,C=US"
},
{
"key": "plugins.security.ssl.http.clientauth_mode",
"value": "OPTIONAL"
}
],
"ulimits": { "ulimits": {
"memlock": { "memlock": {
"soft": -1, "soft": -1,
@@ -209,64 +176,22 @@
"condition": "service_healthy" "condition": "service_healthy"
} }
}, },
"environment": [ "environment": {
{ "WAZUH_INDEXER_HOSTS": "wazuh.indexer:9200",
"key": "WAZUH_INDEXER_HOSTS", "WAZUH_NODE_NAME": "manager",
"value": "wazuh.indexer:9200" "WAZUH_NODE_TYPE": "master",
}, "WAZUH_CLUSTER_NODES": "wazuh.manager",
{ "WAZUH_CLUSTER_BIND_ADDR": "wazuh.manager",
"key": "WAZUH_NODE_NAME", "INDEXER_URL": "https://wazuh.indexer:9200",
"value": "manager" "INDEXER_USERNAME": "${INDEXER_USERNAME:-admin}",
}, "INDEXER_PASSWORD": "${INDEXER_PASSWORD:-admin}",
{ "FILEBEAT_SSL_VERIFICATION_MODE": "full",
"key": "WAZUH_NODE_TYPE", "SSL_CERTIFICATE_AUTHORITIES": "/var/ossec/etc/certs/root-ca.pem",
"value": "master" "SSL_CERTIFICATE": "/var/ossec/etc/certs/server.pem",
}, "SSL_KEY": "/var/ossec/etc/certs/server-key.pem",
{ "API_USERNAME": "wazuh-wui",
"key": "WAZUH_CLUSTER_NODES", "API_PASSWORD": "${API_PASSWORD:-MyS3cr37P450r.*-}"
"value": "wazuh.manager" },
},
{
"key": "WAZUH_CLUSTER_BIND_ADDR",
"value": "wazuh.manager"
},
{
"key": "INDEXER_URL",
"value": "https://wazuh.indexer:9200"
},
{
"key": "INDEXER_USERNAME",
"value": "${INDEXER_USERNAME:-admin}"
},
{
"key": "INDEXER_PASSWORD",
"value": "${INDEXER_PASSWORD:-admin}"
},
{
"key": "FILEBEAT_SSL_VERIFICATION_MODE",
"value": "full"
},
{
"key": "SSL_CERTIFICATE_AUTHORITIES",
"value": "/var/ossec/etc/certs/root-ca.pem"
},
{
"key": "SSL_CERTIFICATE",
"value": "/var/ossec/etc/certs/server.pem"
},
{
"key": "SSL_KEY",
"value": "/var/ossec/etc/certs/server-key.pem"
},
{
"key": "API_USERNAME",
"value": "wazuh-wui"
},
{
"key": "API_PASSWORD",
"value": "${API_PASSWORD:-MyS3cr37P450r.*-}"
}
],
"ulimits": { "ulimits": {
"memlock": { "memlock": {
"soft": -1, "soft": -1,
@@ -368,60 +293,21 @@
"condition": "service_healthy" "condition": "service_healthy"
} }
}, },
"environment": [ "environment": {
{ "SERVER_HOST": "0.0.0.0",
"key": "SERVER_HOST", "OPENSEARCH_HOSTS": "https://wazuh.indexer:9200",
"value": "0.0.0.0" "SERVER_SSL_ENABLED": "true",
}, "INDEXER_USERNAME": "${INDEXER_USERNAME:-admin}",
{ "INDEXER_PASSWORD": "${INDEXER_PASSWORD:-admin}",
"key": "OPENSEARCH_HOSTS", "WAZUH_API_URL": "https://wazuh.manager",
"value": "https://wazuh.indexer:9200" "DASHBOARD_USERNAME": "${DASHBOARD_USERNAME:-kibanaserver}",
}, "DASHBOARD_PASSWORD": "${DASHBOARD_PASSWORD:-kibanaserver}",
{ "API_USERNAME": "wazuh-wui",
"key": "SERVER_SSL_ENABLED", "API_PASSWORD": "${API_PASSWORD:-MyS3cr37P450r.*-}",
"value": "true" "SERVER_SSL_CERTIFICATE": "/usr/share/wazuh-dashboard/config/certs/dashboard.pem",
}, "SERVER_SSL_KEY": "/usr/share/wazuh-dashboard/config/certs/dashboard-key.pem",
{ "OPENSEARCH_SSL_CERTIFICATE_AUTHORITIES": "/usr/share/wazuh-dashboard/config/certs/root-ca.pem"
"key": "INDEXER_USERNAME", },
"value": "${INDEXER_USERNAME:-admin}"
},
{
"key": "INDEXER_PASSWORD",
"value": "${INDEXER_PASSWORD:-admin}"
},
{
"key": "WAZUH_API_URL",
"value": "https://wazuh.manager"
},
{
"key": "DASHBOARD_USERNAME",
"value": "${DASHBOARD_USERNAME:-kibanaserver}"
},
{
"key": "DASHBOARD_PASSWORD",
"value": "${DASHBOARD_PASSWORD:-kibanaserver}"
},
{
"key": "API_USERNAME",
"value": "wazuh-wui"
},
{
"key": "API_PASSWORD",
"value": "${API_PASSWORD:-MyS3cr37P450r.*-}"
},
{
"key": "SERVER_SSL_CERTIFICATE",
"value": "/usr/share/wazuh-dashboard/config/certs/dashboard.pem"
},
{
"key": "SERVER_SSL_KEY",
"value": "/usr/share/wazuh-dashboard/config/certs/dashboard-key.pem"
},
{
"key": "OPENSEARCH_SSL_CERTIFICATE_AUTHORITIES",
"value": "/usr/share/wazuh-dashboard/config/certs/root-ca.pem"
}
],
"volumes": [ "volumes": [
{ {
"hostPath": "${APP_DATA_DIR}/data/config/wazuh_ssl_certs", "hostPath": "${APP_DATA_DIR}/data/config/wazuh_ssl_certs",
BIN
View File
Binary file not shown.
+2 -1
View File
@@ -12,7 +12,8 @@
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/bun": "latest", "@types/bun": "latest",
"@types/node": "^22.14.1" "@types/node": "^22.14.1",
"yaml": "2"
}, },
"dependencies": { "dependencies": {
"@runtipi/common": "^0.8.0", "@runtipi/common": "^0.8.0",