Docker 出问题时怎么查:不重装,像物业一样找到是哪间房出了问题
当 Docker 报错时,很多人会做同一件事:关掉 Docker Desktop,重开;不行就删容器;再不行就重装。
这样做有时真的能“暂时好了”,但它没有让你知道问题出在哪里。下次遇到同样的问题,你还是会焦虑。
更麻烦的是:如果你在不知道数据卷作用的情况下乱删,真正重要的数据反而可能被误删。
所以这篇文章先给你一条最重要的原则:
Docker 出问题时,先看状态,再看日志,再看连接。最后才考虑删除重建。
你不需要成为运维工程师。你只需要把 Docker 当成一栋楼:
- 打不开网页,先看楼外门牌有没有挂好;
- 两个服务连不上,先看内部电话线有没有接上;
- 容器一直重启,先看房间里开门后发生了什么;
- 数据不见了,先看是不是接错了储物柜;
- 权限报错,先看谁没有拿到该有的钥匙。
按这个顺序排查,绝大多数新手问题都不会再显得神秘。
先把这 5 条“救火命令”收藏起来
你不需要一次学会几十条命令。下面五条足够覆盖最常见情况。
| 命令 | 它在生活中像什么 | 你用它回答什么问题 |
|---|---|---|
docker compose ps |
看整栋楼的入住名单 | n8n 和数据库到底有没有在运行? |
docker compose logs -f n8n |
调出 n8n 房间的监控记录 | n8n 为什么启动失败或重启? |
docker compose logs -f postgres |
调出数据库房间的监控记录 | 数据库有没有正常准备好? |
docker compose config |
让物业把配置册重新读一遍 | 变量、端口、缩进最后到底是什么样? |
docker inspect 容器名 |
查房屋档案 | 实际挂了什么端口、网络、数据卷? |
你会发现,这些命令不是用来“修复”的,而是用来先看清事实的。
这非常重要。因为 Docker 的很多问题不是程序坏了,而是你以为它按 A 方式启动了,实际上它按 B 方式启动了。
情况一:浏览器打不开 n8n
你输入:
http://localhost:5678
浏览器却说无法访问 。
先不要改端口,也不要删容器。请先在 n8n 的配置文件夹中输入:
docker compose ps
你会看到类似下面几种结果。
结果 A:n8n 显示 running,并且有端口
例如:
127.0.0.1:5678->5678/tcp
这表示:楼外的 5678 门牌已经接到 n8n 房间里的 5678 窗口。此时如果浏览器仍打不开,再看日志:
docker compose logs --tail=100 n8n
重点不要只看最后一句。往上找第一条真正的 ERROR,它通常才是原因。
结果 B:n8n 根本没有 running
这表示房间并没有正常开门。可能是它刚启动就失败了。
立刻执行:
docker compose logs -f n8n
然后观察最早出现的错误。最常见的是数据库连不上、环境变量没填、端口被占用,或者 YAML 配置没有按预期加载。
结果 C:n8n 在运行,但没有显示端口
这说明 n8n 房间在楼里营业,但你没有给它挂对外门牌。
检查 compose.yaml 是否包含:
ports:
- "127.0.0.1:5678:5678"
如果没有,添加后执行:
docker compose up -d
情况二:提示 port is already allocated
你可能看到过这句话:
Bind for 0.0.0.0:5678 failed: port is already allocated
先把它翻译成人话:
这栋楼外的 5678 门牌,已经被别的店铺占用了。Docker 不能把同一个门牌同时挂给两个房间。
这不代表 n8n 坏了,也不代表 Docker 必须重装。
你有两种选择
第一种:原来占用 5678 的服务已经不用了。
先找出 Docker 中正在运行的容器:
docker ps
确认名称后,再停止并删除那个不再需要的旧容器:
docker stop 旧容器名
docker rm 旧容器名
第二种:你想让两个服务同时存在。
那就改 n8n 的左边端口:
ports:
- "127.0.0.1:18080:5678"
现在的意思是:
- 楼外的新门牌叫 18080;
- n8n 房间内原来的窗口仍然叫 5678。
浏览器改为打开:
http://localhost:18080
改端口时 ,优先改左边。左边是你电脑的门牌,右边是 n8n 房间内部习惯使用的窗口。
情况三:n8n 提示数据库连接失败
这是最常见、也最容易被“localhost”带偏的问题。
你可能会看到类似:
Connection refused
或者:
Could not connect to database
先别慌。把它想成 n8n 想给数据库打电话,但电话没有接通。原因只会在三类地方:数据库房间没开门、电话线没接上、号码拨错了。
第一步:确认数据库真的开门了
docker compose ps postgres
如果 PostgreSQL 不是 running,请看它自己的日志:
docker compose logs --tail=100 postgres
不要先盯着 n8n。n8n 只是打电话的人;如果接电话的数据库房间根本没开门,先修数据库才有意义。
第二步:确认号码没有写成 localhost
请检查 n8n 配置是否是:
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
不要写:
DB_POSTGRESDB_HOST: localhost
为什么?
因为 n8n 容器里的 localhost,指的是 n8n 房间自己。它不是你的电脑,也不是 PostgreSQL 房间。
正确的 postgres 是内部电话簿中的房间名;5432 是 PostgreSQL 房间里的接待号码。
第三步:确认密码小信封没有写错
执行:
docker compose config
它会把 .env 里的变量代入并展示最终配置。你要确认:
POSTGRES_PASSWORD不是空的;- n8n 和 PostgreSQL 使用的是同一组变量;
.env确实和compose.yaml放在同一个文件夹。
如果你在 .env 中写错变量名,Docker 不会猜你的意思。它只会按实际看到的内容运行。
情况四:容器一直重启,像“活不过十秒”
在 Docker Desktop 中看到容器不断从 Restarting 变成 Up,又很快回到 Restarting,通常不是 Docker 在抽风。
它表示:房间打开了,但里面的主程序一启动就遇到问题;由于你设置了:
restart: unless-stopped
物业会不断尝试重新开门。
这时最有价值的不是重启 Docker Desktop,而是:
docker compose logs -f 服务名
例如:
docker compose logs -f n8n
从第一条 ERROR 开始看。常见原因包括:
- 数据库尚未准备好;
.env中的变量为空;- 端口冲突;
- 配置文件缩进错误;
- 更新镜像后,某个旧配置不再适用。
你可以把日志理解成房间里的监控录像。房间为什么关门,录像通常比猜测可靠得多。
情况五:重建后,工作流或凭据“看起来没了”
这时请先停下。不要再执行任何 prune、不要随手删 volume、也不要立刻重新注册一套全新的 n8n。
你要先判断:资料是真的没了,还是新房间没有接回原来的储物柜。
第一步:看储物柜还在不在
docker volume ls
找到名称里带有 n8n_data 的 volume。Compose 可能在前面加上项目名,这是正常的。
第二步:看当前 n8n 是否接对了柜子
docker inspect n8n
在输出中查找 Mounts。你希望看到:
Type是volume;- 名称与之前的数据卷对应;
- 容器内目标路径是
/home/node/.n8n。
第三步:确认主钥匙没有被换掉
检查 .env:
N8N_ENCRYPTION_KEY=...
它必须与原先部署时使用的值一致。
数据卷像储物柜,N8N_ENCRYPTION_KEY 像保险文件的主钥匙。柜子还在,不代表换了钥匙后仍能顺利打开加密内容。
最危险的一条命令
docker compose down -v
普通的 docker compose down 只是关房、拆掉容器;带 -v 则会连这个项目的储物柜一起删除。
除非你明确要“从零开始且不要任何旧数据”,否则不要使用 -v。
Docker 官方也提醒,volume 独立于容器生命周期;它能在容器删除后保留数据,但在你明确删除 volume 时,数据当然也会被清除。Docker 官方说明
情况六:提示 permission denied
这句话的意思是:程序找到了文件柜,但没有钥匙。
它最常发生在你使用类似下面的配置时:
volumes:
- ./某个本机文件夹:/workspace
这叫 bind mount,意思是把电脑上真实的文件夹直接搬进容器。它很方便,但也会把宿主机的权限问题一起带进来。
新手先这样判断:
- 如果你只是想保存 n8n 或数据库自己的内部资料,请优先用 named volume。
- 如果你必须让容器读取电脑上的某个文件夹,再使用 bind mount。
- 不要一上来就用
chmod -R 777解决权限。它像为了让员工能拿文件,直接把整个办公室的门全部拆掉,短期省事,长期风险很高。
在 Windows 或 macOS 上,也要确认 Docker Desktop 被允许访问你挂载的文件夹。否则你以为已经把文件箱搬进房间,实际上物业根本不允许搬运。
请记住这张“从外到内”的排查路线
当你下次遇到问题,不用重新翻整篇文章。按下面路线走就可以:
浏览器打不开
↓
先看 docker compose ps
↓
服务没运行:看 docker compose logs
↓
服务运行但打不开:看 ports 是否存在、端口是否被占
↓
n8n 连不上数据库:看 postgres 是否运行、地址是否写 postgres、变量是否正确
↓
数据不见:先看 volume 和 N8N_ENCRYPTION_KEY,绝不先删除
这套路线的价值在于:你不是在“试命令”,而是在一层层缩小范围。
先站在楼外看门牌,再进入楼里看哪间房,最后才检查房间里的电话线、储物柜和钥匙。这样一来,Docker 就不再像一个黑箱。
结尾:你不需要怕 Docker,但要养成正确的顺序
Docker 真正让人焦虑的,从来不是命令本身,而是“我不知道删掉会发生什么”。
而你现在已经掌握了最实用的安全感来源:
容器可以重建;日志用来找原因;端口决定入口;网络决定谁能通信;数据卷和密钥决定成果能不能回来。
下一次出问题时,先不要重装。先打开终端,运行:
docker compose ps
从这一行开始,你就已经比过去那个只能靠猜的自己,更接近真正能掌控 Docker 了。