n8n을 Docker Compose로 셀프 호스팅하기 (Ubuntu)
Ubuntu 서버에 n8n을 Docker Compose 컨테이너로 배포하고 PostgreSQL·방화벽·SSL까지 구성하는 과정을 정리한다.
2026-08-12 · 최초 발행 2025-06-11
Docker Compose로 n8n을 배포하면 n8n 자체와 필요하면 데이터베이스까지 컨테이너 단위로 묶어 관리할 수 있다. docker-compose.yml 파일 하나가 서비스 정의·볼륨·네트워크를 전부 담기 때문에, Node.js·npm을 직접 설치하고 systemd 유닛을 작성하는 방식보다 배포 단위가 명확하게 나뉜다.
사전 준비
Ubuntu 20.04 LTS 또는 22.04 LTS, 루트 또는 sudo 권한 계정, SSH 접근 환경이 필요하고 Docker와 Docker Compose가 설치돼 있어야 한다. n8n은 기본적으로 5678 포트를 쓰므로 방화벽에서 열어야 하며, 도메인과 SSL을 쓸 경우 Nginx·Certbot도 선택적으로 준비한다.
Docker와 Docker Compose 설치
시스템을 최신 상태로 유지한다.
sudo apt update && sudo apt upgrade -y
Docker 공식 스크립트로 설치한다.
sudo apt install -y curl
curl -fsSL https://get.docker.com | sudo sh
설치 후 버전을 확인한다.
docker --version
Docker version 27.3.1(2025년 5월 기준 최신 버전)처럼 출력된다. Docker Compose는 별도로 받는다.
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
Docker Compose version v2.29.2처럼 나오면 정상이다. sudo 없이 docker 명령을 쓰려면 현재 계정을 docker 그룹에 추가한다.
sudo usermod -aG docker $USER
적용하려면 로그아웃 후 다시 로그인하거나 새 터미널 세션을 시작해야 한다.
docker-compose.yml 작성하기
작업 디렉토리를 만든다.
mkdir ~/n8n && cd ~/n8n
파일을 연다.
nano docker-compose.yml
기본적으로 SQLite를 쓰는 구성은 다음과 같다.
version: "3.8"
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
ports:
- "5678:5678"
environment:
- N8N_HOST=0.0.0.0
- N8N_PORT=5678
- N8N_PROTOCOL=http
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=your_username
- N8N_BASIC_AUTH_PASSWORD=your_secure_password
- WEBHOOK_URL=http://<your_server_ip_or_domain>:5678/
- N8N_ENCRYPTION_KEY=your_secret_encryption_key
- GENERIC_TIMEZONE=Asia/Seoul
volumes:
- n8n_data:/home/node/.n8n
restart: always
networks:
- n8n_network
volumes:
n8n_data:
networks:
n8n_network:
driver: bridge
image는 최신 n8n 이미지, ports는 호스트 5678을 컨테이너 5678에 매핑한다. environment의 N8N_BASIC_AUTH_*는 기본 인증 설정, WEBHOOK_URL은 <your_server_ip_or_domain>을 실제 서버 IP나 도메인으로 바꿔 넣는 웹훅용 공용 URL, N8N_ENCRYPTION_KEY는 암호화 키(openssl rand -base64 32로 생성한 랜덤 문자열 권장), GENERIC_TIMEZONE은 한국 시간대 Asia/Seoul이다. volumes는 설정·워크플로우 데이터를 호스트에 영구 저장하고, restart: always는 컨테이너 실패 시 자동 재시작, networks는 컨테이너 간 통신용 브리지 네트워크다. 볼륨 데이터를 저장할 디렉토리 권한도 설정해 둔다.
sudo chown -R $USER:$USER ~/n8n
sudo chmod -R 755 ~/n8n
컨테이너 실행과 로그 확인
Docker Compose로 컨테이너를 띄운다.
docker-compose up -d
-d는 백그라운드 실행이다. 상태를 확인한다.
docker ps
n8n 컨테이너가 Up 상태여야 한다. 브라우저에서 http://<서버_IP>:5678에 접속해 설정한 N8N_BASIC_AUTH_USER·N8N_BASIC_AUTH_PASSWORD로 로그인했을 때 워크플로우 편집 화면이 뜨면 성공이다. 문제가 있으면 컨테이너 로그를 본다.
docker logs n8n
PostgreSQL 컨테이너 추가하기
기본 SQLite 대신 프로덕션에서는 PostgreSQL을 권장한다. docker-compose.yml에 postgres 서비스를 추가하는 식으로 확장한다.
nano docker-compose.yml
version: "3.8"
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
ports:
- "5678:5678"
environment:
- N8N_HOST=0.0.0.0
- N8N_PORT=5678
- N8N_PROTOCOL=http
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=your_username
- N8N_BASIC_AUTH_PASSWORD=your_secure_password
- WEBHOOK_URL=http://<your_server_ip_or_domain>:5678/
- N8N_ENCRYPTION_KEY=your_secret_encryption_key
- GENERIC_TIMEZONE=Asia/Seoul
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n_user
- DB_POSTGRESDB_PASSWORD=your_db_password
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
restart: always
networks:
- n8n_network
postgres:
image: postgres:15
container_name: n8n_postgres
environment:
- POSTGRES_USER=n8n_user
- POSTGRES_PASSWORD=your_db_password
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
restart: always
networks:
- n8n_network
volumes:
n8n_data:
postgres_data:
networks:
n8n_network:
driver: bridge
바뀐 부분은 postgres 서비스 추가, DB_TYPE 등 PostgreSQL 관련 환경 변수, n8n이 postgres 컨테이너에 의존하도록 하는 depends_on, 그리고 DB 데이터를 영구 저장할 postgres_data 볼륨이다. 컨테이너를 재시작한다.
docker-compose down
docker-compose up -d
n8n 로그에서 PostgreSQL 연결이 성공했는지 확인한다.
docker logs n8n
운영 보강: 방화벽과 HTTPS
방화벽·리버스 프록시·SSL 설정은 배포 방식과 무관하게 동일한 절차를 따른다. UFW로 필요한 포트만 연다.
sudo apt install ufw -y
sudo ufw allow 22
sudo ufw allow 5678
sudo ufw enable
SSH(22)와 n8n(5678)을 허용하고, HTTPS를 쓸 경우 443도 추가로 연다. Nginx를 리버스 프록시로 세운다.
sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/n8n
도메인을 your_domain.com으로 바꿔 아래 설정을 추가한다.
server {
listen 80;
server_name your_domain.com;
location / {
proxy_pass http://localhost:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Certbot으로 SSL을 붙인다.
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your_domain.com
Certbot이 Nginx 설정을 자동으로 HTTPS로 업데이트한다. docker-compose.yml도 함께 수정한다.
nano docker-compose.yml
N8N_PROTOCOL=http를 N8N_PROTOCOL=https로, WEBHOOK_URL을 https://your_domain.com/로 바꾼 뒤 컨테이너를 재시작한다.
docker-compose down
docker-compose up -d
업데이트와 백업
최신 n8n 이미지로 갱신한다.
docker-compose down
docker-compose pull
docker-compose up -d
n8n 데이터와 PostgreSQL 데이터를 함께 백업한다.
tar -czf n8n_backup_$(date +%F).tar.gz ~/n8n
docker exec n8n_postgres pg_dump -U n8n_user n8n > n8n_db_backup_$(date +%F).sql
로그는 각 컨테이너별로 확인한다.
docker logs n8n
docker logs n8n_postgres
최종 점검
http://<서버_IP>:5678 또는 https://your_domain.com으로 접속해 정상 작동하는지, 워크플로우 생성·테스트가 되는지, 방화벽·인증 설정이 걸려 있는지 확인한다.
참고 자료
- n8n 공식 문서: https://docs.n8n.io
- Docker Compose 문서: https://docs.docker.com/compose
- Nginx 및 Certbot 설정: https://certbot.eff.org