n8n Worker 설정: Docker Compose로 확장 가능한 프로덕션 환경 구축

n8n Worker 설정: Docker Compose로 확장 가능한 프로덕션 환경 구축

n8n으로 업무 자동화 워크플로우를 운영하다 보면, 어느 순간 ‘큐 모드(Queue Mode)’와 ‘Worker’라는 개념이 반드시 필요해지는 시점이 찾아옵니다. 초기에는 메인 프로세스 하나로 충분하지만, 워크플로우가 늘어나고 실행 빈도가 높아지면 단일 인스턴스로는 처리 속도가 느려지거나, 예약 작업이 밀리는 병목 현상이 발생하기 마련입니다. 특히 프로덕션 환경에서 n8n을 운영 중이라면 단순히 ‘동작하는 것’을 넘어 ‘확장 가능한 구조’를 고민해야 합니다. 이 글에서는 Docker Compose 구성을 기반으로, n8n Worker를 추가하여 워크플로우 처리 성능을 확장할 수 있는 실전적인 프로덕션 환경 구축 방법을 단계별로 다루겠습니다.

📌 핵심 요약 (TL;DR)
– n8n Worker는 메인 프로세스와 분리되어 워크플로우 실행만 담당하는 ‘실행 노드’입니다.
– Docker Compose 환경에서 QUEUE_MODE=true 설정과 Redis를 결합하면 손쉽게 Worker를 추가할 수 있습니다.
– Worker 수를 늘리면 처리 성능을 확장할 수 있으며, 배포 시 무중단 업데이트도 가능해집니다.
– AWS ECS/Fargate 등 완전관리형 환경을 활용하면 운영 부담을 줄일 수 있습니다.

1. 왜 n8n Worker가 필요한가? (단일 인스턴스의 한계)

기본적인 n8n 설치 방식은 모든 워크플로우 실행을 메인 컨테이너 내부의 스레드에서 처리합니다. 개발 단계나 트래픽이 적은 환경에서는 큰 문제가 없지만, 프로덕션에서는 다음과 같은 중요한 이슈가 발생합니다.

첫째, 실행 시간 초과(Timeout) 문제입니다. 예를 들어 대용량 CSV나 이미지를 처리하는 워크플로우가 오래 실행되는 동안 다른 워크플로우의 요청이 대기하면서 전체적인 응답 속도가 저하될 수 있습니다. 둘째, 예약 작업(Schedule) 지연입니다. 5분마다 실행되는 크론잡이 많을수록 단일 프로세스가 감당해야 할 부하가 과중해집니다. 셋째, 배포 전략의 한계입니다. 코드를 업데이트하기 위해 컨테이너를 재시작하면 실행 중이던 워크플로우가 모두 중단될 수 있습니다.

이를 해결하는 방법이 바로 n8n Worker를 분리하여 운영하는 아키텍처입니다. Worker는 메인 프로세스(Webhook 및 UI 담당)와 분리되어, Redis 큐에서 작업 메시지를 가져와 자신의 컨테이너 안에서 실행합니다. 이 구조 덕분에 Worker 수를 늘리는 방식으로 성능 확장이 가능해집니다.

2. Docker Compose 기반 n8n Worker 환경 설계

n8n Worker를 운영하기 위한 핵심은 QUEUE_MODE 환경 변수를 활성화하고, 작업 큐 역할을 할 Redis를 함께 구성하는 것입니다. 아래는 가장 보편적으로 사용되는 Docker Compose 기본 구조입니다.

services:
  n8n-main:
    image: n8nio/n8n
    environment:
      - N8N_MODE=queue
      - QUEUE_MODE=true
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=n8n-db
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=your_password
      - N8N_REDIS_HOST=redis
      - N8N_REDIS_PORT=6379
    ports:
      - '5678:5678'
    depends_on:
      - redis
      - n8n-db

  n8n-worker:
    image: n8nio/n8n
    command: ['n8n', 'worker']
    environment:
      - N8N_MODE=queue
      - QUEUE_MODE=true
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=n8n-db
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=your_password
      - N8N_REDIS_HOST=redis
      - N8N_REDIS_PORT=6379
    depends_on:
      - redis
      - n8n-main

  redis:
    image: redis:7-alpine
    restart: unless-stopped

  n8n-db:
    image: postgres:15
    environment:
      - POSTGRES_DB=n8n
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=your_password

