场景导入:Docker 隔离墙下的“数据库失联”
很多 N8N 大学的同学在折腾自动化时,都走过这样的弯路:为了省事,把 n8n 跑在 Docker 容器里,却发现 Workflow 想读取宿主机(服务器)上的 MySQL 数据时,死活连不上。报错信息通常很玄学,比如 Connection refused 或 Unknown database。
这其实不是 n8n 配置错了,而是 Docker 的网络隔离机制在“作祟”。容器默认是个独立的沙盒,它看不见宿主机的端口,自然也就连不上宿主机的数据库。今天这篇硬核教程,笔者就带你彻底打通这堵墙。
核心实操:三种方案打通任督二脉
根据你的 Docker 运行方式和环境,这里有三种最实用的连接方案。请根据你的实际情况选择。
方案一:使用宿主机网络模式(最简单,Linux 专属)
如果你是在 Linux 服务器上直接用 Docker CLI 运行 n8n,这是最快的方法。它让容器直接共享宿主机的网络栈,容器眼中的 localhost 就是宿主机的 localhost。
操作步骤:
- 停止并移除旧的 n8n 容器。
- 重新运行容器时,添加
--network host参数。 - 关键命令:
docker run -it --rm --name n8n -v ~/.n8n:/home/node/.n8n -e N8N_BASIC_AUTH_ACTIVE=true -e N8N_BASIC_AUTH_USER=admin -e N8N_BASIC_AUTH_PASSWORD=password --network host docker.n8n.io/n8nio/n8n
在这种模式下,你配置 MySQL 节点时,Host 直接填 127.0.0.1 或 localhost 即可。
方案二:使用宿主机 IP 地址(通用,全平台适用)
如果你在用 Docker Compose 或者在 Mac/Windows 上运行,--network host 可能不支持或行为不同。此时,最稳妥的办法是使用宿主机的局域网 IP。
操作步骤:
- 找到宿主机的 IP 地址。在 Linux 上使用
ip addr show,在 Mac/Windows 上使用ipconfig(通常是 192.168.x.x)。 - 确保宿主机的 MySQL 允许远程连接(通常监听 0.0.0.0 或该 IP)。
- 在 n8n 的 MySQL 节点中配置:
- Host: 填写宿主机的 IP(如
192.168.1.100),绝对不能填 localhost。 - Port: 通常为
3306。
注意:如果宿主机防火墙(如 ufw 或 firewalld)开启了,记得放行 3306 端口。
方案三:Docker 内部互联(最优雅,生产推荐)
如果你使用的是 Docker Compose 部署 n8n 和 MySQL,推荐使用 Docker 原生的网络桥接。这不仅安全,而且不受主机 IP 变动影响。
操作步骤:
- 创建一个自定义 Docker 网络(如果还没创建)。
- 将 n8n 和 MySQL 容器都加入这个网络。
- 在 n8n 的 MySQL 节点中配置:
- Host: 填写 MySQL 容器的名字(例如
mysql_db)。 - Port:
3306。
docker-compose.yml 示例片段:
version: '3.8'
services:
n8n:
image: docker.n8n.io/n8nio/n8n
networks:
- n8n-net
# ... 其他配置
mysql_db:
image: mysql:8.0
networks:
- n8n-net
ports:
- "3306:3306"
# ... 其他配置
networks:
n8n-net:
driver: bridge
避坑指南:那些年我们踩过的坑
在实际操作中,笔者见过太多同学在最后一步卡住。以下两个细节务必注意:
1. MySQL 的绑定地址 (bind-address)
这是最常见的坑。默认情况下,MySQL 可能只监听 127.0.0.1。这意味着它拒绝来自容器(被视为外部)的连接。
解决办法: 修改 MySQL 配置文件(通常是 /etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),将 bind-address 改为 0.0.0.0,然后重启 MySQL 服务。
2. 用户权限问题
即便网络通了,MySQL 用户也可能没有远程访问权限。默认用户 root@localhost 只能在本地登录。
解决办法: 登录 MySQL 命令行,执行类似以下语句(根据实际 IP 调整):
GRANT ALL PRIVILEGES ON *.* TO 'your_user'@'%' IDENTIFIED BY 'your_password';
FLUSH PRIVILEGES;
FAQ 常见问题
Q1: 为什么我填 localhost 连不上?
A: 在 Docker 容器内部,localhost 指的是容器自己,而不是宿主机。除非你用了 --network host 模式,否则永远不要在容器内的 n8n 中把 MySQL Host 填成 localhost。
Q2: 使用 Docker Compose 时,端口怎么映射?
A: 在 docker-compose.yml 的 MySQL 服务部分,必须指定 ports: ["3306:3306"]。这样宿主机和同一网络下的其他容器才能访问。
Q3: 连接时提示 "Access denied" 怎么办?
A: 这通常是权限问题。检查两点:1. MySQL 用户是否允许从对应 IP(或 %)访问;2. 密码是否正确。可以先用命令行工具(如 Navicat 或 mysql 命令)在宿主机上测试该用户能否登录。
总结与资源
连接 n8n 容器与宿主机 MySQL 的本质,是解决 Docker 的网络隔离问题。记住核心原则:要么让容器共享宿主机网络,要么让宿主机 MySQL 开放给外部访问。 笔者建议在生产环境使用 Docker Compose 管理容器,利用内部网络通信,最为稳定安全。
如果你在配置过程中遇到其他网络报错,欢迎在 N8N 大学社区发帖,我们一起排雷!