宝塔docker使用指南
·
Vanguard
总结
实际步骤
- 确保 compose(可配置多个镜像, 插入.dev 等) 文件准确 dockerfile(部署单个镜像) 文件准确
- 上传 compose 文件 .env.test 文件 至 /www/server/panel/data/compose/oversea_test/.env.test
- 根据文档中编写好的命令来编译镜像文件并导出压缩 上传至宝塔
- 根据 compose 配置 .env.test 配置 新镜像文件, 创建容器
- 持续更新 编译新镜像, 更新 compose 更新 .env (提前删除旧容器文件夹 避免影响)
概念解释
关系:Dockerfile 用于 构建镜像;Docker Compose 用于 运行一个或多个容器服务、定义它们如何组合、互联、配置。换句话说:先用 Dockerfile 定义服务镜像,再用 Compose 将服务镜像与其他服务一起运行。
问题案例
如果在 ARM64 Mac (Apple Silicon) 上构建镜像,直接传输到 AMD64 Linux 服务器会出现平台不匹配错误。
解决方案
方案一: 本地构建 AMD64 镜像 (推荐)
在本地 Mac 构建 AMD64 架构镜像:
# 1. 构建 AMD64 架构镜像
npm run docker:build:test:amd64
# 或生产环境
npm run docker:build:prod:amd64
# 2. 导出镜像
npm run docker:save:test
# 或生产环境
npm run docker:save:prod
# 3. 压缩镜像 (可选)
gzip oversea-service-test.tar
# 4. 上传到服务器
scp oversea-service-test.tar.gz user@server:/path/to/app/
在服务器加载镜像:
# 1. 解压 (如果压缩了)
gunzip oversea-service-test.tar.gz
# 2. 加载镜像
docker load -i oversea-service-test.tar
# 3. 验证镜像
docker images | grep oversea-service
# 4. 确保环境文件存在
# 方式 1: 上传 .env.test 文件
scp .env.test user@server:/path/to/app/.env.test
# 方式 2: 在服务器创建
cat > .env.test << 'EOF'
NODE_ENV=test
PORT=3000
JWT_SECRET=your_secret
# ... 其他配置
EOF
# 5. 确保 docker-compose 文件存在
ls -la docker-compose.test.yml
# 6. 启动容器
docker-compose -f docker-compose.test.yml up -d
# 7. 查看状态
docker ps
docker logs -f oversea_service_test
环境文件检查清单
在服务器上运行容器前,确保:
# 1. 检查环境文件是否存在
ls -la .env.test
# 2. 检查文件不是目录
file .env.test
# 输出应该是: .env.test: ASCII text
# 3. 检查文件权限
chmod 644 .env.test
# 4. 验证文件内容
cat .env.test | head -5
# 5. 确保必要的配置项存在
grep -E "NODE_ENV|PORT|JWT_SECRET|MONGO" .env.test
常见错误处理
错误 1: Platform mismatch
The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64)
解决:
# 重新构建 AMD64 镜像
docker build --platform linux/amd64 -t oversea-service:test .
# 或在 docker-compose.yml 中指定 platform
platform: linux/amd64
错误 2: Not a directory
Are you trying to mount a directory onto a file (or vice-versa)?
解决:
# 确保 .env.test 是文件,不是目录
rm -rf .env.test # 如果是目录
touch .env.test # 创建文件
vim .env.test # 添加配置
# 或不使用文件挂载,改用 env_file
# docker-compose.yml 中:
env_file:
- .env.test
错误 3: No such file or directory
.env.test: no such file or directory
解决:
# 从模板创建
cp .env.template .env.test
vim .env.test
# 或从本地上传
scp .env.test user@server:/path/to/app/.env.test
完整部署脚本
创建 deploy-to-server.sh:
#!/bin/bash
# 配置
SERVER_USER="your_username"
SERVER_HOST="your_server_ip"
SERVER_PATH="/path/to/app"
ENV="test" # 或 prod
echo "🚀 开始部署到服务器..."
# 1. 构建 AMD64 镜像
echo "1️⃣ 构建 AMD64 镜像..."
docker build --platform linux/amd64 -t oversea-service:$ENV .
# 2. 导出镜像
echo "2️⃣ 导出镜像..."
docker save oversea-service:$ENV -o oversea-service-$ENV.tar
# 3. 压缩
echo "3️⃣ 压缩镜像..."
gzip -f oversea-service-$ENV.tar
# 4. 上传镜像
echo "4️⃣ 上传镜像到服务器..."
scp oversea-service-$ENV.tar.gz $SERVER_USER@$SERVER_HOST:$SERVER_PATH/
# 5. 上传配置文件
echo "5️⃣ 上传配置文件..."
scp .env.$ENV $SERVER_USER@$SERVER_HOST:$SERVER_PATH/
scp docker-compose.$ENV.yml $SERVER_USER@$SERVER_HOST:$SERVER_PATH/
# 6. 远程部署
echo "6️⃣ 在服务器上部署..."
ssh $SERVER_USER@$SERVER_HOST << ENDSSH
cd $SERVER_PATH
# 解压镜像
gunzip -f oversea-service-$ENV.tar.gz
# 加载镜像
docker load -i oversea-service-$ENV.tar
# 停止旧容器
docker-compose -f docker-compose.$ENV.yml down
# 启动新容器
docker-compose -f docker-compose.$ENV.yml up -d
# 查看状态
docker ps | grep oversea
# 查看日志
docker logs --tail 50 oversea_service_$ENV
echo "✅ 部署完成!"
ENDSSH
echo "✅ 所有步骤完成!"
使用:
chmod +x deploy-to-server.sh
./deploy-to-server.sh
验证部署
# 1. 检查容器状态
docker ps | grep oversea
# 2. 查看实时日志
docker logs --tail 100 -f oversea_service_test
# 3. 检查 PM2 进程状态
docker exec -it oversea_service_test pm2 list
# 4. 查看 PM2 日志
docker exec -it oversea_service_test pm2 logs
# 5. 测试服务
curl http://localhost:3001/health # 测试环境
curl http://localhost:3000/health # 生产环境
# 6. 查看容器详情
docker inspect oversea_service_test
# 7. 进入容器调试
docker exec -it oversea_service_test sh
# 在容器内:
pm2 list # 查看 PM2 进程
pm2 logs # 查看应用日志
env | grep NODE # 查看环境变量
ls -la # 查看文件结构
常见问题排查
问题 1: PM2 进程启动后立即退出
症状: 容器运行但服务无法访问,PM2 显示 online 后立即消失
原因:
- 环境变量配置错误
- MongoDB 连接失败
- 端口已被占用
- 代码启动错误
解决步骤:
# 1. 查看容器日志
docker logs oversea_service_test
# 2. 进入容器检查 PM2
docker exec -it oversea_service_test sh
pm2 list
pm2 logs --lines 100
# 3. 检查环境变量
env | grep -E "NODE_ENV|MONGO|JWT"
# 4. 手动启动查看详细错误
pm2 delete all
node server.js
# 5. 检查端口占用
netstat -tuln | grep 3000
问题 2: 容器不断重启
症状: docker ps 显示容器一直在重启
解决:
# 查看容器重启次数和原因
docker inspect oversea_service_test | grep -A 10 State
# 查看最近的错误日志
docker logs --tail 200 oversea_service_test
# 临时禁用自动重启,查看错误
docker update --restart=no oversea_service_test
# 重新构建镜像
docker-compose -f docker-compose.test.yml build --no-cache
docker-compose -f docker-compose.test.yml up -d
问题 3: MongoDB 连接失败
症状: 日志显示 MongoDB 连接错误
解决:
# 检查 MongoDB 连接字符串
docker exec -it oversea_service_test env | grep MONGO_URI
# 如果 MongoDB 在宿主机:
# - macOS/Windows: 使用 host.docker.internal
# - Linux: 使用宿主机 IP 或 172.17.0.1
# 修改 .env.test 中的 MONGO_URI
# 示例:
MONGO_URI=mongodb://host.docker.internal:27017 # Mac/Win
MONGO_URI=mongodb://172.17.0.1:27017 # Linux
# 或者将 MongoDB 也放在 Docker 中
# 在 docker-compose.test.yml 添加 MongoDB 服务
问题 4: 健康检查失败
症状: docker ps 显示容器为 unhealthy
解决:
# 查看健康检查日志
docker inspect oversea_service_test | grep -A 20 Health
# 进入容器手动测试
docker exec -it oversea_service_test sh
wget -O- http://localhost:3000/health
# 或
curl http://localhost:3000/health
# 如果应用没有 /health 端点,修改 docker-compose.yml
# 移除 healthcheck 或修改为:
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/"]
问题 5: 环境文件加载失败
症状: 应用启动但配置为默认值
解决:
# 检查环境文件是否正确加载
docker exec -it oversea_service_test env
# 确保 .env.test 在正确位置
ls -la .env.test
# 重新上传环境文件
scp .env.test user@server:/path/to/app/.env.test
# 重启容器
docker-compose -f docker-compose.test.yml restart
调试技巧
使用交互式模式启动容器
# 停止后台容器
docker-compose -f docker-compose.test.yml down
# 交互式启动,查看完整启动过程
docker run -it --rm \
-e NODE_ENV=test \
--env-file .env.test \
-p 3001:3000 \
oversea-service:test \
sh
# 在容器内手动启动
ls -la
env | grep NODE
pm2-runtime start ecosystem.config.cjs --only oversea_test
查看详细的 PM2 日志
# 进入容器
docker exec -it oversea_service_test sh
# 查看 PM2 日志文件
pm2 logs --lines 200
# 查看特定应用的日志
pm2 logs oversea_test --lines 100
# 查看错误日志
pm2 logs oversea_test --err --lines 50
# 监控实时日志
pm2 logs oversea_test --raw
完整诊断脚本
创建 diagnose.sh:
#!/bin/bash
CONTAINER_NAME="oversea_service_test"
echo "🔍 开始诊断容器: $CONTAINER_NAME"
echo "================================"
# 1. 容器状态
echo "📦 容器状态:"
docker ps -a | grep $CONTAINER_NAME
# 2. 容器日志
echo ""
echo "📋 最近 50 行日志:"
docker logs --tail 50 $CONTAINER_NAME
# 3. PM2 进程
echo ""
echo "⚙️ PM2 进程状态:"
docker exec -it $CONTAINER_NAME pm2 list 2>/dev/null || echo "无法获取 PM2 状态"
# 4. 环境变量
echo ""
echo "🔧 环境变量:"
docker exec -it $CONTAINER_NAME env | grep -E "NODE_ENV|MONGO|JWT|PORT" 2>/dev/null
# 5. 端口监听
echo ""
echo "🌐 端口监听:"
docker exec -it $CONTAINER_NAME netstat -tuln 2>/dev/null || echo "netstat 不可用"
# 6. 健康状态
echo ""
echo "💚 健康检查:"
docker inspect $CONTAINER_NAME | grep -A 10 Health
echo ""
echo "================================"
echo "✅ 诊断完成"
使用:
chmod +x diagnose.sh
./diagnose.sh
回滚
如果部署失败,快速回滚:
# 1. 停止新容器
docker-compose -f docker-compose.test.yml down
# 2. 加载备份镜像
docker load -i oversea-service-test-backup.tar
# 3. 启动旧版本
docker-compose -f docker-compose.test.yml up -d