위 구조에서 n8n-worker 컨테이너가 핵심 확장 유닛입니다. docker compose up –scale n8n-worker=3 명령어를 사용하면 동일한 Worker 컨테이너를 3개로 복제하여 병렬 처리 효과를 얻을 수 있습니다. 다만 이때 주의할 점은, 모든 Worker가 동일한 볼륨(로컬 파일 시스템)을 공유해야 한다는 것입니다. 예를 들어 워크플로우에서 /data 폴더에 파일을 저장한다면 로컬 볼륨이 아닌 NFS, EFS, S3 등 공유 스토리지로 연결해야 합니다. 또한 DB 패스워드와 같은 민감 정보는 Docker Secrets 또는 .env 파일로 분리해 관리하는 것이 안전합니다.

3. Worker 확장 운영 전략 및 성능 비교

Worker 수는 무작정 늘린다고 좋은 것이 아닙니다. DB 커넥션 풀과 Redis 처리량을 고려하여 적절한 수준으로 유지해야 합니다. 아래 표는 동일한 조건의 테스트 워크플로우를 기준으로 한 예시 비교입니다. 실제 수치는 워크플로우의 크기와 인프라 성능에 따라 달라질 수 있습니다.

구성 방식 CPU 코어 사용 실행 시간 예시 (100개 워크플로우) 운영 난이도 무중단 배포
단일 인스턴스 1 코어 12분 30초 ⭐ (낮음) 불가능
Worker 2개 2 코어 6분 15초 ⭐⭐⭐ (보통) 가능
Worker 4개 4 코어 3분 20초 ⭐⭐⭐ (보통) 가능
AWS ECS Fargate (자동 확장) 가변적 부하에 따라 자동 조정 ⭐⭐⭐⭐ (높음) 가능

예시 환경에서는 Worker 수를 2배로 늘리면 처리 시간이 약 절반 수준으로 줄어드는 경향을 보입니다. 다만 Worker가 4개를 초과하면 DB와 Redis가 병목이 될 수 있으므로, 단순히 Worker만 확장하기보다 Redis 클러스터링과 DB 커넥션 풀 증가를 함께 검토해야 합니다.

4. 프로덕션 배포 시 필수 설정 (오류 방지 가이드)

프로덕션에서 n8n Worker가 제대로 동작하지 못하는 가장 흔한 원인은 첫째, 잘못된 환경변수 누락이고 둘째, 공유 볼륨 미설정입니다. 아래 체크리스트를 확인하세요.

첫 번째로 N8N_ENCRYPTION_KEY를 모든 컨테이너에 동일하게 설정해야 합니다. 이 키는 자격증명(Credential)을 암호화하는 데 사용되며, Worker에서 다른 키를 사용하면 복호화에 실패하여 모든 인증이 깨질 수 있습니다. 두 번째로 EXECUTIONS_MODE=queue로 명시적으로 지정하여 실행 기록이 DB에 올바르게 저장되도록 해야 합니다.

또한 로드밸런서(엔진엑스, ALB 등)를 사용할 때는 Webhook URL을 외부 호스트로 고정해야 합니다. 환경 변수 N8N_HOSTN8N_PROTOCOL을 설정하지 않으면 웹훅 호출 시 내부 IP로 요청이 전달되어 동작하지 않을 수 있습니다. 아래와 같이 설정하는 것을 권장합니다.

environment:
  - N8N_HOST=your-domain.com
  - N8N_PROTOCOL=https
  - WEBHOOK_URL=https://your-domain.com/
  - N8N_ENCRYPTION_KEY=your-strong-encryption-key
  - EXECUTIONS_MODE=queue
  - N8N_RUNNERS_ENABLED=true

위 설정 중 N8N_RUNNERS_ENABLED=true는 최신 n8n 버전에서 코드 실행 노드(Code Node)를 별도 프로세스로 분리해 장시간 실행되는 코드가 Worker 전체를 블로킹하지 않도록 돕는 옵션입니다. Worker와 함께 사용하면 병렬 처리 효율이 높아질 수 있습니다.

5. Redis 및 DB 튜닝을 통한 Worker 성능 최적화

아무리 Worker를 많이 늘려도 Redis에 장애가 발생하면 전체 시스템이 멈출 수 있습니다. Redis는 단순한 캐시가 아닌 n8n의 작업 큐(Message Broker)이기 때문입니다. 프로덕션 환경에서는 Redis 설정을 다음과 같이 변경하는 것이 좋습니다.

