DigitalOcean에서 n8n 호스팅하기
n8n v2.42요약
이 호스팅 가이드는 실제 도메인과 자동 HTTPS를 갖춘 DigitalOcean 드롭릿에서 n8n을 셀프 호스팅하는 방법을 보여줍니다. n8n이 실행되고 나면, 선택 사항인 마지막 섹션에서 n8n Assistant를 추가하는 방법을 다룹니다.
이 호스팅 가이드는 실제 도메인과 자동 HTTPS를 갖춘 DigitalOcean 드롭릿에서 n8n을 셀프 호스팅하는 방법을 보여줍니다. 다음을 사용합니다:
- 인터넷에서 드롭릿에 접근할 수 있도록 해주는 리버스 프록시인 Caddy. Caddy는 n8n 인스턴스의 SSL/TLS 인증서도 자동으로 생성하고 관리합니다.
- 애플리케이션 구성 요소를 생성하고 정의하며 이들이 함께 작동하는 방식을 정의하는 Docker Compose.
n8n이 실행되고 나면, 선택 사항인 마지막 섹션에서 n8n Assistant를 추가하는 방법을 다룹니다.
이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.
이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.
이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.
드롭릿 생성#
- DigitalOcean에 로그인합니다.
- 드롭릿을 호스팅할 프로젝트를 선택하거나 새 프로젝트를 생성합니다.
- 프로젝트에서 Manage 메뉴의 Droplets를 선택합니다.
- Marketplace 탭에서 제공되는 Docker 이미지를 사용하여 새 드롭릿을 생성합니다.
드롭릿 리소스
드롭릿을 생성할 때 DigitalOcean은 플랜을 선택하도록 요청합니다. 대부분의 사용 수준에서는 기본 공유 CPU 플랜으로 충분합니다.
SSH 키 또는 비밀번호
DigitalOcean에서는 SSH 키와 비밀번호 기반 인증 중 선택할 수 있습니다. SSH 키가 더 안전한 것으로 간주됩니다.
드롭릿에 로그인하고 새 사용자 생성#
이 가이드의 나머지 부분에서는 SSH를 사용하는 터미널로 드롭릿에 로그인해야 합니다. 자세한 내용은 How to Connect to Droplets with SSH를 참조하세요.
root 사용자로 작업하지 않도록 새 사용자를 생성해야 합니다:
- root로 로그인합니다.
- 새 사용자를 생성합니다:
adduser <username> - CLI의 안내에 따라 사용자 생성을 완료합니다.
- 새 사용자에게 관리자 권한을 부여합니다:
이제 명령어 앞에usermod -aG sudo <username>sudo를 붙여서 슈퍼유저 권한으로 명령을 실행할 수 있습니다. - 새 사용자를 위해 SSH를 설정하는 단계를 따릅니다: Add Public Key Authentication.
- 드롭릿에서 로그아웃합니다.
- 새 사용자로 SSH를 사용해 로그인합니다.
구성 리포지터리 클론#
Docker Compose, n8n, Caddy에는 일련의 폴더와 구성 파일이 필요합니다. 이를 드롭릿에 로그인한 사용자의 홈 폴더에 이 리포지터리에서 클론할 수 있습니다. 다음 단계에서는 어떤 파일을 변경해야 하고 어떤 변경을 해야 하는지 알려줍니다.
다음 명령어로 리포지터리를 클론합니다:
git clone https://github.com/n8n-io/n8n-docker-caddy.git
그리고 클론한 리포지터리의 루트로 디렉터리를 변경합니다:
cd n8n-docker-caddy
기본 폴더와 파일#
호스트 운영 체제(DigitalOcean 드롭릿)는 생성한 두 폴더를 Docker 컨테이너에 복사하여 Docker에서 사용할 수 있게 합니다. 두 폴더는 다음과 같습니다:
caddy_config: Caddy 구성 파일을 보관합니다.local_files: n8n을 사용해 업로드하거나 추가하는 파일을 위한 폴더입니다.
Docker 볼륨 생성#
재시작 사이에 Caddy 캐시를 유지하고 시작 시간을 단축하려면 Docker가 재시작 사이에 재사용하는 Docker 볼륨을 생성하세요:
sudo docker volume create caddy_data
n8n 데이터용 Docker 볼륨을 생성합니다:
sudo docker volume create n8n_data
DNS 설정#
n8n은 일반적으로 서브도메인에서 작동합니다. 제공업체에서 서브도메인에 대한 DNS 레코드를 생성하고 드롭릿의 IP 주소를 가리키도록 설정하세요. 정확한 단계는 DNS 제공업체에 따라 다르지만, 일반적으로 n8n 서브도메인에 대해 새로운 "A" 레코드를 생성해야 합니다. DigitalOcean은 An Introduction to DNS Terminology, Components, and Concepts를 제공합니다.
포트 열기#
n8n은 웹 애플리케이션으로 실행되므로 드롭릿은 비보안 트래픽을 위한 포트 80과 보안 트래픽을 위한 포트 443에 대한 수신 접근을 허용해야 합니다.
다음 두 명령을 실행하여 드롭릿의 방화벽에서 다음 포트를 엽니다:
sudo ufw allow 80
sudo ufw allow 443
n8n 구성#
n8n에는 Docker 컨테이너에서 실행되는 애플리케이션에 전달할 환경 변수 설정이 몇 가지 필요합니다. 예시 .env 파일에는 직접 값으로 교체해야 하는 자리 표시자가 들어 있습니다.
다음 명령어로 파일을 엽니다:
nano .env
파일에는 무엇을 변경해야 하는지 알려주는 인라인 주석이 포함되어 있습니다.
n8n 환경 변수에 대한 자세한 내용은 환경 변수를 참조하세요.
Docker Compose 파일#
Docker Compose 파일(docker-compose.yml)은 애플리케이션에 필요한 서비스, 이 경우 Caddy와 n8n을 정의합니다. 별도의 데이터베이스 서비스는 없으며, n8n은 기본적으로 내장 SQLite 데이터베이스를 사용합니다.
- Caddy 서비스 정의는 사용하는 포트와 컨테이너에 복사할 로컬 볼륨을 정의합니다.
- n8n 서비스 정의는 사용하는 포트, n8n 실행에 필요한 환경 변수(일부는
.env파일에 정의됨), 컨테이너에 복사해야 하는 볼륨을 정의합니다.
Docker Compose 파일은 .env 파일에 설정된 환경 변수를 사용하므로 내용을 변경할 필요는 없지만, 살펴보려면 다음 명령어를 실행하세요:
nano docker-compose.yml
Caddy 구성#
Caddy는 어떤 도메인을 서비스해야 하는지, 외부 세계에 어떤 포트를 노출해야 하는지 알아야 합니다. caddy_config 폴더의 Caddyfile 파일을 편집하세요.
nano caddy_config/Caddyfile
자리 표시자 도메인을 여러분의 도메인으로 변경하세요. 서브도메인을 n8n으로 지정하는 단계를 따랐다면, 전체 도메인은 n8n.example.com과 비슷한 형태가 됩니다. reverse_proxy 설정의 n8n은 docker-compose.yml 파일에 정의된 서비스 정의를 사용하도록 Caddy에 알려줍니다:
n8n.<domain>.<suffix> {
reverse_proxy n8n:5678 {
flush_interval -1
}
}
automate.example.com을 사용하는 경우 Caddyfile은 다음과 비슷하게 보일 수 있습니다:
automate.example.com {
reverse_proxy n8n:5678 {
flush_interval -1
}
}
Docker Compose 시작#
다음 명령어로 n8n과 Caddy를 시작합니다:
sudo docker compose up -d
이 작업은 몇 분 정도 걸릴 수 있습니다.
설정 테스트#
브라우저에서 앞서 정의한 서브도메인과 도메인 이름으로 구성된 URL을 엽니다. 처음 열면 n8n이 소유자 계정을 만들도록 안내합니다.
n8n과 Caddy 중지#
다음 명령어로 n8n과 Caddy를 중지할 수 있습니다:
sudo docker compose stop
선택 사항: n8n Assistant 추가#
n8n Assistant는 코드를 실행할 샌드박스가 필요합니다. Docker Compose 가이드에서 사용하는 것과 동일한 샌드박스 스택을 이 설정에 추가할 수 있습니다. 시작하기 전에 알아 두면 좋은 사항은 다음과 같습니다:
- 이 샌드박스는 로컬 개발과 테스트에 적합합니다. 아래 스택은 n8n에 번들로 포함된 자체 샌드박스(
n8n-sandbox)를 사용합니다. 공개 도메인을 사용하는 DigitalOcean 드롭릿은 실제 운영 환경인 경우가 많으므로, 프로덕션에 사용할 예정이라면 Daytona를 대신 사용하는 것을 고려하세요. - 필요하면 크기를 조정하세요. 샌드박스 러너는 Docker-in-Docker를 사용하므로 n8n 단독보다 더 많은 여유 리소스가 필요합니다. 최소 4 GB RAM / 2 vCPU를 프로비저닝해야 합니다.
- 네트워크 변경은 필요하지 않습니다. Caddy는 n8n 자체만 프록시하며, 샌드박스 서비스는 Compose 네트워크 내부에만 있으므로 DNS, 방화벽, Caddyfile 변경이 필요하지 않습니다.
-
.env에 이미 있는 변수와 함께 샌드박스 시크릿을 추가합니다:# 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 # Web search: secret for the bundled SearXNG instance — pick your own value SEARXNG_SECRET=change-me-searxng-secret -
다른 구성 파일과 같은 위치에
searxng-settings.yml파일을 생성합니다(기본 SearXNG 이미지는 HTML만 제공하므로, 이 설정은 n8n의 웹 검색에 필요한 JSON API를 활성화합니다):use_default_settings: true search: formats: - html - json -
docker-compose.yml을 열고 기존caddy및n8n서비스와 함께 샌드박스 및 검색 서비스를 추가합니다:volumes: sandbox-tls: services: sandbox-certs: image: ghcr.io/n8n-io/n8n-sandbox-service-api:latest user: '0:0' entrypoint: ['sh', '-c'] command: - > bootstrap-mtls.sh --out-dir /tls --api-san sandbox-api --control-san-prefix sandbox-runner && chown -R sandbox-api:sandbox-api /tls/api environment: NUM_RUNNERS: '1' volumes: - sandbox-tls:/tls sandbox-api: image: ghcr.io/n8n-io/n8n-sandbox-service-api:latest depends_on: sandbox-certs: condition: service_completed_successfully environment: SANDBOX_API_KEYS: ${SANDBOX_API_KEYS} SANDBOX_API_RUNNER_REGISTRATION_TOKEN: ${SANDBOX_API_RUNNER_REGISTRATION_TOKEN} SANDBOX_API_RUNNER_API_KEY: ${SANDBOX_API_RUNNER_API_KEY} SANDBOX_API_GRPC_TLS_CERT_FILE: /tls/api/grpc-server.crt SANDBOX_API_GRPC_TLS_KEY_FILE: /tls/api/grpc-server.key SANDBOX_API_GRPC_TLS_CLIENT_CA_FILE: /tls/api/ca.crt SANDBOX_API_RUNNER_CONTROL_GRPC_TLS_CA_FILE: /tls/api/ca.crt SANDBOX_API_RUNNER_CONTROL_GRPC_TLS_CERT_FILE: /tls/api/control-grpc-api-client.crt SANDBOX_API_RUNNER_CONTROL_GRPC_TLS_KEY_FILE: /tls/api/control-grpc-api-client.key SANDBOX_API_RUNNER_CONTROL_GRPC_TLS_SERVER_NAME: sandbox-runner-1 volumes: - sandbox-tls:/tls:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"] interval: 5s timeout: 3s retries: 5 start_period: 10s # Never publish 8080/9090 — Caddy never routes to this service, and it shouldn't. sandbox-runner-1: image: ghcr.io/n8n-io/n8n-sandbox-service-runner-dind:latest privileged: true depends_on: sandbox-api: condition: service_healthy environment: SANDBOX_RUNNER_API_KEYS: ${SANDBOX_API_RUNNER_API_KEY} SANDBOX_RUNNER_REGISTRATION_TOKEN: ${SANDBOX_API_RUNNER_REGISTRATION_TOKEN} SANDBOX_RUNNER_API_GRPC_ADDR: sandbox-api:9090 SANDBOX_RUNNER_HTTP_BASE_URL: http://sandbox-runner-1:8080 SANDBOX_RUNNER_CONTROL_GRPC_LISTEN_ADDR: ':9091' SANDBOX_RUNNER_CONTROL_GRPC_ADVERTISE_ADDR: sandbox-runner-1:9091 SANDBOX_RUNNER_ID: runner-1 SANDBOX_RUNNER_DOCKER_SANDBOX_IMAGE: ghcr.io/n8n-io/n8n-sandbox-service-sandbox:latest SANDBOX_RUNNER_REGISTRATION_GRPC_CA_FILE: /tls/runner/ca.crt SANDBOX_RUNNER_REGISTRATION_GRPC_CERT_FILE: /tls/runner/grpc-client.crt SANDBOX_RUNNER_REGISTRATION_GRPC_KEY_FILE: /tls/runner/grpc-client.key SANDBOX_RUNNER_REGISTRATION_GRPC_SERVER_NAME: sandbox-api SANDBOX_RUNNER_CONTROL_GRPC_TLS_CERT_FILE: /tls/runner/control-grpc-server.crt SANDBOX_RUNNER_CONTROL_GRPC_TLS_KEY_FILE: /tls/runner/control-grpc-server.key SANDBOX_RUNNER_CONTROL_GRPC_TLS_CLIENT_CA_FILE: /tls/runner/ca.crt volumes: - sandbox-tls:/tls:ro # Never expose this container's ports publicly — it runs privileged Docker-in-Docker. searxng: image: ghcr.io/searxng/searxng:latest environment: SEARXNG_SECRET: ${SEARXNG_SECRET} volumes: - ./searxng-settings.yml:/etc/searxng/settings.yml:ro # Internal-only: n8n reaches it by service name. Never publish its port, and don't route Caddy to it. -
기존
n8n서비스의environment블록에 이에 대응하는 샌드박스 변수를 추가합니다:environment: # ...your existing N8N_HOST, N8N_PORT, etc. stay as they are - N8N_ENABLED_MODULES=instance-ai - N8N_INSTANCE_AI_SANDBOX_ENABLED=true - N8N_INSTANCE_AI_SANDBOX_PROVIDER=n8n-sandbox - N8N_SANDBOX_SERVICE_URL=http://sandbox-api:8080 - N8N_SANDBOX_SERVICE_API_KEY=${SANDBOX_API_KEYS} - N8N_INSTANCE_AI_SEARXNG_URL=http://searxng:8080 depends_on: sandbox-api: condition: service_healthy -
새 서비스가 변경 사항을 반영하도록 모든 것을 다시 시작합니다:
sudo docker compose up -d -
모델 API 키를 추가합니다. 모델 제공업체를 선택하는 방법을 포함한 전체 참조는 n8n Assistant 설정을 참조하세요. 웹 검색은 위의 번들 SearXNG 서비스로 별도 설정 없이 작동하며, 대신 Brave Search를 사용하려면 Brave Search 키를 추가하세요.
이 드롭릿을 인터넷에 노출하기 전에 .env의 change-me-... 자리 표시자를 여러분만의 고유한 시크릿으로 교체하세요. sandbox-runner-1은 권한이 상승된(privileged) Docker-in-Docker로 실행됩니다. 해당 포트를 절대 공개하지 말고, Caddy가 이 서비스로 라우팅하지 않도록 하세요.
업데이트#
이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.
다음 단계#
이 섹션의 상세 내용은 n8n 공식 문서를 참조하세요.