InfoGrab DocsInfoGrab Docs

Docker Compose로 설치

요약

이 가이드는 n8n Assistant를 구동하는 샌드박스 스택을 포함하여 직접 Docker Compose 설정을 구성하는 방법을 안내합니다. 이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요. 파일을 직접 작성하지 않고 n8n(및 n8n Assistant)을 빠르게 실행하려면 대신 한 줄 설정을 사용하세요.

대상 독자#

이 가이드는 n8n Assistant를 구동하는 샌드박스 스택을 포함하여 직접 Docker Compose 설정을 구성하는 방법을 안내합니다. 구성을 완전히 제어하고 싶거나 n8n을 기존 Compose 프로젝트에 통합해야 할 때 사용하세요.

참고

이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.

파일을 직접 작성하지 않고 n8n(및 n8n Assistant)을 빠르게 실행하려면 대신 한 줄 설정을 사용하세요. 아래의 모든 항목이 자동으로 설정됩니다.

시작하기 전에 필요한 것#

  • Docker Engine과 Docker Compose v2. docker compose version을 실행하여 확인하세요.
  • 최소 4 GB RAM과 2 vCPU. AI가 생성한 코드를 실행하는 샌드박스(sandbox-runner-1)는 Docker-in-Docker를 사용하므로 일반적인 컨테이너보다 더 많은 여유 자원이 필요합니다.
Note

Windows 사용자: WSL을 사용하고, Docker Desktop(WSL2 백엔드)을 사용하거나 Linux 배포판에 Docker Engine을 직접 설치하세요. 프로젝트 폴더는 /mnt/c/... 아래가 아니라 WSL 파일 시스템 내부(예: ~/n8n)에 두세요. 이 경계를 넘나드는 바인드 마운트는 느리고 권한 문제를 일으킬 수 있습니다.

1단계: 프로젝트 폴더 생성#

mkdir n8n && cd n8n

2단계: .env 생성#

이 파일에는 실행할 버전과 샌드박스 서비스가 서로 통신할 때 사용하는 시크릿이 들어 있습니다. 자리표시자를 사용자 고유의 값으로 바꾼 .env 파일을 생성하고, 이 파일은 버전 관리에서 제외하세요.

# n8n version - get the version number of the latest stable release from https://github.com/n8n-io/n8n/releases
N8N_VERSION=change-me-version-number

# Sandbox service version - the API, runner, and sandbox images share one release.
# Get the number of the latest stable "service" release (not a staging prerelease) from https://github.com/n8n-io/n8n-sandbox-service/releases
N8N_SANDBOX_VERSION=change-me-sandbox-version-number

# n8n task runner authentication. Use a random secret you generate.
N8N_RUNNERS_AUTH_TOKEN=change-me-runner-auth-token

# Sandbox service secrets — pick your own values
SANDBOX_API_KEYS=change-me-api-key
SANDBOX_API_RUNNER_REGISTRATION_TOKEN=change-me-registration-token
SANDBOX_API_RUNNER_API_KEY=change-me-runner-key

# Must match a value in SANDBOX_API_KEYS above — this is how n8n authenticates to the sandbox
N8N_SANDBOX_SERVICE_API_KEY=change-me-api-key

# Web search: secret for the bundled SearXNG instance — pick your own value
SEARXNG_SECRET=change-me-searxng-secret
N8N_INSTANCE_AI_SEARXNG_URL=http://searxng:8080

아직 AI 제공업체 키는 필요하지 않습니다. 모든 것이 실행되면 아래의 n8n Assistant 켜기를 참고하세요.

3단계: searxng-settings.yml 생성#

기본 SearXNG 이미지는 HTML만 제공합니다. n8n의 웹 검색에는 JSON API가 필요하며, 이 파일이 이를 활성화합니다.

use_default_settings: true
search:
  formats:
    - html
    - json

4단계: compose.yml 생성#

여기에서 설정하는 모든 서비스를 정의합니다. n8n 자체, n8n Assistant가 코드를 안전하게 실행할 수 있게 하는 샌드박스 스택, 웹 검색을 위한 SearXNG가 포함됩니다.

방금 설정한 항목#

