Docker 常见问题和解决方案
容器启动问题
1. 容器立即退出
症状:容器启动后立即停止
# 查看容器退出状态
docker ps -a
docker inspect myapp --format='{{.State.ExitCode}}'
# 查看容器日志
docker logs myapp
docker logs --tail 100 myapp
常见原因和解决方案:
# 原因 1: 主进程退出
# 解决: 使用前台进程
CMD ["nginx", "-g", "daemon off;"]
# 原因 2: 没有可执行的命令
# 解决: 指定正确的 CMD 或 ENTRYPOINT
# 原因 3: 权限问题
# 解决: 检查文件权限
docker run -it --rm myapp sh
ls -la /app
# 原因 4: 依赖缺失
# 解决: 检查依赖是否安装
docker run -it --rm myapp sh
node --version
2. 容器无法启动
# 端口已被占用
Error: Bind for 0.0.0.0:8080 failed: port is already allocated
# 解决方案
# 1. 查找占用端口的进程
lsof -i:8080
netstat -tulpn | grep 8080
# 2. 停止占用端口的容器
docker ps | grep 8080
docker stop container_name
# 3. 使用不同端口
docker run -d -p 8081:80 nginx
3. 内存不足
# 错误信息
Cannot allocate memory
# 查看系统资源
docker info | grep -i memory
free -h
# 解决方案
# 1. 限制容器内存
docker run -d --memory="512m" --memory-swap="1g" myapp
# 2. 清理未使用的资源
docker system prune -a --volumes
# 3. 增加 Docker 内存限制(Docker Desktop)
网络问题
1. 容器无法访问外网
# 测试网络连接
docker exec myapp ping google.com
docker exec myapp curl https://www.baidu.com
# 检查 DNS 配置
docker exec myapp cat /etc/resolv.conf
# 解决方案
# 1. 指定 DNS 服务器
docker run -d --dns 8.8.8.8 --dns 8.8.4.4 myapp
# 2. 使用 host 网络模式
docker run -d --network host myapp
# 3. 检查防火墙规则
sudo iptables -L
sudo firewall-cmd --list-all
2. 容器间无法通信
# 检查容器网络
docker network inspect bridge
# 解决方案
# 1. 创建自定义网络
docker network create mynetwork
docker run -d --network mynetwork --name app1 myapp
docker run -d --network mynetwork --name app2 myapp
# 2. 连接到同一网络
docker network connect mynetwork existing_container
# 3. 使用容器名访问
docker exec app1 ping app2
docker exec app1 curl http://app2:3000
3. 端口映射不生效
# 检查端口映射
docker port myapp
# 常见问题
# 1. 容器内应用监听 127.0.0.1
# 解决: 改为监听 0.0.0.0
# 2. 防火墙阻止
# 解决: 开放端口
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
# 3. 端口映射错误
docker run -d -p 8080:80 nginx # 主机:容器
数据卷问题
1. 数据丢失
# 检查数据卷
docker volume ls
docker volume inspect mydata
# 备份数据
docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
alpine tar czf /backup/backup.tar.gz -C /data .
# 恢复数据
docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/backup.tar.gz -C /data
2. 权限问题
# 症状: Permission denied
# 检查权限
docker exec myapp ls -la /data
# 解决方案
# 1. 更改文件所有者
docker exec -u root myapp chown -R appuser:appuser /data
# 2. 在 Dockerfile 中设置
RUN chown -R appuser:appuser /app/data
# 3. 使用正确的用户运行
docker run -d --user 1001:1001 myapp
3. 挂载路径不存在
# 错误: no such file or directory
# 解决方案
# 1. 创建目录
mkdir -p /host/path
# 2. 使用绝对路径
docker run -d -v /absolute/path:/container/path myapp
# 3. 使用命名卷
docker volume create mydata
docker run -d -v mydata:/data myapp
镜像问题
1. 拉取镜像失败
# 网络问题
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
# 解决方案
# 1. 配置镜像加速器
sudo vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
]
}
sudo systemctl restart docker
# 2. 使用代理
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
# 3. 手动下载镜像
docker pull registry.cn-hangzhou.aliyuncs.com/library/nginx:latest
docker tag registry.cn-hangzhou.aliyuncs.com/library/nginx:latest nginx:latest
2. 镜像构建失败
# 查看构建日志
docker build -t myapp . --progress=plain
# 常见问题
# 1. Dockerfile 语法错误
# 解决: 检查 Dockerfile 语法
# 2. 网络超时
# 解决: 使用镜像源
RUN npm config set registry https://registry.npmmirror.com
# 3. 磁盘空间不足
# 解决: 清理空间
docker system prune -a --volumes
df -h
3. 镜像过大
# 查看镜像大小
docker images
# 优化方案
# 1. 使用 alpine 基础镜像
FROM node:18-alpine
# 2. 多阶段构建
FROM node:18 AS builder
# ...
FROM node:18-alpine
COPY --from=builder /app/dist .
# 3. 清理缓存
RUN npm ci && \
npm cache clean --force && \
rm -rf /tmp/*
# 4. 使用 .dockerignore
性能问题
1. 容器运行缓慢
# 查看资源使用
docker stats myapp
# 解决方案
# 1. 限制资源使用
docker run -d \
--cpus="2.0" \
--memory="2g" \
--memory-swap="2g" \
myapp
# 2. 使用 SSD 存储
# 3. 优化应用代码
# 4. 使用缓存
2. 磁盘空间占用过多
# 查看磁盘使用
docker system df
docker system df -v
# 清理方案
# 1. 删除未使用的资源
docker system prune -a --volumes
# 2. 删除特定资源
docker container prune
docker image prune -a
docker volume prune
# 3. 限制日志大小
docker run -d \
--log-opt max-size=10m \
--log-opt max-file=3 \
myapp
# 4. 配置全局日志限制
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
3. 容器启动慢
# 原因分析
# 1. 镜像过大
# 2. 健康检查时间过长
# 3. 依赖服务未就绪
# 解决方案
# 1. 优化镜像大小
# 2. 使用 depends_on 和 healthcheck
version: '3.8'
services:
db:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
app:
image: myapp
depends_on:
db:
condition: service_healthy
# 3. 使用预热容器
docker-compose up -d db
sleep 30
docker-compose up -d app
Docker Desktop 问题
1. Docker Desktop 无法启动
# Windows
# 1. 检查 WSL 2
wsl --list --verbose
wsl --set-default-version 2
# 2. 重置 Docker Desktop
# Settings -> Troubleshoot -> Reset to factory defaults
# 3. 重新安装 Docker Desktop
# Mac
# 1. 检查系统版本
sw_vers
# 2. 重置 Docker
# Troubleshoot -> Reset to factory defaults
# 3. 检查磁盘空间
df -h
2. WSL 2 集成问题
# 启用 WSL 2
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# 设置默认版本
wsl --set-default-version 2
# 转换现有发行版
wsl --list --verbose
wsl --set-version Ubuntu 2
Docker Compose 问题
1. 服务无法启动
# 验证配置文件
docker-compose config
# 查看详细日志
docker-compose up --verbose
# 常见问题
# 1. 端口冲突
# 解决: 更改端口映射
# 2. 依赖服务未就绪
# 解决: 使用 depends_on 和 healthcheck
# 3. 环境变量缺失
# 解决: 检查 .env 文件
2. 服务间网络问题
# 检查网络
docker-compose ps
docker network ls
docker network inspect projectname_default
# 解决方案
# 1. 使用服务名访问
services:
web:
image: nginx
api:
image: myapi
environment:
API_URL: http://web:80
# 2. 自定义网络
networks:
frontend:
backend:
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
最佳实践
故障排查流程
1. 收集信息
docker version
docker info
docker ps -a
docker logs myapp
docker inspect myapp
docker stats
2. 检查配置
# Dockerfile
cat Dockerfile
# docker-compose.yml
docker-compose config
# 环境变量
docker exec myapp env
3. 网络调试
docker network ls
docker network inspect bridge
docker exec myapp ping other_container
docker exec myapp curl http://other_container
4. 资源检查
docker stats
docker system df
free -h
df -h
5. 日志分析
docker logs myapp
docker logs --tail 100 --follow myapp
journalctl -u docker
调试工具
1. 进入容器调试
# Bash
docker exec -it myapp bash
# Sh (Alpine)
docker exec -it myapp sh
# 以 root 用户进入
docker exec -it -u root myapp bash
# 使用特定工作目录
docker exec -it -w /app myapp bash
2. 安装调试工具
# Debian/Ubuntu
docker exec -it myapp bash
apt-get update
apt-get install -y curl wget telnet net-tools
# Alpine
docker exec -it myapp sh
apk add --no-cache curl wget busybox-extras
# CentOS/RHEL
docker exec -it myapp bash
yum install -y curl wget telnet net-tools
3. 网络调试
# 测试连接
docker exec myapp curl -v http://api.example.com
docker exec myapp wget -O- http://api.example.com
docker exec myapp ping google.com
# 查看端口
docker exec myapp netstat -tulpn
docker exec myapp ss -tulpn
# DNS 解析
docker exec myapp nslookup google.com
docker exec myapp dig google.com
4. 文件系统调试
# 查看文件
docker exec myapp ls -la /app
docker exec myapp cat /app/config.json
# 复制文件
docker cp myapp:/app/logs/error.log ./
docker cp ./config.json myapp:/app/
# 查看磁盘使用
docker exec myapp df -h
docker exec myapp du -sh /app/*