最近在 Ubuntu 24.04 上重新把 n8n 的工作流自动化服务完整部署了一遍,包括把界面切换成中文版,整个过程用 Docker Compose 串联起来,配置干净,维护也省心。这篇文章就把我从零开始的操作步骤、关键配置、踩过的坑全部记录下来,给需要在 Linux 服务器上自托管 n8n 的开发者、自动化爱好者和运维朋友一个可以直接照做的参考方案。
先说结论:n8n 本身就已经内置了中文界面,严格来说不存在“中文版”这种独立发行版。所谓“中文版”,其实只需要在部署阶段设置好默认语言,或者在初次登录后手动切换就行。很多人一搜“中文版 n8n”,会以为是某个汉化过的镜像,其实完全没必要,官方镜像就自带多语言。我这次部署过程中,真正值得花心思的是 Docker Compose 的编排、数据库选择、时区设置、数据持久化和后续的备份升级,这些才是决定能不能长期稳定运行的关键。
1. 方案选型:为什么是 Ubuntu 24.04 + Docker Compose
1.1 n8n 是干什么的
n8n 是一个开源的工作流自动化工具,简单理解就是一个可以自己部署的 Zapier。它把各种应用和服务通过节点连接起来,比如定时抓取网页、发送邮件、调用大模型接口、同步表格数据、推送企业微信消息,都能靠工作流组合完成。和 SaaS 平台相比,数据完全掌握在自己手里,没有按执行次数收费的压力,节点和接口也没有那么多限制。尤其在国内使用,不用考虑平台服务不可达的问题,这对依赖 Webhook 和定时任务的人来说非常重要。
我用 n8n 已经有一段时间了,最常见的用途是把内部系统之间的重复操作串起来。比如某个系统生成报表后,自动触发 n8n 工作流,把数据整理后推送到企业群里;再比如每天定时拉取第三方 API 的数据,清洗后写进数据库。这些事如果纯手工用脚本做,每个都要单独维护一套任务调度和环境,用 n8n 统一管理之后,可视化界面里就能看到整个执行链路,出问题也好排查。
1.2 部署方式对比:原生安装、Docker 还是 Docker Compose
在 Ubuntu 24.04 上部署 n8n,基本有三条路可以走。
第一种是直接安装 Node.js 然后运行 npx n8n,这种方式对版本管理不友好,Node 版本一变就可能出兼容问题,而且 n8n 升级后要回滚很麻烦。第二种是用单个 docker run 命令启动容器,这种方式已经比原生安装好很多,但参数全堆在命令行里,可读性差,服务和数据库的关系还得额外手动管理。第三种就是用 Docker Compose,这也是我最终选择的方案。
Docker Compose 的好处在于把整个服务栈用 YAML 文件描述清楚,包含 n8n 应用和 PostgreSQL 数据库,只要一条docker compose up -d就能全部拉起。配置可以版本化管理,换服务器的时候拷走配置文件就能复现同样的环境。更实际的是,Compose 能管理服务依赖关系,比如等数据库健康检查通过后再启动 n8n,避免服务启动顺序导致连接失败的问题。
1.3 数据库选型:为什么不用默认的 SQLite
这里有一个很多人忽略的细节:n8n 默认使用 SQLite。如果只是个人测试,SQLite 完全够用,文件型数据库零配置,备份直接复制文件就行。但一旦工作流数量增多、执行频率变高,或者同一个 n8n 实例要供多个人使用,SQLite 的并发写入能力很快就会捉襟见肘。
改用一个单独的 PostgreSQL 容器,和 n8n 容器一起编排进同一个 Compose 文件,是目前比较合理的生产级配置。PostgreSQL 的并发处理能力、事务支持和备份工具生态都远好于 SQLite,而且后续如果要部署 n8n 的高可用集群,PostgreSQL 也是必要条件。代价无非是多一个容器,内存占用多一点,但这和稳定性比起来完全值得。
| 对比项 | SQLite | PostgreSQL |
|---|---|---|
| 部署复杂度 | 零配置 | 需要一个额外容器 |
| 并发能力 | 弱,写锁竞争明显 | 强,适合多人同时使用 |
| 数据备份 | 复制文件即可 | pg_dump 导出,支持定时备份 |
| 适用场景 | 本地实验、单用户小项目 | 生产环境、多用户、高频率执行 |
| 升级迁移 | 简单 | 更方便,工具链成熟 |
2. 环境准备:Ubuntu 24.04 基础配置与 Docker 安装
2.1 系统初始化与必要依赖
我用的是一台 Ubuntu 24.04 LTS 的服务器,纯净系统,没有装过 Docker。准备工作从更新软件源和升级现有软件包开始。
sudo apt update && sudo apt upgrade -y这一步看起来基础,但很重要。24.04 作为一个 LTS 版本,软件包更新频率不算高,定期升级可以避免系统自带软件和 Docker 源之间出现依赖冲突。
接着安装一些基础工具,比如 curl 和 ca-certificates,后面添加 Docker 官方软件源的时候会用到。
sudo apt install -y ca-certificates curl2.2 安装 Docker 与 Compose 插件
安装 Docker 有两种常用思路。一种是直接装 Ubuntu 软件源里的 docker.io,胜在省事,但版本一般偏旧,Docker Compose v2 插件可能不完整。另一种是添加 Docker 官方软件源,安装 docker-ce,我推荐这种,版本新,和官方文档的对齐程度高。
先把 Docker 官方的 GPG 密钥下载并保存到系统钥匙环里,这样 apt 才能验证软件包签名。
sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg然后根据系统版本写入 Docker 软件源地址。Ubuntu 24.04 的版本代号会通过VERSION_CODENAME自动读取,不需要手工修改。
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null软件源配置好之后,更新索引并安装 Docker Engine 全家桶,其中就包含 docker-compose-plugin。
sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin安装完成后,把当前用户加入 docker 组,这样操作 docker 命令时就不用每次都加 sudo。
sudo usermod -aG docker $USER提示:执行完 usermod 之后,需要重新登录一次让组权限生效。如果不想重新登录,可以用
newgrp docker临时切换当前会话。
验证安装是否成功:
docker --version docker compose version能看到 Docker 和 Compose 版本号输出,说明环境已经就绪。
3. 核心配置:docker-compose.yml 逐段拆解
3.1 目录规划与配置文件骨架
我习惯把所有服务放在一个独立目录里,这样无论是备份还是清理都边界清晰。
mkdir -p ~/n8n-deploy && cd ~/n8n-deploy在目录里创建 docker-compose.yml,整个服务栈就由两个容器组成:postgres 负责数据存储,n8n 负责应用逻辑。
services: postgres: image: postgres:16 restart: unless-stopped environment: POSTGRES_USER: n8n POSTGRES_PASSWORD: change_this_to_a_strong_password 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: n8nio/n8n:latest restart: unless-stopped depends_on: postgres: condition: service_healthy environment: DB_TYPE: postgresdb DB_POSTGRESDB_HOST: postgres DB_POSTGRESDB_PORT: 5432 DB_POSTGRESDB_USER: n8n DB_POSTGRESDB_PASSWORD: change_this_to_a_strong_password DB_POSTGRESDB_DATABASE: n8n N8N_DEFAULT_LOCALE: zh TZ: Asia/Shanghai GENERIC_TIMEZONE: Asia/Shanghai ports: - "5678:5678" volumes: - n8n_data:/home/node/.n8n volumes: postgres_data: n8n_data:新版 Docker Compose 不再需要写version字段,写了也不影响运行,但不写更干净。你需要在配置里把change_this_to_a_strong_password替换成自己的强密码,并且保证 postgres 和 n8n 两处的密码完全一致。
3.2 PostgreSQL 容器配置要点
postgres 容器用的是 postgres:16,这个版本是当前社区兼容性很好的版本。环境变量中POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB三个参数决定 PostgreSQL 初始化时创建的用户、密码和数据库名。这三个值要和后面 n8n 容器连接数据库时填写的完全对应,否则 n8n 启动时会报认证失败。
restart: unless-stopped保证服务器重启后容器自动拉起,除非你手动 stop,这个策略适合常驻服务。数据卷postgres_data挂载到/var/lib/postgresql/data,这行配置必须有,否则容器一删,数据库数据就全没了。
健康检查用的命令是pg_isready -U n8n -d n8n,这段逻辑很简单,就是探测 PostgreSQL 是否已经准备好接受连接。配合 n8n 服务的depends_on.condition: service_healthy,可以确保 PostgreSQL 完全启动后再启动 n8n,从根源上避免“数据库没起来,n8n 疯狂报连接错误后退出”的情况。
3.3 n8n 容器配置与中文化设置
n8n 镜像我写了n8nio/n8n:latest,最省心。如果追求版本可控,可以改成具体版本号,比如n8nio/n8n:1.60.0,升级时手动修改版本号再重新部署。对于大多数人,latest 足够,更新走docker compose pull && docker compose up -d就行。
环境变量里分成几组核心参数。
数据库连接组:DB_TYPE=postgresdb告诉 n8n 不要用默认的 SQLite;DB_POSTGRESDB_HOST=postgres是因为 Compose 会自动创建一个内部网络,服务名postgres可以直接解析为那个容器的 IP;其他几项就是数据库端口、用户、密码和库名,和 PostgreSQL 容器里的配置保持一致。
中文化设置组:N8N_DEFAULT_LOCALE=zh是让 n8n 首次启动就使用简体中文作为默认语言。如果你忘记设置这一项,也不要紧,登录之后在用户设置里还能手动切换。这里需要注意,语言代码是zh,不是zh-CN之类,写错可能导致设置不生效。设置这个环境变量之后,如果发现界面还是英文,通常是浏览器语言优先级或旧版本缓存问题,强制刷新一次浏览器基本能解决。
时区设置组:TZ=Asia/Shanghai影响的是容器内部系统时区,GENERIC_TIMEZONE=Asia/Shanghai影响的是 n8n 内部的时间处理逻辑。如果不设置GENERIC_TIMEZONE,定时触发节点 Schedule Trigger 可能会按 UTC 时间执行,导致你想象中早上 8 点执行的任务实际在下午 4 点才跑。这是很多人部署后最容易忽略的问题。
端口映射"5678:5678"将宿主机的 5678 端口转发到容器内的 n8n 默认端口。n8n 的官方默认端口就是 5678,如果你本机已经占用了这个端口,可以把左边改成任意未占用的端口,比如"5678:5678"改为"8080:5678",访问时就用对应端口。
3.4 数据卷与权限经验
配置末尾声明了两个数据卷:postgres_data和n8n_data。命名卷会由 Docker 创建并管理,首次启动时自动初始化目录。这里我推荐使用命名卷,而不是直接挂载宿主机目录,原因是权限问题经常在直接挂载时出现。
n8n 容器内部的运行用户是 node,它的 UID 是 1000。如果用宿主机的目录挂载到/home/node/.n8n,一旦目录所有者不是 UID 1000,n8n 容器会因为没有目录写权限而启动失败。命名卷则完全避开这个坑,Docker 会规范化权限,所以个人部署场景选择命名卷是最稳妥的。
4. 启动部署:从命令到中文界面落地
4.1 一键拉起服务与日志观察
在~/n8n-deploy目录里执行:
docker compose up -d-d参数表示后台运行,首次执行时 docker 会拉取 postgres:16 和 n8nio/n8n 两个镜像,视网络情况可能需要几十秒到几分钟。如果拉取镜像特别慢,大概率是 Docker Hub 网络问题,可以给 Docker 配置 registry mirror 镜像源来加快下载速度。
启动完成后,用下面的命令确认服务状态:
docker compose ps正常情况下,两个容器都应该是 Up 状态,而且 postgres 的 HEALTHY 健康状态会在启动后十几秒内变为 healthy。
如果想实时观察 n8n 容器的日志,用:
docker compose logs -f n8n看到日志里出现类似服务启动成功、端口监听的输出,就说明 n8n 已经正常运行了。此时打开浏览器访问http://你的服务器IP:5678,如果是在本地虚拟机部署,访问http://localhost:5678即可。
4.2 首次访问与管理员账号注册
首次访问 n8n 页面,会出现一个用户注册表单。按照页面提示填写邮箱、姓名和密码,创建的就是 n8n 的管理员账号。这一步只需要认真设置一个足够强度的密码就行,后续的数据库连接、节点认证都走工作流内的凭据配置,和这个账号无关。
完成注册后进入 n8n 主界面,这时候页面默认显示的语言取决于镜像内部默认值。如果你设置了N8N_DEFAULT_LOCALE=zh,界面直接就是中文;如果没设置或者不生效,接下来手动切一次即可。
4.3 手动切换为中文版界面
点击右上角的用户头像,在弹出的菜单里进入 Settings 设置页,找到 Language 语言选项,在下拉框里选择中文(简体),保存后页面会自动刷新,整个工作台界面会切换成中文。这是 n8n 原生的多语言功能,不需要额外安装任何汉化包,也不需要更换镜像。
注意:n8n 的中文翻译由社区持续维护,大部分核心界面和常见节点都有完整翻译,但个别比较新的节点或高级设置项可能仍显示英文,这属于正常现象。对实际使用基本没有阻碍。
4.4 验证工作流能正常执行
部署完成不代表一切正常,我习惯在初始化配置之后,立即创建一个最小工作流验证链路通畅。比如用 Manual Trigger 手动触发节点作为起点,连接一个 Set 设置数据节点,再连一个 NoOp 空操作节点,手动运行一次,看执行结果是否成功。这样能确认 n8n 应用本身没问题,而不至于等到需要真正跑业务时才发现某个底层组件有问题。
如果执行日志正常,说明 n8n 和 PostgreSQL 的交互、前端渲染、工作流引擎都正常工作。到这一步,一套完整的中文 n8n 服务已经跑起来了。
5. 对外访问:反向代理与 HTTPS 配置
5.1 三种常见访问方式
部署完成后默认通过http://IP:5678访问,这种方式适合内网实验环境。但如果 n8n 需要接收外部 Webhook,或者要通过手机在外网访问,继续用 IP 加端口的方式就有些局限。日常使用中,还可以配置一个反向代理域名,让 n8n 跑在标准的 443 端口并自动启用 HTTPS。
三种方式简单对比如下:
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 直接 IP:5678 | 配置简单,零额外操作 | 无加密,Webhook 地址不好看 | 内网测试、个人实验 |
| Nginx 反向代理 | 灵活,可控性好 | 证书申请与管理要自己处理 | 已有 Nginx 环境的用户 |
| Caddy 反向代理 | 自动申请和续期 HTTPS 证书 | 需要额外安装 Caddy | 追求省心的朋友 |
5.2 Caddy 反向代理示例
Caddy 配置很简单,可以自动申请 Let’s Encrypt 证书:
your.domain.com { reverse_proxy 127.0.0.1:5678 }这种情况下,最好把 docker-compose.yml 里 n8n 的端口映射改为只监听本机回环地址,避免 5678 端口暴露到公网,减少被扫描的风险。
ports: - "127.0.0.1:5678:5678"改了端口映射之后执行docker compose up -d重新创建容器,然后启动 Caddy 服务,访问https://your.domain.com就能直接打开 n8n。
5.3 配置域名后需要同步修改的环境变量
一旦使用域名访问,建议在 n8n 环境变量中补上N8N_HOST、N8N_PROTOCOL和WEBHOOK_URL,让 n8n 生成的回调地址和 Webhook 地址跟着域名走。
N8N_HOST: your.domain.com N8N_PROTOCOL: https WEBHOOK_URL: https://your.domain.com/不设置的话,工作流里的 Webhook 节点生成的外部地址可能是http://你的IP:5678这种形式,发给第三方系统后对方无法通过 HTTPS 回调用。这个细节在对接外部系统时非常容易踩中,建议一步到位配好。
6. 常见问题排查与日常维护
6.1 常见问题速查表
部署过程中最常遇到的问题,我整理成一张速查表,遇到对应现象直接对照处理。
| 现象 | 可能原因 | 排查与解决方法 |
|---|---|---|
| n8n 容器启动后立即退出 | 数据库密码不一致或数据库未就绪 | 用docker compose logs n8n查看报错,确认两个服务的密码一致 |
| 访问 5678 端口超时 | 云安全组或 UFW 防火墙未放行 | 执行sudo ufw allow 5678/tcp,并检查云控制台安全组规则 |
| 页面长时间英文,切换语言无效 | 浏览器缓存了旧版本前端资源 | 强制刷新浏览器,或清除站点缓存后重新加载 |
| 定时任务执行时间差 8 小时 | 缺少GENERIC_TIMEZONE环境变量 | 在 n8n 环境变量中补上GENERIC_TIMEZONE: Asia/Shanghai后重建容器 |
| 数据库数据随容器删除而丢失 | 未配置数据卷或误删了命名卷 | 查看docker volume ls确认卷存在,用docker compose down -v会清空数据,慎用 |
| 镜像拉取速度极慢 | Docker Hub 网络延迟 | 配置 Docker registry mirror 镜像源后重启 Docker |
6.2 数据备份与恢复
备份是部署完必须立刻考虑的事,否则数据丢了才后悔。n8n 的业务数据都保存在 PostgreSQL 里,所以最核心的备份是导出一个 SQL 文件。
cd ~/n8n-deploy docker compose exec postgres pg_dump -U n8n -d n8n > n8n_backup_$(date +%F).sql这条命令会在当前目录生成一个以当天日期命名的 SQL 备份文件。恢复时,把备份文件复制到服务器上,执行:
docker compose exec -T postgres psql -U n8n -d n8n < n8n_backup_2025-01-01.sql实际操作前建议先让 n8n 停止对外写入,比如docker compose stop n8n,恢复完成后再启动,避免数据不一致。
除了数据库,n8n 的~/.n8n目录里还保存了部分配置文件和一些本地文件,所以除了 pg_dump 之外,也建议把 n8n_data 卷里的内容打包一份。
6.3 升级和回滚
n8n 的新版本发布频率相当高,一些安全问题和新节点都依赖版本更新,所以我会定期升级。升级流程很简单:
cd ~/n8n-deploy docker compose pull docker compose up -d升级前一定先做一次数据库备份。因为新版本可能包含数据库迁移逻辑,迁移一旦失败或者出现不兼容,没有备份就只能干瞪眼。升级后观察日志,确认工作流的执行没有异样,再清理旧镜像:
docker image prune -f如果升级后发现功能异常,可以在 docker-compose.yml 里把镜像 tag 改回上一个版本号,然后重新docker compose up -d,回滚操作同样依赖之前那个备份文件。
6.4 一点经验体会
这套 deployment 跑下来,我最大的感受是 Docker Compose 把 n8n 的部署复杂度压到了最低,但真正决定一个自动化服务能否长期稳定运行的,不是那一条启动命令,而是部署前对数据持久化、时区、语言、端口暴露、备份策略的考虑是否到位。
我个人比较习惯在 compose 文件旁边放一个 README,记录部署时间、管理员邮箱、数据卷名称、上一次备份的路径。因为 n8n 这种自托管服务,往往不会天天去操作它,等半年后需要升级时,这些记录能帮你快速回忆当时的部署决策。另外,强烈建议启用 Docker 的restart策略,配合服务器的进程守护,保证断电重启后服务能自动恢复。自动化工具的使命就是省心,部署完之后,它越安静,说明你做得越对。