故障排除.md 7.7 KB

Docker部署故障排除指南

常见问题与解决方案

1. 端口被占用 ⚠️

错误信息:

Ports are not available: exposing port TCP 0.0.0.0:8888 -> 0.0.0.0:0: 
listen tcp 0.0.0.0:8888: bind: address already in use

原因: 8888端口已被其他进程占用

解决方案A - 停止占用进程:

# 1. 查找占用端口的进程
lsof -i :8888
# 或
netstat -tlnp | grep 8888

# 2. 停止进程(替换PID为实际进程ID)
kill <PID>

# 3. 重新启动Docker
docker-compose up -d

解决方案B - 更换端口:

# 修改 docker-compose.yml
ports:
  - "9999:8888"  # 使用9999端口

# 或使用命令行
docker run -d -p 9999:8888 sign-server:latest

# 访问地址变为: http://localhost:9999

2. 容器名称冲突 ⚠️

错误信息:

The container name "/sm2-sign-server" is already in use

解决方案:

# 删除旧容器
docker rm -f sm2-sign-server

# 重新启动
docker-compose up -d

3. 镜像构建失败 ⚠️

错误信息:

ERROR: failed to solve: failed to compute cache key

可能原因: bin目录或lib目录不存在

解决方案:

# 1. 确保已编译(在本地有Java环境时)
javac -encoding UTF-8 -d bin -cp "lib/*" $(find src -name "*.java")

# 2. 检查目录结构
ls -la bin/
ls -la lib/

# 3. 重新构建
docker-compose build --no-cache
docker-compose up -d

4. 容器启动后立即退出 ⚠️

检查方法:

# 查看容器状态
docker ps -a

# 查看日志
docker logs sm2-sign-server

常见原因和解决方案:

原因1: Java版本不兼容

# 修改Dockerfile使用不同的Java版本
FROM openjdk:11-jre-slim  # 改用Java 11

原因2: 类文件缺失

# 确保所有class文件存在
find bin -name "*.class"

# 如果缺失,重新编译
javac -encoding UTF-8 -d bin -cp "lib/*" $(find src -name "*.java")

5. 无法访问服务 ⚠️

症状: curl无法连接或超时

排查步骤:

步骤1: 检查容器是否运行

docker ps
# 确保STATUS显示"Up"

步骤2: 检查端口映射

docker port sm2-sign-server
# 应该显示: 8888/tcp -> 0.0.0.0:8888

步骤3: 检查容器日志

docker logs sm2-sign-server
# 查看是否有错误信息

步骤4: 测试容器内部

# 进入容器
docker exec -it sm2-sign-server sh

# 在容器内测试
wget -O- http://localhost:8888/api/health

步骤5: 检查防火墙

# CentOS/RHEL
firewall-cmd --list-ports

# Ubuntu
ufw status

# 如需开放端口
firewall-cmd --permanent --add-port=8888/tcp
firewall-cmd --reload

6. Docker未安装 ⚠️

错误信息:

docker: command not found

解决方案:

# 安装Docker (Linux)
curl -fsSL https://get.docker.com | sh
systemctl start docker
systemctl enable docker

# 验证安装
docker --version
docker-compose --version

7. 权限不足 ⚠️

错误信息:

permission denied while trying to connect to the Docker daemon

解决方案:

# 方案A: 添加用户到docker组
sudo usermod -aG docker $USER
# 重新登录生效

# 方案B: 使用sudo
sudo docker-compose up -d

8. 内存不足 ⚠️

症状: 容器频繁重启或OOM错误

解决方案:

# 限制内存使用
docker run -d \
  --name sm2-sign-server \
  -p 8888:8888 \
  --memory="256m" \
  --memory-swap="512m" \
  sign-server:latest

# 或修改docker-compose.yml
services:
  sign-server:
    deploy:
      resources:
        limits:
          memory: 256M

9. 环境变量不生效 ⚠️

症状: 传入的私钥未使用

检查:

# 查看容器环境变量
docker exec sm2-sign-server env | grep SM2

正确设置方式:

docker-compose.yml:

