最近在 VPS 上折腾 Docker 的配置,遇到了几个挺让人头秃的问题。相信不少喜欢在服务器上搭建各种服务的兄弟们,也都有过类似的经历:明明本地跑得好好的镜像,一拉到服务器上报错连篇;或者是容器起是起来了,死活访问不到服务。

今天我就把平时遇到的高频坑点,还有对应的解决思路整理了一下,希望能帮到正在抓狂的你。

一、 容器启动后立即退出

这是新手最容易遇到的问题。你明明执行了 docker run,结果 docker ps 查不到进程,用 docker ps -a 一看,状态是 Exited

原因分析: Docker 容器的生命周期依赖于容器内 PID 为 1 的进程(主进程)。一旦主进程结束,容器就会随之停止。很多基础镜像(如 alpineubuntu)默认没有持续运行的前台进程,如果你启动时没有指定命令或者命令执行完了,容器自然就退出了。

解决方案:

  1. 确保前台运行: 启动命令必须是一个挂起的前台进程。例如 Nginx 需要 nginx -g 'daemon off;',而不是直接 nginx(后者会后台运行导致主进程退出)。
  2. 调试模式: 进入容器看看到底发生了什么。
    docker run -it --rm your-image sh
    # 或者对于已经退出的容器
    docker logs <container_id>
    
    查看日志输出,往往能直接发现是因为缺少配置文件还是命令路径错误。

二、 端口映射还是访问不通?

明明做了 -p 8080:80 的映射,防火墙也放行了,外网还是连不上。

原因分析: 除了防火墙问题,还有一个容易被忽视的点:容器内的服务是否监听了 0.0.0.0。很多服务默认只监听 127.0.0.1(本地回环),这意味着只有容器内部能访问,Docker 的端口映射根本抓不到流量。

解决方案: 修改应用的配置文件,确保服务监听在 0.0.0.0 上。以常见的 Web 服务为例:

  • Nginx: listen 0.0.0.0:80;
  • Node.js/Express: app.listen(3000, '0.0.0.0')
  • Python/Flask: app.run(host='0.0.0.0')

三、 权限问题导致的报错

特别是挂载目录(Volume)的时候,经常碰到容器内进程提示 Permission denied

原因分析: 宿主机和容器内的用户 ID(UID)可能不一致。比如你在宿主机是用 root 创建的文件夹,而容器内应用是以非 root 用户(如 uid 1000)运行的,这就产生了权限冲突。

解决方案:

  1. 修改宿主机权限: 简单粗暴,直接把挂载目录的权限放开(注意安全风险)。
    chown -R 1000:1000 /path/to/volume
    
  2. 指定用户运行:docker rundocker-compose.yml 中指定以 root 用户运行(需确认镜像支持)。
    user: "0:0"
    
  3. 使用命名空间: 比较高级的玩法,重新映射容器内的 UID,但这需要配置 Docker daemon,不太适合临时救急。

四、 Docker 网络无法解析域名

容器内跑个 ping baidu.combad address 或者 temporary failure in name resolution

原因分析: 通常是因为 Docker 守护进程的 DNS 配置继承了宿主机的 /etc/resolv.conf,或者宿主机本身的 DNS 设置有问题(比如有些 VPS 商商的默认 DNS 很拉胯)。

解决方案:

  1. 修改宿主机 DNS: 编辑 /etc/resolv.conf,换成公共 DNS,如 8.8.8.8223.5.5.5(阿里云)。
  2. 强制容器指定 DNS: 在启动命令中加入 --dns 参数。
    docker run --dns 8.8.8.8 --dns 223.5.5.5 your-image
    
  3. 如果是 Docker Desktop(Mac/Win): 在设置里手动修改 Docker Engine 的 DNS 配置。

五、 磁盘空间被吃满

跑了一段时间后,服务器报警提示磁盘满,一查发现 /var/lib/docker 占用了几十个 G。

原因分析: Docker 的镜像、停止的容器、未使用的卷和构建缓存都会占用空间。特别是构建镜像时产生的中间层,如果不定期清理,非常臃肿。

解决方案: 善用 Docker 自带的清理指令,但一定要看清楚参数,别把重要数据删了:

  1. 清理悬虚镜像:
    docker image prune
    
  2. 清理停止的容器:
    docker container prune
    
  3. 一键清理所有未使用资源(慎用):
    docker system prune -a --volumes
    
    这个命令会删除所有停止的容器、未被任何容器使用的网络、悬虚镜像以及所有未使用的构建缓存。

总结

Docker 虽然好用,但它的隔离机制也带来了不少排查上的“黑盒”属性。遇到问题时,不要慌,记住三板斧:

  1. 看日志: docker logs 是你的第一朋友。
  2. 进容器: docker exec -it <id> sh 实地考察。
  3. 查配置: 重点检查网络监听地址和文件权限。

希望这些踩坑经验能帮大家少走弯路,如果你还有更离奇的报错,欢迎在评论区交流,大家一起来“破案”!

标签: none

AI Skills Smart Station on Nick Launches

评论已关闭