첫째, Redis 컨테이너에 –appendonly yes 옵션을 추가하여 AOF 지속성을 활성화합니다. 이러면 Worker가 작업을 가져간 후 Redis가 재시작되더라도 데이터가 유실되지 않습니다. 둘째, maxmemory 정책을 noeviction으로 설정해 메모리가 가득 찼을 때 작업 큐 데이터가 임의로 삭제되는 일이 없도록 하는 것이 안전합니다. 단, 메모리가 가득 차면 새 작업이 거부될 수 있으므로 Redis 메모리 사용량을 모니터링하고 maxmemory를 적절히 늘려야 합니다. 셋째, DB(PostgreSQL)는 커넥션 수를 기본값 10에서 50 이상으로 증가시키는 것이 좋습니다.

다음은 Redis와 DB의 최적 설정 예시입니다.

redis:
  image: redis:7-alpine
  command: >
    redis-server
    --appendonly yes
    --maxmemory 256mb
    --maxmemory-policy noeviction
  volumes:
    - redis-data:/data

n8n-db:
  image: postgres:15
  environment:
    - POSTGRES_DB=n8n
    - POSTGRES_USER=n8n
    - POSTGRES_PASSWORD=your_password
  command: >
    postgres
    -c max_connections=100
    -c shared_buffers=256MB
  volumes:
    - db-data:/var/lib/postgresql/data

Redis AOF 지속성을 활성화해 두면 Worker가 작업을 가져간 후 Redis가 재시작되더라도 작업 데이터를 보존할 수 있으며, DB 커넥션 풀을 넉넉히 설정하면 Worker가 많아져도 연결 부족으로 인한 실행 실패 가능성을 줄일 수 있습니다. 다만 실제 효과는 n8n 버전, 워크플로우 규모, 인프라 자원에 따라 달라질 수 있습니다.

6. 무중단 업데이트 및 배포 전략

n8n을 업데이트할 때 기존 방식은 전체 컨테이너를 중지하고 재시작하는 것이었습니다. 그러나 Worker 아키텍처에서는 롤링 업데이트(Rolling Update) 전략을 사용할 수 있습니다.

전략은 간단합니다. 메인 컨테이너는 UI와 웹훅만 담당하므로 잠시 재시작해도 실행 중인 워크플로우에 영향이 없습니다. 모든 워크플로우 실행은 Worker가 처리하기 때문입니다. 따라서 docker compose up -d –no-deps n8n-main 으로 메인을 먼저 업데이트하고, 이후 docker compose up -d –scale n8n-worker=2 과 같은 방식으로 Worker를 하나씩 교체하거나 새 버전으로 이미지를 교체하면 됩니다.

이때 중요한 점은 현재 실행 중인 워크플로우가 종료될 때까지 충분한 Grace Period를 설정해야 한다는 것입니다. Docker Compose에서는 stop_grace_period 옵션을 이용하여 컨테이너가 종료되기 전에 현재 작업을 마무리할 시간을 부여할 수 있습니다. 다음 설정을 참고하세요.

services:
  n8n-worker:
    image: n8nio/n8n
    stop_grace_period: 60s
    command: ['n8n', 'worker']
    # ... 나머지 환경변수

위처럼 설정하면 Worker에 SIGTERM 시그널이 전달된 후에도 최대 60초 동안 현재 진행 중인 작업을 완료하고 안전하게 종료됩니다. 이 기법을 사용하면 n8n 업데이트로 인한 워크플로우 중단 가능성을 크게 줄일 수 있습니다.

7. 결론: 작게 시작해서 유연하게 확장하라

n8n Worker와 Docker Compose의 조합은 생각보다 어렵지 않으면서도 큰 운영 이점을 제공합니다. 처음부터 대규모 인프라를 만들 필요 없이, 먼저 Worker를 1개만 추가하여 큐 모드가 정상 동작하는지 검증하는 것에서 시작하시기 바랍니다. 이후 워크플로우의 실행 시간을 모니터링하면서 Worker의 개수를 점진적으로 늘려가면 됩니다.

만약 직접 서버를 관리할 시간적인 여유가 없고, 자동 확장(Auto-scaling)과 완전관리형 인프라를 원하신다면, 앞서 소개한 AWS ECS 또는 Fargate로 전환하는 것도 좋은 대안이 될 수 있습니다. ECS는 오토스케일링이 내장되어 있어 특정 시간대에 워크플로우가 몰리는 환경에서 비용을 절감하면서도 성능을 유지하는 데 유리합니다.

마지막으로, 어떤 환경을 선택하든 데이터베이스 백업과 Redis 모니터링은 필수입니다. n8n Worker 도입은 단순한 성능 향상이 아니라, 장애 내성(Fault Tolerance)을 갖춘 프로덕션 시스템의 기본기를 다지는 과정입니다. 오늘 소개한 체크리스트를 하나씩 적용하여 안정적이고 빠른 자동화 환경을 구축하시길 바랍니다.

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다