Hướng dẫn: Nâng cấp version N8n
Hướng dẫn: Triển khai N8n với docker compose
- --- lượt xem
Tiếp nối bài viết triển khai N8n với Docker (sử dụng các câu lệnh docker run), trong bài viết này tôi sẽ hướng dẫn bạn cách triển khai N8n sử dụng Docker Compose. Cách này sẽ giúp bạn dễ dàng quản lý các container hơn, đặc biệt khi bạn cần chạy nhiều dịch vụ cùng lúc.
Yêu cầu
- Cài đặt Docker trên máy chủ của bạn. Bạn có thể tham khảo hướng dẫn cài đặt Docker.
- Cài đặt Docker Compose. Bạn có thể tham khảo hướng dẫn cài đặt Docker Compose.
- (Tham khảo) Bài viết này đang sử dụng môi trường sau:
- Hệ điều hành: MacOS 15.6.1 (Chip M)
- Docker version: 28.5.1
Cấu trúc ‘Project’
Tạo một thư mục mới để chứa các file cấu hình Docker Compose và các dữ liệu liên quan đến N8n:
-- n8n-docker-compose
|-- n8n
|-- postgres
|-- docker-compose.yml
|-- .env
Thực hiện các lệnh sau để tạo thư mục và di chuyển vào bên trong:
mkdir n8n-docker-compose
cd n8n-docker-compose
Tạo thư mục ‘n8n’ và ‘postgres’
Tạo 2 thư mục n8n và postgres để để lưu trữ Dockerfile và dữ liệu của N8n và PostgreSQL:
mkdir n8n postgres
Tạo file dockerfile cho N8n
Tạo file Dockerfile bên trong thư mục n8n:
touch n8n/Dockerfile
Mở file n8n/Dockerfile và thêm nội dung sau:
FROM n8nio/n8n:latest
USER root
RUN apk add --no-cache \
python3 \
py3-pip
# Install build dependencies for packages like psutil
# RUN apk add --no-cache gcc musl-dev linux-headers python3-dev
# Install Python packages globally (without venv)
RUN pip3 install --break-system-packages --no-cache-dir --use-pep517 --no-build-isolation \
telethon \
email-validator==2.3.0 \
validate_email==1.3 \
py3-validate-email==1.0.5.post2
# Fix permissions for Python site-packages to ensure user 'node' can access them
RUN chmod -R 755 /usr/lib/python3.12/site-packages && \
find /usr/lib/python3.12/site-packages -type d -exec chmod 755 {} \; && \
find /usr/lib/python3.12/site-packages -type f -exec chmod 644 {} \;
# Remove build dependencies to reduce image size
# RUN apk del gcc musl-dev linux-headers python3-dev
RUN apk add --no-cache \
chromium \
chromium-chromedriver \
nss \
freetype \
freetype-dev \
harfbuzz \
ca-certificates \
ttf-freefont \
curl
# Set environment variables for Puppeteer and Playwright
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 \
PLAYWRIGHT_BROWSERS_PATH=/usr/bin \
PYTHONPATH=/usr/lib/python3.12/site-packages
RUN apk add --no-cache openssh-client
RUN mkdir -p /home/node/.ssh && \
chown -R node:node /home/node/.ssh && \
chmod 700 /home/node/.ssh
RUN npm install -g \
moment
USER node
Tạo file dockerfile cho PostgreSQL
Tạo file Dockerfile bên trong thư mục postgres:
touch postgres/Dockerfile
Mở file postgres/Dockerfile và thêm nội dung sau:
FROM postgres:17
RUN apt-get update && apt-get install -y \
build-essential \
git \
postgresql-server-dev-17
RUN git clone https://github.com/pgvector/pgvector.git \
&& cd pgvector \
&& make \
&& make install
RUN apt-get remove -y build-essential git postgresql-server-dev-all \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/*
Tạo file docker-compose.yml
Tiếp theo, tạo file docker-compose.yml để định nghĩa các dịch vụ Docker:
touch docker-compose.yml
Mở file docker-compose.yml và thêm nội dung sau:
networks:
n8n_network:
driver: bridge
services:
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
networks: [ n8n_network ]
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 10s
timeout: 3s
retries: 10
postgres-db:
build: ./postgres
container_name: postgres
restart: unless-stopped
networks: [ n8n_network ]
ports:
- "5432:5432"
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- ./docker-volumes-system/postgres-data:/var/lib/postgresql/data
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB -h 127.0.0.1 || exit 1" ]
interval: 10s
timeout: 5s
retries: 10
n8n:
build: ./n8n
container_name: n8n-main
restart: unless-stopped
networks: [ n8n_network ]
ports:
- "5678:5678"
environment:
# Time & Node
- TZ=${N8N_TZ}
- GENERIC_TIMEZONE=${N8N_GENERIC_TIMEZONE}
- UV_THREADPOOL_SIZE=${N8N_UV_THREADPOOL_SIZE}
- NODE_OPTIONS=${N8N_NODE_OPTIONS}
# DB
- DB_TYPE=${N8N_DB_TYPE}
- DB_POSTGRESDB_DATABASE=${N8N_DB_POSTGRESDB_DATABASE}
- DB_POSTGRESDB_HOST=${N8N_DB_POSTGRESDB_HOST}
- DB_POSTGRESDB_PORT=${N8N_DB_POSTGRESDB_PORT}
- DB_POSTGRESDB_USER=${N8N_DB_POSTGRESDB_USER}
- DB_POSTGRESDB_PASSWORD=${N8N_DB_POSTGRESDB_PASSWORD}
# App
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_SECURE_COOKIE=${N8N_SECURE_COOKIE}
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS}
- N8N_HIRING_BANNER_ENABLED=${N8N_HIRING_BANNER_ENABLED}
# Runners / Code
- N8N_RUNNERS_ENABLED=${N8N_RUNNERS_ENABLED}
- N8N_RUNNERS_MODE=${N8N_RUNNERS_MODE}
- N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN}
- N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
- N8N_RUNNERS_MAX_CONCURRENCY=${N8N_RUNNERS_MAX_CONCURRENCY}
- NODE_FUNCTION_ALLOW_EXTERNAL=${N8N_NODE_FUNCTION_ALLOW_EXTERNAL}
# Queue mode
- EXECUTIONS_PROCESS=${N8N_EXECUTIONS_PROCESS}
- EXECUTIONS_DATA_PRUNE=${N8N_EXECUTIONS_DATA_PRUNE}
- EXECUTIONS_DATA_MAX_AGE=${N8N_EXECUTIONS_DATA_MAX_AGE}
- EXECUTIONS_DATA_PRUNE_MAX_COUNT=${N8N_EXECUTIONS_DATA_PRUNE_MAX_COUNT}
- QUEUE_BULL_REDIS_HOST=${N8N_QUEUE_BULL_REDIS_HOST}
- QUEUE_BULL_REDIS_PORT=${N8N_QUEUE_BULL_REDIS_PORT}
# (optional) Public URLs
- VUE_APP_URL_BASE_API=${N8N_VUE_APP_URL_BASE_API}
- WEBHOOK_URL=${N8N_WEBHOOK_URL}
volumes:
- ./docker-volumes-system/n8n:/home/node/.n8n
- ./data:/data
- ${HOME}/.ssh/id_rsa:/home/node/.ssh/id_rsa:ro
- ${HOME}/.ssh/known_hosts:/home/node/.ssh/known_hosts
depends_on:
redis:
condition: service_healthy
postgres-db:
condition: service_healthy
n8n-worker:
build: ./n8n
command: worker
restart: unless-stopped
networks: [ n8n_network ]
environment:
- TZ=${N8N_WORKER_TZ}
- UV_THREADPOOL_SIZE=${N8N_WORKER_UV_THREADPOOL_SIZE}
- NODE_OPTIONS=${N8N_WORKER_NODE_OPTIONS}
# Queue mode
- EXECUTIONS_PROCESS=${N8N_WORKER_EXECUTIONS_PROCESS}
- QUEUE_BULL_REDIS_HOST=${N8N_WORKER_QUEUE_BULL_REDIS_HOST}
- QUEUE_BULL_REDIS_PORT=${N8N_WORKER_QUEUE_BULL_REDIS_PORT}
- N8N_WORKER_CONCURRENCY=${N8N_WORKER_CONCURRENCY}
# DB
- DB_TYPE=${N8N_WORKER_DB_TYPE}
- DB_POSTGRESDB_DATABASE=${N8N_WORKER_DB_POSTGRESDB_DATABASE}
- DB_POSTGRESDB_HOST=${N8N_WORKER_DB_POSTGRESDB_HOST}
- DB_POSTGRESDB_PORT=${N8N_WORKER_DB_POSTGRESDB_PORT}
- DB_POSTGRESDB_USER=${N8N_WORKER_DB_POSTGRESDB_USER}
- DB_POSTGRESDB_PASSWORD=${N8N_WORKER_DB_POSTGRESDB_PASSWORD}
# KEY
- N8N_ENCRYPTION_KEY=${N8N_WORKER_ENCRYPTION_KEY}
# External modules
- NODE_FUNCTION_ALLOW_EXTERNAL=${N8N_WORKER_NODE_FUNCTION_ALLOW_EXTERNAL}
volumes:
- ~/Workplace/docker-n8n/data:/home/node/.n8n
- ~/Workplace/docker-n8n/my-data:/data
- ${HOME}/.ssh/id_rsa:/home/node/.ssh/id_rsa:ro
- ${HOME}/.ssh/known_hosts:/home/node/.ssh/known_hosts
depends_on:
redis:
condition: service_healthy
postgres-db:
condition: service_healthy
n8n-runner:
image: n8nio/n8n:latest
container_name: n8n-runner
restart: unless-stopped
networks: [ n8n_network ]
environment:
- N8N_RUNNERS_MODE=internal
- N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN}
- N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_RUNNERS_MAX_CONCURRENCY=${N8N_RUNNERS_MAX_CONCURRENCY}
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS}
- N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT=${N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT:-15}
- DB_TYPE=${N8N_DB_TYPE}
- DB_POSTGRESDB_DATABASE=${N8N_DB_POSTGRESDB_DATABASE}
- DB_POSTGRESDB_HOST=${N8N_DB_POSTGRESDB_HOST}
- DB_POSTGRESDB_PORT=${N8N_DB_POSTGRESDB_PORT}
- DB_POSTGRESDB_USER=${N8N_DB_POSTGRESDB_USER}
- DB_POSTGRESDB_PASSWORD=${N8N_DB_POSTGRESDB_PASSWORD}
# Queue
- QUEUE_BULL_REDIS_HOST=${N8N_QUEUE_BULL_REDIS_HOST}
- QUEUE_BULL_REDIS_PORT=${N8N_QUEUE_BULL_REDIS_PORT}
# Tùy chọn
- TZ=${N8N_TZ}
- GENERIC_TIMEZONE=${N8N_GENERIC_TIMEZONE}
- NODE_FUNCTION_ALLOW_EXTERNAL=${N8N_NODE_FUNCTION_ALLOW_EXTERNAL}
entrypoint: ["/usr/local/bin/task-runner-launcher", "javascript"]
depends_on:
redis:
condition: service_healthy
postgres-db:
condition: service_healthy
Tạo file .env
Tạo file .env để lưu trữ các biến môi trường:
touch .env
Mở file .env và thêm nội dung sau (bạn có thể tùy chỉnh các giá trị theo nhu cầu của mình):
# N8N (for n8n service)
N8N_TZ=Asia/Ho_Chi_Minh
N8N_GENERIC_TIMEZONE=Asia/Ho_Chi_Minh
N8N_UV_THREADPOOL_SIZE=64
N8N_NODE_OPTIONS=--max-old-space-size=16384
N8N_DB_TYPE=postgresdb
N8N_DB_POSTGRESDB_DATABASE=n8n
N8N_DB_POSTGRESDB_HOST=postgres
N8N_DB_POSTGRESDB_PORT=5432
N8N_DB_POSTGRESDB_USER=root
N8N_DB_POSTGRESDB_PASSWORD=mywePassword
N8N_ENCRYPTION_KEY=2de51f761154e998af3b15f4b03937b8
N8N_SECURE_COOKIE=false
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
N8N_HIRING_BANNER_ENABLED=false
N8N_RUNNERS_ENABLED=true
N8N_RUNNERS_MODE=external
N8N_RUNNERS_AUTH_TOKEN=860f66d0f4459da19c5bda0eb5f3eadc
N8N_RUNNERS_MAX_CONCURRENCY=5
N8N_NODE_FUNCTION_ALLOW_EXTERNAL=*
N8N_EXECUTIONS_PROCESS=queue
N8N_EXECUTIONS_DATA_PRUNE=true
N8N_EXECUTIONS_DATA_MAX_AGE=168
N8N_EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000
N8N_QUEUE_BULL_REDIS_HOST=redis
N8N_QUEUE_BULL_REDIS_PORT=6379
N8N_VUE_APP_URL_BASE_API=http://localhost:5678/
N8N_WEBHOOK_URL=http://localhost:5678/
# POSTGRES (for postgres-db service)
POSTGRES_DB=n8n
POSTGRES_USER=root
POSTGRES_PASSWORD=mywePassword
# N8N_WORKER (for n8n-worker service)
N8N_WORKER_TZ=Asia/Ho_Chi_Minh
N8N_WORKER_UV_THREADPOOL_SIZE=64
N8N_WORKER_NODE_OPTIONS=--max-old-space-size=16384
N8N_WORKER_EXECUTIONS_PROCESS=queue
N8N_WORKER_QUEUE_BULL_REDIS_HOST=redis
N8N_WORKER_QUEUE_BULL_REDIS_PORT=6379
N8N_WORKER_CONCURRENCY=5
N8N_WORKER_DB_TYPE=postgresdb
N8N_WORKER_DB_POSTGRESDB_DATABASE=n8n
N8N_WORKER_DB_POSTGRESDB_HOST=postgres
N8N_WORKER_DB_POSTGRESDB_PORT=5432
N8N_WORKER_DB_POSTGRESDB_USER=root
N8N_WORKER_DB_POSTGRESDB_PASSWORD=mywePassword
N8N_WORKER_ENCRYPTION_KEY=2de51f761154e998af3b15f4b03937b8
N8N_WORKER_NODE_FUNCTION_ALLOW_EXTERNAL=*
Bạn hãy thay đổi các giá trị trong file .env theo nhu cầu của bạn, đặc biệt là các thông tin liên quan đến cơ sở dữ liệu và khóa mã hóa như POSTGRES_PASSWORD, N8N_WORKER_ENCRYPTION_KEY, N8N_DB_POSTGRESDB_PASSWORD, và N8N_ENCRYPTION_KEY.
Lưu ý: các giá trị trùng nhau trong ví dụ trên hãy đảm bảo khi bạn sinh ra giá trị mới nó sẽ tương ứng với nhau.
Khởi động các dịch vụ
Sau khi đã tạo xong các file cấu hình, bạn có thể khởi động các dịch vụ bằng lệnh sau:
docker-compose up -d
Lệnh này sẽ tải về các image cần thiết, xây dựng các container từ các Dockerfile và khởi động chúng trong chế độ nền.
Bạn có thể kiểm tra trạng thái của các container bằng lệnh:
docker-compose ps
Nếu mọi thứ hoạt động bình thường, bạn sẽ thấy các container n8n, postgres-db, và redis đang chạy.

Truy cập N8n
Mở trình duyệt và truy cập vào địa chỉ http://localhost:5678 để sử dụng N8n. Bạn có thể bắt đầu tạo các workflow tự động hóa của mình ngay lập tức.