n8n Docker 部署教程:从零搭建第一个自动化工作流
n8n 是一款 fair-code 模式的工作流自动化平台,可以用可视化画布拼装节点,也能插入 JavaScript、Python 代码片段,覆盖 1500+ 集成。对于想把自动化能力放在自己服务器上、又不想被 SaaS 绑定的团队来说,Docker 部署是最常见的入口。本文从零开始,用 Docker Compose 搭建一个带 PostgreSQL 的 n8n 实例,并完成第一个 RSS → 邮件的工作流。


准备工作
开始之前,需要确认三件事:
- Docker 与 Docker Compose:推荐使用较新版本的 Docker(自带
docker compose子命令,老版本才需要单独的docker-compose二进制)。可以用docker --version和docker compose version验证。 - 内存:n8n 本身是 Node.js 应用,单实例最低建议 1GB 内存。如果跑大型工作流或多并发执行,建议 2GB 及以上。
- 端口:默认使用
5678,确保宿主机该端口可用;如果被占用,可以改成别的端口(比如5688)。
宿主机操作系统没有强制要求,Linux、macOS、Windows(WSL2)都可以跑通。下面以 Linux 为例演示,命令在 macOS 上基本一致。
编写 docker-compose.yml
为了让数据真正”活下来”,建议用 PostgreSQL 替换默认的 SQLite 数据库,并把数据目录挂载到宿主机。这样即使容器被删,重建也不会丢东西。
新建一个目录,比如 ~/n8n-deploy,进入后创建 docker-compose.yml:
version: "3.8"
services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=n8npass
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8npass
- GENERIC_TIMEZONE=Asia/Shanghai
- TZ=Asia/Shanghai
- N8N_HOST=localhost
- N8N_PORT=5678
- N8N_PROTOCOL=http
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
n8n_data:
几个关键点说明:
image: docker.n8n.io/n8nio/n8n是官方镜像源,与 README 中的docker run命令保持一致。GENERIC_TIMEZONE和TZ设为Asia/Shanghai,避免节点里出现”今天 8 点跑成昨天 16 点”这种时区错乱。volumes:部分把所有可变数据挂到命名卷,方便后续备份与迁移。depends_on加了健康检查条件,避免数据库还没准备好 n8n 就启动失败。
https://user-images.githubusercontent.com/10284570/173569848-c624317f-42b1-45a6-ab09-f0ea3c247648.png ### 启动与初始化
在 docker-compose.yml 所在目录执行:
docker compose up -d
-d 表示后台运行。第一次会拉取镜像,时间稍长。可以用 docker compose ps 查看运行状态,看到两个服务的 State 都是 running 且 postgres 健康检查通过就算成功。
打开浏览器访问 http://localhost:5678,第一次进入会要求设置一个拥有者账号(owner account)。这一步建议用一个强密码,因为这个账号拥有所有权限。之后可以再邀请其他用户。
如果一切顺利,就能看到 n8n 的画布界面,左侧是节点面板,中间是工作流编辑区,右侧是节点配置面板。