구성 요소 용도
n8n 워크플로 편집기 자체이며, http://localhost:5678에서 사용할 수 있습니다.
sandbox-certs 다른 샌드박스 서비스에 필요한 TLS 인증서를 생성하기 위해 한 번 실행된 후 종료됩니다.
sandbox-api n8n Assistant가 코드를 실행해야 할 때 n8n이 통신하는 컨트롤 플레인입니다.
sandbox-runner-1 실제 작업을 수행합니다. 샌드박스를 생성하고 실행하는 권한이 있는(privileged) Docker-in-Docker 컨테이너입니다.
searxng n8n Assistant용으로 번들된 웹 검색 백엔드입니다.

여기에는 n8n 자체 샌드박스(n8n-sandbox)가 번들되어 있으며, 로컬 개발과 테스트에 적합합니다. 프로덕션 인스턴스에서는 현재 n8n이 대신 Daytona를 샌드박스 제공업체로 권장합니다. Daytona 샌드박스를 구성하는 방법은 n8n Assistant 설정을 참고하세요.

여기에는 데이터베이스 서비스가 정의되어 있지 않습니다. n8n은 내장 SQLite 데이터베이스를 사용하며, 볼륨을 마운트하지 않으면 컨테이너 내부에 저장됩니다. 프로덕션 인스턴스에서는 Postgres로 교체하세요. 아래의 SQLite 대신 PostgreSQL 사용을 참고하세요.

5단계: 모두 시작#

docker compose up -d
docker compose ps

sandbox-api가 healthy로 표시될 때까지 기다립니다. 그러면 sandbox-runner-1과 n8n이 자동으로 시작됩니다.

6단계: 작동 확인#

# sandbox-api is reachable from n8n
docker compose exec n8n wget -qO- http://sandbox-api:8080/healthz

# the runner registered itself with the API
docker compose logs sandbox-api | grep -i runner

# n8n is up
curl -sf http://localhost:5678/healthz

웹 브라우저에서 http://localhost:5678로 접속하여 n8n을 실행합니다.

선택 사항: n8n Assistant 켜기#

위의 모든 과정은 전체 샌드박스 스택을 실행하지만, n8n Assistant 자체는 사용할 모델을 지정하기 전까지 꺼져 있습니다. n8n이 실행된 후 n8n UI(인스턴스의 AI 설정)에서 설정할 수 있으며, 첫 로그인 전에 구성하려면 .env를 사용할 수도 있습니다.

  1. AI 제공업체 키를 .env에 추가합니다.

    N8N_INSTANCE_AI_MODEL_API_KEY=sk-ant-xxx
    
  2. 변경 사항을 반영하도록 n8n을 재시작합니다.

    docker compose up -d n8n
    

웹 검색은 기본적으로 번들된 SearXNG 서비스를 통해 실행됩니다. 대신 Brave Search를 사용하려면 UI에서 설정하거나 Brave API 키를 .env에 추가하세요. 설정하면 SearXNG보다 우선합니다.

INSTANCE_AI_BRAVE_SEARCH_API_KEY=BSA-xxx

지원되는 모델 제공업체를 포함한 전체 설정 단계는 n8n Assistant 설정에 있습니다.

선택 사항: SQLite 대신 PostgreSQL 사용#

