Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb8fdc64ba | ||
|
|
349adb2b95 | ||
|
|
cf81405a3f | ||
|
|
95dd642243 | ||
|
|
7df02cccdf |
@@ -65,6 +65,32 @@ describe("each app should have a valid config.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 l’installation>')
|
||||||
|
expect(description).toContain('/opt/runtipi/app-data/migrated/searxng/data/settings.yml')
|
||||||
|
expect(description).toContain('- json')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("modern compose files preserve runtime semantics", () => {
|
describe("modern compose files preserve runtime semantics", () => {
|
||||||
test("n8n-sandbox keeps its one-shot certificate service", async () => {
|
test("n8n-sandbox keeps its one-shot certificate service", async () => {
|
||||||
const fileContent = await getFile('n8n-sandbox', 'docker-compose.yml')
|
const fileContent = await getFile('n8n-sandbox', 'docker-compose.yml')
|
||||||
@@ -74,6 +100,8 @@ describe("modern compose files preserve runtime semantics", () => {
|
|||||||
expect(parsed['x-runtipi']?.schema_version).toBe(2)
|
expect(parsed['x-runtipi']?.schema_version).toBe(2)
|
||||||
expect(parsed.services?.['sandbox-certs']?.restart).toBe('no')
|
expect(parsed.services?.['sandbox-certs']?.restart).toBe('no')
|
||||||
expect(parsed.services?.['sandbox-api']?.['x-runtipi']?.is_main).toBe(true)
|
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')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1,32 +1,79 @@
|
|||||||
# n8n Sandbox Service
|
# 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 :
|
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 |
|
| Service | Rôle |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `sandbox-certs` | Job one-shot : génère la CA privée et les certificats mTLS, puis s'arrête. |
|
| `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-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. |
|
| `sandbox-runner-1` | Docker-in-Docker **privileged** : crée et exécute les conteneurs sandbox. |
|
||||||
|
|
||||||
## Après l'installation
|
## Après l'installation
|
||||||
|
|
||||||
Dans l'app **n8n** (paramètres ou `app.env`), ajouter :
|
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 :
|
||||||
N8N_ENABLED_MODULES=instance-ai
|
|
||||||
N8N_INSTANCE_AI_SANDBOX_ENABLED=true
|
```yaml
|
||||||
N8N_INSTANCE_AI_SANDBOX_PROVIDER=n8n-sandbox
|
# Add your docker-compose overrides here.
|
||||||
N8N_INSTANCE_AI_SANDBOX_IMAGE=n8nio/n8n-sandbox-service-sandbox:1.3.0
|
# The overrides will be merged with the generated docker-compose.yml file.
|
||||||
N8N_SANDBOX_SERVICE_URL=http://sandbox-api:8080
|
|
||||||
N8N_SANDBOX_SERVICE_API_KEY=<valeur du champ « Clé API sandbox »>
|
# 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 l’installation>
|
||||||
```
|
```
|
||||||
|
|
||||||
Puis redémarrer n8n et vérifier depuis son conteneur :
|
Remplacer entièrement `<clé choisie lors de l’installation>` 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
|
||||||
```
|
```
|
||||||
wget -qO- http://sandbox-api:8080/healthz # {"status":"ok"}
|
|
||||||
|
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
|
## Données persistantes
|
||||||
|
|
||||||
Tout est sous `app-data/<store>/n8n-sandbox/data/` :
|
Tout est sous `app-data/<store>/n8n-sandbox/data/` :
|
||||||
|
|||||||
Reference in New Issue
Block a user