services:
  sign-server:
    environment:
      SM2_PRIVATE_KEY: "您的私钥"
      REQ_ORG_NO: "您的机构号"

命令行:

docker run -d \
  -e SM2_PRIVATE_KEY="私钥" \
  -e REQ_ORG_NO="机构号" \
  sign-server:latest

10. 配置文件挂载失败 ⚠️

错误: 配置文件不生效

正确挂载方式:

# 1. 创建配置文件
cat > config.properties << EOF
reqOrgNo=201811200001003
priKey=您的私钥
EOF

# 2. 挂载到容器
docker run -d \
  -v $(pwd)/config.properties:/app/config.properties:ro \
  sign-server:latest

# 注意: 使用绝对路径或$(pwd)

docker-compose.yml:

services:
  sign-server:
    volumes:
      - ./config.properties:/app/config.properties:ro

快速诊断命令

# 一键诊断脚本
#!/bin/bash

echo "=== Docker状态 ==="
docker --version
echo ""

echo "=== 容器状态 ==="
docker ps -a | grep sm2-sign-server
echo ""

echo "=== 端口占用 ==="
lsof -i :8888
echo ""

echo "=== 容器日志(最后20行)==="
docker logs --tail 20 sm2-sign-server
echo ""

echo "=== 网络测试 ==="
curl -s http://localhost:8888/api/health || echo "❌ 服务不可访问"

日志查看技巧

# 实时查看日志
docker logs -f sm2-sign-server

# 查看最近100行
docker logs --tail 100 sm2-sign-server

# 查看带时间戳的日志
docker logs -t sm2-sign-server

# 查看最近10分钟的日志
docker logs --since 10m sm2-sign-server

完全重置

如果以上都不行,完全重置:

# 1. 停止并删除所有相关容器
docker stop sm2-sign-server
docker rm sm2-sign-server

# 2. 删除镜像
docker rmi sign-server:latest

# 3. 清理缓存(可选)
docker system prune -a

# 4. 重新构建和启动
docker-compose build --no-cache
docker-compose up -d

# 5. 验证
docker logs -f sm2-sign-server

获取帮助

如果问题仍未解决:

  1. 查看完整日志:

    docker logs sm2-sign-server > docker.log
    cat docker.log
    
  2. 检查系统资源:

    df -h          # 磁盘空间
    free -h        # 内存
    docker stats   # 容器资源使用
    
  3. 容器详细信息:

    docker inspect sm2-sign-server
    

常用管理命令速查

# 启动
docker-compose up -d

# 停止
docker-compose down

# 重启
docker-compose restart

# 查看状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 重新构建
docker-compose build --no-cache

# 强制重启
docker-compose down
docker-compose up -d --force-recreate

# 更新镜像
docker-compose pull
docker-compose up -d

性能优化建议

1. 使用更小的基础镜像

# 当前使用 (85MB)
FROM openjdk:8-jre-alpine

# 备选方案 (更小)
FROM adoptopenjdk:8-jre-hotspot-alpine

2. 限制日志大小

docker run -d \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  sign-server:latest

3. 健康检查

在Dockerfile添加:

HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --quiet --tries=1 --spider http://localhost:8888/api/health || exit 1

最佳实践

  1. ✅ 使用docker-compose管理容器
  2. ✅ 通过环境变量传递敏感信息
  3. ✅ 设置合理的资源限制
  4. ✅ 配置日志轮转
  5. ✅ 启用自动重启(restart: unless-stopped)
  6. ✅ 定期更新基础镜像
  7. ✅ 使用健康检查
  8. ✅ 生产环境使用HTTPS

紧急恢复

服务完全失败时的快速恢复:

#!/bin/bash
# emergency-recovery.sh

echo "开始紧急恢复..."

# 停止所有
docker-compose down
docker rm -f sm2-sign-server

# 清理
docker system prune -f

# 重建
docker-compose build --no-cache

# 启动
docker-compose up -d

# 等待
sleep 5

# 测试
curl http://localhost:8888/api/health

echo "恢复完成"

提示: 将此文档保存为 故障排除.md,遇到问题时快速查阅。