SQLite는 시험 삼아 사용하기에는 충분하지만, 소수의 사용자를 넘어서거나 워크플로가 24시간 실행되어야 하는 프로덕션 인스턴스에서는 대신 Postgres를 사용하세요.

  1. 샌드박스 시크릿과 함께 Postgres 자격 증명을 .env에 추가합니다.

    POSTGRES_USER=change-me-user
    POSTGRES_PASSWORD=change-me-password
    POSTGRES_DB=n8n
    
  2. compose.yml에 postgres 서비스와 해당 데이터용 볼륨을 추가합니다.

    volumes:
      db-storage:
    
    services:
      postgres:
        image: postgres:18
        restart: always
        environment:
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
          PGDATA: /var/lib/postgresql/data
        volumes:
          - db-storage:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
          interval: 5s
          timeout: 5s
          retries: 10
    

    Postgres 18은 기본 데이터 저장 위치가 변경되었습니다. `PGDATA`를 설정하면 이전 버전과 같은 폴더에 유지되므로 볼륨 마운트가 그대로 유지됩니다. 이 줄을 제거하지 마세요. 제거하면 Postgres 18이 볼륨이 포함하지 않는 위치에 데이터를 기록하여 데이터베이스가 빈 상태로 시작됩니다.

    이전 버전의 Postgres를 이미 실행 중인가요? 18로 바로 이동하는 것은 메이저 버전 업그레이드이며, Postgres는 이전 메이저 버전이 기록한 데이터 디렉터리를 열 수 없습니다. 기존 설정에서 이미지 태그만 올리면 `database files are incompatible with server` 오류로 실패합니다. 데이터는 손상되지 않습니다. 먼저 `pg_dumpall`로 백업한 다음 공식 [PostgreSQL 업그레이드 가이드](https://www.postgresql.org/docs/18/upgrading.html)를 따르세요.

  3. n8n 서비스의 environment 블록에 다음을 추가하여 n8n이 Postgres를 사용하도록 지정하고, Postgres도 기다리도록 설정합니다.

    environment:
          # ...your existing N8N_ENABLED_MODULES, N8N_INSTANCE_AI_* settings stay as they are
          DB_TYPE: postgresdb
          DB_POSTGRESDB_HOST: postgres
          DB_POSTGRESDB_PORT: '5432'
          DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
          DB_POSTGRESDB_USER: ${POSTGRES_USER}
          DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      depends_on:
        sandbox-api:
          condition: service_healthy
        postgres:
          condition: service_healthy
    
  4. 모두 재시작합니다.

    docker compose up -d
    

    n8n은 시작할 때 새 Postgres 데이터베이스로 스스로 마이그레이션합니다. 기존 SQLite 데이터는 자동으로 이전되지 않습니다. 이 설정은 새 인스턴스를 위한 것이며, 제자리 마이그레이션을 위한 것이 아닙니다.

    비루트 전용 Postgres 사용자와 외부 태스크 러너 같은 더 강화된 설정은 n8n 호스팅 리포지터리의 [`withPostgres` 예제](https://github.com/n8n-io/n8n-hosting/tree/main/docker-compose/withPostgres)를 참고하세요.

문제 해결#

증상 추정 원인
sandbox-api 또는 sandbox-runner-1이 시작되지 않고 인증서 오류가 발생함 sandbox-certs가 완료되지 않았습니다. docker compose logs sandbox-certs를 확인하세요.
sandbox-api가 healthy가 되지 않음 로그를 확인하고, 해당 이미지에 wget이 실제로 있는지도 확인하세요.
sandbox-runner-1이 시작 시 ... must be set 오류와 함께 반복적으로 충돌함 필수 환경 변수가 없습니다. 가장 흔한 경우는 SANDBOX_RUNNER_API_KEYS 또는 SANDBOX_RUNNER_REGISTRATION_TOKEN입니다. 러너에 필요한 환경 변수의 전체 목록은 러너 컨테이너 내부에서 strings /usr/local/bin/sandbox-runner | grep -oE 'SANDBOX_[A-Z_]+ must be set' 를 실행하여 확인하세요.
러너가 API에 등록되지 않음 SANDBOX_RUNNER_REGISTRATION_TOKEN이 일치하지 않거나 SANDBOX_RUNNER_API_GRPC_ADDR가 잘못되었습니다.
n8n의 샌드박스 호출이 실패함 .env의 샌드박스 URL/키가 sandbox-api의 주소 또는 SANDBOX_API_KEYS와 일치하지 않습니다.
Linux에서는 작동하지만 WSL에서는 실패함 대개 바인드 마운트 경로 문제입니다. 프로젝트를 /mnt/c/...가 아닌 WSL 파일 시스템 내부에 두세요.

보안 체크리스트#

  • sandbox-runner-1(privileged: true, Docker-in-Docker)은 절대 공용 인터넷에 노출되지 않습니다. 호스트의 root와 동등하게 취급하세요.
  • 클라우드 방화벽에서는 n8n의 포트만 열려 있습니다.
  • SANDBOX_API_KEYS, 등록 토큰, 러너 키는 고유한 값이며 change-me-...로 남겨 두지 않고 주기적으로 교체합니다.
  • sandbox-api와 sandbox-runner-1은 env_file: .env를 사용하지 않습니다. 각각 필요한 특정 변수만 environment 블록에서 명시적으로 받습니다. 모델 API 키, Brave 키, Postgres 비밀번호, n8n 암호화 키는 샌드박스 컨테이너에 전달되지 않습니다.
  • sandbox-tls 볼륨 아래의 mTLS 키는 루트 CA 키를 포함하여 0600으로 제한되며, 해당 키가 필요한 서비스만 소유합니다(자체 키는 sandbox-api, 러너 키와 CA 키는 root). 어느 것도 모든 사용자가 읽을 수 없습니다.
  • sandbox-tls 볼륨을 다시 생성할 계획이 있습니다. sandbox-certs가 생성하는 인증서는 자동으로 갱신되지 않습니다.

서비스 아키텍처#

Mermaid 다이어그램 (17줄)
소스 코드 보기
flowchart LR
    subgraph compose["docker-compose.yml (one project)"]
        n8n["n8n"]
        certs["sandbox-certs<br/>(runs once, then exits)"]
        api["sandbox-api"]
        runner["sandbox-runner-1<br/>(privileged, DinD)"]
        sandboxes["sandbox containers<br/>(per execution)"]
    certs -.-&gt;|TLS certs| api
    certs -.-&gt;|TLS certs| runner
    n8n --&gt;|HTTP :8080| api
    api --&gt;|control gRPC| runner
    runner --&gt; sandboxes
end

classDef oneshot fill:#eee,stroke:#999,stroke-dasharray: 3 3;
class certs oneshot</code></pre></details></div>

n8n은 코드 실행 요청을 sandbox-api로 보내고, sandbox-api는 이를 sandbox-runner-1에 전달하며, sandbox-runner-1이 실제 샌드박스 컨테이너를 생성하고 실행합니다. sandbox-certs는 시작할 때 한 번 실행되어 나머지 둘에 필요한 TLS 인증서를 생성한 후 종료되며, 나머지는 모두 이를 기다립니다.

관련 리소스#

Docker Compose로 설치

n8n v2.42
원문 보기

요약

이 가이드는 n8n Assistant를 구동하는 샌드박스 스택을 포함하여 직접 Docker Compose 설정을 구성하는 방법을 안내합니다. 이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요. 파일을 직접 작성하지 않고 n8n(및 n8n Assistant)을 빠르게 실행하려면 대신 한 줄 설정을 사용하세요.

대상 독자#

이 가이드는 n8n Assistant를 구동하는 샌드박스 스택을 포함하여 직접 Docker Compose 설정을 구성하는 방법을 안내합니다. 구성을 완전히 제어하고 싶거나 n8n을 기존 Compose 프로젝트에 통합해야 할 때 사용하세요.

참고

이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.

파일을 직접 작성하지 않고 n8n(및 n8n Assistant)을 빠르게 실행하려면 대신 한 줄 설정을 사용하세요. 아래의 모든 항목이 자동으로 설정됩니다.

시작하기 전에 필요한 것#

  • Docker Engine과 Docker Compose v2. docker compose version을 실행하여 확인하세요.
  • 최소 4 GB RAM과 2 vCPU. AI가 생성한 코드를 실행하는 샌드박스(sandbox-runner-1)는 Docker-in-Docker를 사용하므로 일반적인 컨테이너보다 더 많은 여유 자원이 필요합니다.
Note

Windows 사용자: WSL을 사용하고, Docker Desktop(WSL2 백엔드)을 사용하거나 Linux 배포판에 Docker Engine을 직접 설치하세요. 프로젝트 폴더는 /mnt/c/... 아래가 아니라 WSL 파일 시스템 내부(예: ~/n8n)에 두세요. 이 경계를 넘나드는 바인드 마운트는 느리고 권한 문제를 일으킬 수 있습니다.

1단계: 프로젝트 폴더 생성#

mkdir n8n && cd n8n

2단계: .env 생성#

이 파일에는 실행할 버전과 샌드박스 서비스가 서로 통신할 때 사용하는 시크릿이 들어 있습니다. 자리표시자를 사용자 고유의 값으로 바꾼 .env 파일을 생성하고, 이 파일은 버전 관리에서 제외하세요.

# n8n version - get the version number of the latest stable release from https://github.com/n8n-io/n8n/releases
N8N_VERSION=change-me-version-number

# Sandbox service version - the API, runner, and sandbox images share one release.
# Get the number of the latest stable "service" release (not a staging prerelease) from https://github.com/n8n-io/n8n-sandbox-service/releases
N8N_SANDBOX_VERSION=change-me-sandbox-version-number

# n8n task runner authentication. Use a random secret you generate.
N8N_RUNNERS_AUTH_TOKEN=change-me-runner-auth-token

# Sandbox service secrets — pick your own values
SANDBOX_API_KEYS=change-me-api-key
SANDBOX_API_RUNNER_REGISTRATION_TOKEN=change-me-registration-token
SANDBOX_API_RUNNER_API_KEY=change-me-runner-key

# Must match a value in SANDBOX_API_KEYS above — this is how n8n authenticates to the sandbox
N8N_SANDBOX_SERVICE_API_KEY=change-me-api-key

# Web search: secret for the bundled SearXNG instance — pick your own value
SEARXNG_SECRET=change-me-searxng-secret
N8N_INSTANCE_AI_SEARXNG_URL=http://searxng:8080

아직 AI 제공업체 키는 필요하지 않습니다. 모든 것이 실행되면 아래의 n8n Assistant 켜기를 참고하세요.

3단계: searxng-settings.yml 생성#

기본 SearXNG 이미지는 HTML만 제공합니다. n8n의 웹 검색에는 JSON API가 필요하며, 이 파일이 이를 활성화합니다.

use_default_settings: true
search:
  formats:
    - html
    - json

4단계: compose.yml 생성#

여기에서 설정하는 모든 서비스를 정의합니다. n8n 자체, n8n Assistant가 코드를 안전하게 실행할 수 있게 하는 샌드박스 스택, 웹 검색을 위한 SearXNG가 포함됩니다.

방금 설정한 항목#

구성 요소 용도
n8n 워크플로 편집기 자체이며, http://localhost:5678에서 사용할 수 있습니다.
sandbox-certs 다른 샌드박스 서비스에 필요한 TLS 인증서를 생성하기 위해 한 번 실행된 후 종료됩니다.
sandbox-api n8n Assistant가 코드를 실행해야 할 때 n8n이 통신하는 컨트롤 플레인입니다.
sandbox-runner-1 실제 작업을 수행합니다. 샌드박스를 생성하고 실행하는 권한이 있는(privileged) Docker-in-Docker 컨테이너입니다.
searxng n8n Assistant용으로 번들된 웹 검색 백엔드입니다.

여기에는 n8n 자체 샌드박스(n8n-sandbox)가 번들되어 있으며, 로컬 개발과 테스트에 적합합니다. 프로덕션 인스턴스에서는 현재 n8n이 대신 Daytona를 샌드박스 제공업체로 권장합니다. Daytona 샌드박스를 구성하는 방법은 n8n Assistant 설정을 참고하세요.

여기에는 데이터베이스 서비스가 정의되어 있지 않습니다. n8n은 내장 SQLite 데이터베이스를 사용하며, 볼륨을 마운트하지 않으면 컨테이너 내부에 저장됩니다. 프로덕션 인스턴스에서는 Postgres로 교체하세요. 아래의 SQLite 대신 PostgreSQL 사용을 참고하세요.

5단계: 모두 시작#

docker compose up -d
docker compose ps

sandbox-api가 healthy로 표시될 때까지 기다립니다. 그러면 sandbox-runner-1과 n8n이 자동으로 시작됩니다.

6단계: 작동 확인#

# sandbox-api is reachable from n8n
docker compose exec n8n wget -qO- http://sandbox-api:8080/healthz

# the runner registered itself with the API
docker compose logs sandbox-api | grep -i runner

# n8n is up
curl -sf http://localhost:5678/healthz

웹 브라우저에서 http://localhost:5678로 접속하여 n8n을 실행합니다.

선택 사항: n8n Assistant 켜기#

위의 모든 과정은 전체 샌드박스 스택을 실행하지만, n8n Assistant 자체는 사용할 모델을 지정하기 전까지 꺼져 있습니다. n8n이 실행된 후 n8n UI(인스턴스의 AI 설정)에서 설정할 수 있으며, 첫 로그인 전에 구성하려면 .env를 사용할 수도 있습니다.

  1. AI 제공업체 키를 .env에 추가합니다.

    N8N_INSTANCE_AI_MODEL_API_KEY=sk-ant-xxx
    
  2. 변경 사항을 반영하도록 n8n을 재시작합니다.

    docker compose up -d n8n
    

웹 검색은 기본적으로 번들된 SearXNG 서비스를 통해 실행됩니다. 대신 Brave Search를 사용하려면 UI에서 설정하거나 Brave API 키를 .env에 추가하세요. 설정하면 SearXNG보다 우선합니다.

INSTANCE_AI_BRAVE_SEARCH_API_KEY=BSA-xxx

지원되는 모델 제공업체를 포함한 전체 설정 단계는 n8n Assistant 설정에 있습니다.

선택 사항: SQLite 대신 PostgreSQL 사용#

SQLite는 시험 삼아 사용하기에는 충분하지만, 소수의 사용자를 넘어서거나 워크플로가 24시간 실행되어야 하는 프로덕션 인스턴스에서는 대신 Postgres를 사용하세요.

  1. 샌드박스 시크릿과 함께 Postgres 자격 증명을 .env에 추가합니다.

    POSTGRES_USER=change-me-user
    POSTGRES_PASSWORD=change-me-password
    POSTGRES_DB=n8n
    
  2. compose.yml에 postgres 서비스와 해당 데이터용 볼륨을 추가합니다.

    volumes:
      db-storage:
    
    services:
      postgres:
        image: postgres:18
        restart: always
        environment:
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
          PGDATA: /var/lib/postgresql/data
        volumes:
          - db-storage:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
          interval: 5s
          timeout: 5s
          retries: 10
    

    Postgres 18은 기본 데이터 저장 위치가 변경되었습니다. `PGDATA`를 설정하면 이전 버전과 같은 폴더에 유지되므로 볼륨 마운트가 그대로 유지됩니다. 이 줄을 제거하지 마세요. 제거하면 Postgres 18이 볼륨이 포함하지 않는 위치에 데이터를 기록하여 데이터베이스가 빈 상태로 시작됩니다.

    이전 버전의 Postgres를 이미 실행 중인가요? 18로 바로 이동하는 것은 메이저 버전 업그레이드이며, Postgres는 이전 메이저 버전이 기록한 데이터 디렉터리를 열 수 없습니다. 기존 설정에서 이미지 태그만 올리면 `database files are incompatible with server` 오류로 실패합니다. 데이터는 손상되지 않습니다. 먼저 `pg_dumpall`로 백업한 다음 공식 [PostgreSQL 업그레이드 가이드](https://www.postgresql.org/docs/18/upgrading.html)를 따르세요.

  3. n8n 서비스의 environment 블록에 다음을 추가하여 n8n이 Postgres를 사용하도록 지정하고, Postgres도 기다리도록 설정합니다.

    environment:
          # ...your existing N8N_ENABLED_MODULES, N8N_INSTANCE_AI_* settings stay as they are
          DB_TYPE: postgresdb
          DB_POSTGRESDB_HOST: postgres
          DB_POSTGRESDB_PORT: '5432'
          DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
          DB_POSTGRESDB_USER: ${POSTGRES_USER}
          DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      depends_on:
        sandbox-api:
          condition: service_healthy
        postgres:
          condition: service_healthy
    
  4. 모두 재시작합니다.

    docker compose up -d
    

    n8n은 시작할 때 새 Postgres 데이터베이스로 스스로 마이그레이션합니다. 기존 SQLite 데이터는 자동으로 이전되지 않습니다. 이 설정은 새 인스턴스를 위한 것이며, 제자리 마이그레이션을 위한 것이 아닙니다.

    비루트 전용 Postgres 사용자와 외부 태스크 러너 같은 더 강화된 설정은 n8n 호스팅 리포지터리의 [`withPostgres` 예제](https://github.com/n8n-io/n8n-hosting/tree/main/docker-compose/withPostgres)를 참고하세요.

문제 해결#

증상 추정 원인
sandbox-api 또는 sandbox-runner-1이 시작되지 않고 인증서 오류가 발생함 sandbox-certs가 완료되지 않았습니다. docker compose logs sandbox-certs를 확인하세요.
sandbox-api가 healthy가 되지 않음 로그를 확인하고, 해당 이미지에 wget이 실제로 있는지도 확인하세요.
sandbox-runner-1이 시작 시 ... must be set 오류와 함께 반복적으로 충돌함 필수 환경 변수가 없습니다. 가장 흔한 경우는 SANDBOX_RUNNER_API_KEYS 또는 SANDBOX_RUNNER_REGISTRATION_TOKEN입니다. 러너에 필요한 환경 변수의 전체 목록은 러너 컨테이너 내부에서 strings /usr/local/bin/sandbox-runner | grep -oE 'SANDBOX_[A-Z_]+ must be set' 를 실행하여 확인하세요.
러너가 API에 등록되지 않음 SANDBOX_RUNNER_REGISTRATION_TOKEN이 일치하지 않거나 SANDBOX_RUNNER_API_GRPC_ADDR가 잘못되었습니다.
n8n의 샌드박스 호출이 실패함 .env의 샌드박스 URL/키가 sandbox-api의 주소 또는 SANDBOX_API_KEYS와 일치하지 않습니다.
Linux에서는 작동하지만 WSL에서는 실패함 대개 바인드 마운트 경로 문제입니다. 프로젝트를 /mnt/c/...가 아닌 WSL 파일 시스템 내부에 두세요.

보안 체크리스트#

  • sandbox-runner-1(privileged: true, Docker-in-Docker)은 절대 공용 인터넷에 노출되지 않습니다. 호스트의 root와 동등하게 취급하세요.
  • 클라우드 방화벽에서는 n8n의 포트만 열려 있습니다.
  • SANDBOX_API_KEYS, 등록 토큰, 러너 키는 고유한 값이며 change-me-...로 남겨 두지 않고 주기적으로 교체합니다.
  • sandbox-api와 sandbox-runner-1은 env_file: .env를 사용하지 않습니다. 각각 필요한 특정 변수만 environment 블록에서 명시적으로 받습니다. 모델 API 키, Brave 키, Postgres 비밀번호, n8n 암호화 키는 샌드박스 컨테이너에 전달되지 않습니다.
  • sandbox-tls 볼륨 아래의 mTLS 키는 루트 CA 키를 포함하여 0600으로 제한되며, 해당 키가 필요한 서비스만 소유합니다(자체 키는 sandbox-api, 러너 키와 CA 키는 root). 어느 것도 모든 사용자가 읽을 수 없습니다.
  • sandbox-tls 볼륨을 다시 생성할 계획이 있습니다. sandbox-certs가 생성하는 인증서는 자동으로 갱신되지 않습니다.

서비스 아키텍처#

Mermaid 다이어그램 (17줄)
소스 코드 보기
flowchart LR
    subgraph compose["docker-compose.yml (one project)"]
        n8n["n8n"]
        certs["sandbox-certs<br/>(runs once, then exits)"]
        api["sandbox-api"]
        runner["sandbox-runner-1<br/>(privileged, DinD)"]
        sandboxes["sandbox containers<br/>(per execution)"]
    certs -.-&gt;|TLS certs| api
    certs -.-&gt;|TLS certs| runner
    n8n --&gt;|HTTP :8080| api
    api --&gt;|control gRPC| runner
    runner --&gt; sandboxes
end

classDef oneshot fill:#eee,stroke:#999,stroke-dasharray: 3 3;
class certs oneshot</code></pre></details></div>

n8n은 코드 실행 요청을 sandbox-api로 보내고, sandbox-api는 이를 sandbox-runner-1에 전달하며, sandbox-runner-1이 실제 샌드박스 컨테이너를 생성하고 실행합니다. sandbox-certs는 시작할 때 한 번 실행되어 나머지 둘에 필요한 TLS 인증서를 생성한 후 종료되며, 나머지는 모두 이를 기다립니다.

관련 리소스#