### 数据持久化与备份
n8n 的所有重要数据都集中在挂载卷里:
n8n_data:工作流定义、凭证加密信息、执行历史等。postgres_data:使用 PostgreSQL 时的数据库文件(如果用 SQLite,则全部在n8n_data内)。
定期备份这两份卷就够了。可以用一个简单的脚本:
#!/bin/bash
BACKUP_DIR=~/n8n-backups/$(date +%F)
mkdir -p "$BACKUP_DIR"
docker run --rm \
-v n8n-deploy_postgres_data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf /backup/postgres_data.tar.gz -C /source .
docker run --rm \
-v n8n-deploy_n8n_data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf /backup/n8n_data.tar.gz -C /source .
卷名 n8n-deploy_postgres_data 这种带前缀的格式,是 Docker Compose 自动生成的,格式为 _。如果项目目录改了名字,这里也要相应修改,建议把项目目录直接放在一个稳定路径下,比如 /opt/n8n。
恢复时把 tar 包解开回原卷即可。需要迁移到新服务器,只要把这两个卷的内容搬过去,就能保留全部工作流和凭证。
反向代理与 HTTPS
直接用 5678 端口对外服务在生产环境不太合适:要么端口号奇怪,要么没有 HTTPS。前端放一层 Nginx 或 Caddy 是更稳妥的做法。
Nginx 示例
server {
listen 80;
server_name n8n.example.com;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_buffering off;
client_max_body_size 50m;
}
}
proxy_buffering off 和 Upgrade/Connection 头是 n8n 文档明确强调的——它依赖 SSE/WebSocket 推送执行日志,开启缓冲会导致节点看起来”卡住”。
Caddy 示例
Caddy 自动申请证书,配置更短:
n8n.example.com {
reverse_proxy 127.0.0.1:5678 {
header_up Host {host}
header_up X-Real-IP {remote_addr}
header_up X-Forwarded-For {remote_addrs}
header_up X-Forwarded-Proto https
}
}
同时记得把 docker-compose.yml 里的 N8N_PROTOCOL 改成 https,并把 N8N_HOST 改成实际域名,否则触发器回调、OAuth 跳转会出现”地址错配”的问题。
### 第一个工作流:定时抓 RSS 发邮件
接下来做一个真正能跑的小工作流:每小时抓取指定 RSS 源,发现新条目就通过 SMTP 发邮件汇总。用它把整个”画布 + 凭证 + 触发器 + 条件判断”链路串起来。
新建工作流,按顺序添加以下节点:
- Schedule Trigger:设置
Mode为Every Hour,点击Cron模式可自定义更复杂的规则。 - RSS Feed Read:在
URL填入想要订阅的 RSS 地址,比如某个博客的 feed。 - Code 节点(可选):用一段 JS 把上一次的”已发送标题”和这次的标题对比,过滤掉已发送项。也可以用 n8n 内置的
Remove Duplicates节点按 URL 去重,省事一些。 - Send Email:选择 SMTP 凭证(首次使用时点
Create New Credential,填入发件邮箱的 SMTP 信息;端口和授权码需要到对应邮箱服务商的设置里查找,建议以官方文档为准)。 - 在节点之间画好连线,把 RSS 节点输出的
items[]接到 Code / 邮件节点的输入。
点击右上角 Save,再点 Execute Workflow 手动跑一次,看到收件箱收到邮件就算成功。最后把右上角的开关切到 Active,工作流就会按 Schedule 自动运行。

### 常见坑与排查
实际部署中几个容易踩的坑:
- 时区错位:默认 UTC 跑出来的”每天 8 点”在国内是下午 4 点。务必在
docker-compose.yml里设置GENERIC_TIMEZONE和TZ,重启后生效。 - 用户权限问题:n8n 容器内默认以
node用户运行,挂载到宿主机的目录如果权限太严会导致启动失败。如果必须用 root,可以在 environment 里加N8N_USER_FOLDER指定可写目录,或者放宽宿主机目录权限。 - 大工作流内存飙升:跑批量处理、调用大模型时,Node.js 堆内存可能膨胀。可以加环境变量
NODE_OPTIONS=--max-old-space-size=2048限制上限,再相应提高容器内存限制(deploy.resources.limits.memory)。 - 凭证丢失:备份只复制了卷文件,但忘了备份
n8n_data里的加密密钥(config文件)。换服务器后即使恢复了数据,凭证依然解不开——必须同时迁移密钥文件。 - Webhook 回调失败:很多节点(如 Telegram、GitHub)需要公网回调地址。如果只在内网访问,触发器测试通过但生产环境收不到消息,这时就要靠上面提到的反向代理 + HTTPS 来打通。
部署完成后,n8n 的玩法就完全打开了:从简单的”表单提交 → 写库”,到”AI Agent 拉取文档 → 总结 → 推送到飞书”,都靠同一个画布拼接。建议先从无代码的官方模板入手,把流程跑通再考虑自定义代码节点。需要更深入的配置细节(队列模式、执行模式、多实例),可以查看 n8n 官方文档,那里覆盖了从安装到生产调优的完整链路。

评论(0)