Skip to main content

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/*

相关资源