Spring Boot 应用 Docker 部署完整指南
本文档提供从零开始的 Docker 部署完整流程,包括环境检查、旧服务清理、镜像构建、容器运行及故障排查。
目录
- 环境准备与检查
- 目录结构规划
- [Dockerfile 编写规范](#Dockerfile 编写规范)
- 旧服务清理流程
- 镜像构建与验证
- 容器运行配置
- 部署验证与检查
- 自动化部署脚本
- 常用管理命令
- 故障排查指南
一、环境准备与检查
1.1 检查 Docker 环境
bash
# 检查 Docker 版本
docker --version
# 检查 Docker 服务状态
systemctl status docker
# 如果 Docker 未启动,执行启动
systemctl start docker
systemctl enable docker
# 检查当前运行的容器
docker ps -a
# 检查现有镜像
docker images
1.2 检查系统资源
bash
# 检查磁盘空间
df -h
# 检查内存使用
free -h
# 检查 Docker 存储使用情况
docker system df
1.3 检查端口占用
bash
# 检查应用端口是否被占用(假设应用端口是 8089)
netstat -tlnp | grep 8089
lsof -i:8089
# 如果端口被占用且需要释放
kill -9 <PID>
1.4 检查基础镜像
bash
# 检查是否有 OpenJDK 17 镜像
docker images | grep openjdk
# 如果没有,拉取镜像
docker pull openjdk:17.0.2
二、目录结构规划
2.1 创建项目目录
bash
# 创建主目录
mkdir -p /home/smart-brain
# 创建数据挂载目录(根据实际需求)
mkdir -p /home/rkg/templateFile
# 创建日志目录(可选)
mkdir -p /home/smart-brain/logs
# 创建备份目录
mkdir -p /home/smart-brain/backup
2.2 目录结构说明
/home/smart-brain/ # 主目录
├── Dockerfile # Docker 构建文件
├── greatek-smart-brain-1.0.jar # 应用 jar 包
├── deploy.sh # 自动化部署脚本
├── logs/ # 日志目录(可选)
└── backup/ # 备份目录
/home/rkg/templateFile/ # 数据挂载目录
2.3 设置目录权限
bash
# 设置目录权限
chmod 755 /home/smart-brain
chmod 755 /home/rkg/templateFile
# 查看权限
ls -ld /home/smart-brain
ls -ld /home/rkg/templateFile
三、Dockerfile 编写规范
3.1 Dockerfile 基本结构
Dockerfile 是纯文本文件,不包含任何 shell 命令(如 cd、ls 等),只包含 Docker 指令。
3.2 创建标准 Dockerfile
bash
cd /home/smart-brain
# 方法一:使用 cat 命令创建(推荐)
cat > Dockerfile << 'EOF'
FROM openjdk:17.0.2
LABEL authors="greatek"
WORKDIR /rkg
ENV JAVA_OPTS="-Dfile.encoding=UTF-8 \
-Dsun.jnu.encoding=UTF-8 \
-Duser.language=zh \
-Duser.country=CN \
-Duser.timezone=Asia/Shanghai \
-Djava.security.egd=file:/dev/./urandom"
COPY greatek-smart-brain-1.0.jar app.jar
VOLUME ["/home/rkg/templateFile"]
EXPOSE 8089
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
EOF
bash
# 方法二:使用 vi 编辑器创建
vi Dockerfile
# 按 i 进入编辑模式,粘贴上面的内容
# 按 ESC 退出编辑模式
# 输入 :wq 保存退出
3.3 Dockerfile 指令说明
| 指令 | 说明 | 示例 |
|---|---|---|
| FROM | 基础镜像 | FROM openjdk:17.0.2 |
| LABEL | 元数据标签 | LABEL authors="greatek" |
| WORKDIR | 工作目录 | WORKDIR /rkg |
| ENV | 环境变量 | ENV JAVA_OPTS="-Dfile.encoding=UTF-8" |
| COPY | 复制文件到镜像 | COPY app.jar app.jar |
| VOLUME | 数据卷挂载点 | VOLUME ["/data"] |
| EXPOSE | 暴露端口(文档用途) | EXPOSE 8089 |
| ENTRYPOINT | 容器启动命令 | ENTRYPOINT ["java", "-jar", "app.jar"] |
3.4 验证 Dockerfile
bash
# 查看 Dockerfile 内容(第一行必须是 FROM)
cat Dockerfile
# 检查文件格式(不应有 Windows 换行符)
file Dockerfile
# 如果有 Windows 换行符,转换格式
dos2unix Dockerfile
# 检查是否有隐藏字符
hexdump -C Dockerfile | head -20
3.5 常见错误避免
❌ 错误示例(包含 shell 命令):
dockerfile
cd /home/smart-brain
FROM openjdk:17.0.2
✅ 正确示例:
dockerfile
FROM openjdk:17.0.2
LABEL authors="greatek"
关键点:
- Dockerfile 第一行必须是
FROM指令 - 不能包含
cd、ls、echo等 shell 命令 - 每行指令独立,不能有 shell 脚本语法
四、旧服务清理流程
4.1 查看现有服务
bash
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止)
docker ps -a
# 查看指定容器
docker ps -a | grep abnormal-monitoring
# 查看现有镜像
docker images | grep abnormal-monitoring
4.2 备份旧服务数据
bash
# 备份容器日志
docker logs abnormal-monitoring > /home/smart-brain/backup/abnormal-monitoring-$(date +%Y%m%d-%H%M%S).log 2>&1
# 导出旧镜像(可选,用于回滚)
docker save abnormal-monitoring:v0.0.1 -o /home/smart-brain/backup/abnormal-monitoring-v0.0.1.tar
# 备份容器配置
docker inspect abnormal-monitoring > /home/smart-brain/backup/abnormal-monitoring-config-$(date +%Y%m%d-%H%M%S).json
4.3 停止旧容器
bash
# 优雅停止容器(等待 10 秒)
docker stop abnormal-monitoring
# 强制停止容器
docker stop -t 0 abnormal-monitoring
# 验证容器已停止
docker ps | grep abnormal-monitoring
4.4 删除旧容器
bash
# 删除容器
docker rm abnormal-monitoring
# 强制删除(即使容器正在运行)
docker rm -f abnormal-monitoring
# 验证容器已删除
docker ps -a | grep abnormal-monitoring
4.5 删除旧镜像
bash
# 查看镜像 ID
docker images | grep abnormal-monitoring
# 按标签删除
docker rmi abnormal-monitoring:v0.0.1
# 按镜像 ID 删除
docker rmi ed1067cecd0b
# 强制删除
docker rmi -f abnormal-monitoring:v0.0.1
# 验证镜像已删除
docker images | grep abnormal-monitoring
4.6 清理无用资源
bash
# 清理悬空镜像(<none>)
docker image prune
# 清理停止的容器
docker container prune
# 清理未使用的卷
docker volume prune
# 清理所有未使用资源(慎用)
docker system prune -a
4.7 完整清理脚本
bash
# 创建清理脚本
cat > /home/smart-brain/cleanup.sh << 'EOF'
#!/bin/bash
echo "=========================================="
echo " 清理旧服务"
echo "=========================================="
CONTAINER_NAME="abnormal-monitoring"
IMAGE_NAME="abnormal-monitoring:v0.0.1"
# 1. 备份日志
if docker ps -a | grep -q $CONTAINER_NAME; then
echo "1. 备份容器日志..."
docker logs $CONTAINER_NAME > /home/smart-brain/backup/backup-$(date +%Y%m%d-%H%M%S).log 2>&1
echo " 日志已备份"
fi
# 2. 停止容器
echo "2. 停止容器..."
docker stop $CONTAINER_NAME 2>/dev/null || echo " 容器未运行"
# 3. 删除容器
echo "3. 删除容器..."
docker rm $CONTAINER_NAME 2>/dev/null || echo " 容器不存在"
# 4. 删除镜像
echo "4. 删除镜像..."
docker rmi $IMAGE_NAME 2>/dev/null || echo " 镜像不存在"
# 5. 清理悬空镜像
echo "5. 清理悬空镜像..."
docker image prune -f
echo ""
echo "清理完成!"
echo ""
EOF
chmod +x /home/smart-brain/cleanup.sh
# 执行清理
/home/smart-brain/cleanup.sh
五、镜像构建与验证
5.1 准备构建文件
bash
cd /home/smart-brain
# 确认文件存在
ls -lh
# 应该看到:
# - Dockerfile
# - greatek-smart-brain-1.0.jar
# 检查 jar 包完整性
file greatek-smart-brain-1.0.jar
5.2 构建镜像
bash
cd /home/smart-brain
# 基本构建命令
docker build -t abnormal-monitoring:v0.0.1 .
# 不使用缓存构建
docker build --no-cache -t abnormal-monitoring:v0.0.1 .
# 指定 Dockerfile 位置
docker build -f Dockerfile -t abnormal-monitoring:v0.0.1 .
5.3 构建输出解读
正常构建输出:
Sending build context to Docker daemon 125.2MB
Step 1/8 : FROM openjdk:17.0.2
---> 5e28ba2b4cdb
Step 2/8 : LABEL authors="greatek"
---> Running in a1b2c3d4e5f6
---> Removed intermediate container a1b2c3d4e5f6
---> 1234567890ab
...
Step 8/8 : ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
---> Running in f6e5d4c3b2a1
---> Removed intermediate container f6e5d4c3b2a1
---> abcdef123456
Successfully built abcdef123456
Successfully tagged abnormal-monitoring:v0.0.1
5.4 验证镜像
bash
# 查看镜像
docker images | grep abnormal-monitoring
# 查看镜像详细信息
docker inspect abnormal-monitoring:v0.0.1
# 查看镜像历史
docker history abnormal-monitoring:v0.0.1
# 查看镜像层
docker image inspect abnormal-monitoring:v0.0.1 --format='{{.RootFS.Layers}}'
5.5 镜像测试(可选)
bash
# 临时启动容器测试镜像
docker run --rm -it abnormal-monitoring:v0.0.1 java -version
# 查看镜像内文件
docker run --rm -it abnormal-monitoring:v0.0.1 ls -lh /rkg/
# 测试应用启动(短暂运行)
docker run --rm abnormal-monitoring:v0.0.1 --help
5.6 构建错误处理
错误 1:Dockerfile 解析错误
Error response from daemon: dockerfile parse error on line 1: unknown instruction: cd
解决:删除 Dockerfile 中的 shell 命令,重新创建。
错误 2:找不到 jar 包
COPY failed: file not found
解决:检查 jar 包文件名是否正确,或修改 Dockerfile 中的 COPY 指令。
错误 3:基础镜像拉取失败
Error response from daemon: pull access denied
解决 :手动拉取基础镜像 docker pull openjdk:17.0.2
六、容器运行配置
6.1 网络模式选择
Host 网络模式(推荐用于单机部署)
特点:
- 容器直接使用宿主机网络
- 无需端口映射
- 性能最优
- 容器内使用
localhost访问宿主机服务
bash
docker run -dit \
--name abnormal-monitoring \
--network host \
--restart=unless-stopped \
-v /home/rkg/templateFile:/home/rkg/templateFile \
abnormal-monitoring:v0.0.1
Bridge 网络模式(适用于多容器隔离)
特点:
- 容器使用独立网络
- 需要端口映射
- 容器间隔离
- 使用容器 IP 或容器名通信
bash
docker run -dit \
--name abnormal-monitoring \
-p 8089:8089 \
--restart=unless-stopped \
-v /home/rkg/templateFile:/home/rkg/templateFile \
abnormal-monitoring:v0.0.1
6.2 容器启动参数详解
bash
docker run -dit \
--name abnormal-monitoring \ # 容器名称
--network host \ # 网络模式
--restart=unless-stopped \ # 重启策略
-e SPRING_PROFILES_ACTIVE=prod \ # 环境变量
-e TZ=Asia/Shanghai \ # 时区设置
-v /home/rkg/templateFile:/home/rkg/templateFile \ # 数据卷挂载
-v /home/smart-brain/logs:/rkg/logs \ # 日志挂载(可选)
--memory="2g" \ # 内存限制(可选)
--cpus="2" \ # CPU 限制(可选)
abnormal-monitoring:v0.0.1 # 镜像名
6.3 重启策略说明
| 策略 | 说明 | 使用场景 |
|---|---|---|
no |
不自动重启(默认) | 测试环境 |
always |
总是重启 | 关键服务 |
unless-stopped |
除非手动停止,否则重启 | 生产环境推荐 |
on-failure[:max-retries] |
失败时重启 | 需要控制重启次数 |
6.4 环境变量配置
bash
# 常用环境变量
-e SPRING_PROFILES_ACTIVE=prod # Spring 配置文件
-e JAVA_OPTS="-Xmx2g -Xms2g" # JVM 参数
-e TZ=Asia/Shanghai # 时区
-e NACOS_SERVER_ADDR=127.0.0.1:8848 # Nacos 地址
-e REDIS_HOST=127.0.0.1 # Redis 地址
6.5 数据卷挂载
bash
# 挂载单个目录
-v /home/rkg/templateFile:/home/rkg/templateFile
# 挂载多个目录
-v /home/rkg/templateFile:/home/rkg/templateFile \
-v /home/smart-brain/logs:/rkg/logs \
-v /home/smart-brain/config:/rkg/config
# 只读挂载
-v /home/smart-brain/config:/rkg/config:ro
6.6 完整启动命令(生产环境)
bash
docker run -dit \
--name abnormal-monitoring \
--network host \
--restart=unless-stopped \
-e SPRING_PROFILES_ACTIVE=prod \
-e TZ=Asia/Shanghai \
-e JAVA_OPTS="-Xmx2g -Xms2g -XX:+UseG1GC" \
-v /home/rkg/templateFile:/home/rkg/templateFile \
-v /home/smart-brain/logs:/rkg/logs \
--memory="4g" \
--cpus="2" \
abnormal-monitoring:v0.0.1
七、部署验证与检查
7.1 容器状态检查
bash
# 查看运行状态
docker ps | grep abnormal-monitoring
# 查看详细信息
docker inspect abnormal-monitoring
# 查看容器资源使用
docker stats abnormal-monitoring --no-stream
# 查看容器进程
docker top abnormal-monitoring
7.2 日志检查
bash
# 实时查看日志(Ctrl+C 退出)
docker logs -f abnormal-monitoring
# 查看最近 100 行日志
docker logs --tail 100 abnormal-monitoring
# 查看带时间戳的日志
docker logs -f --timestamps abnormal-monitoring
# 查看指定时间后的日志
docker logs --since "2024-12-10T10:00:00" abnormal-monitoring
# 导出日志到文件
docker logs abnormal-monitoring > /home/smart-brain/app.log 2>&1
7.3 应用健康检查
bash
# 检查端口监听(host 网络模式)
netstat -tlnp | grep java
ss -tlnp | grep java
lsof -i:8089
# 测试应用接口
curl http://localhost:8089/actuator/health
# 测试根路径
curl http://localhost:8089/
# 查看应用版本信息
curl http://localhost:8089/actuator/info
7.4 进入容器检查
bash
# 进入容器
docker exec -it abnormal-monitoring /bin/bash
# 在容器内执行检查
pwd # 查看当前目录
ls -lh # 查看文件
ps aux | grep java # 查看进程
netstat -tlnp # 查看端口
cat /etc/hosts # 查看 hosts
env # 查看环境变量
java -version # 查看 Java 版本
ls -la /home/rkg/templateFile # 查看挂载目录
# 退出容器
exit
7.5 服务注册检查(如果使用 Nacos)
bash
# 查看 Nacos 服务列表
curl "http://localhost:8848/nacos/v1/ns/instance/list?serviceName=abnormal-monitoring"
# 查看服务详情
curl "http://localhost:8848/nacos/v1/ns/instance?serviceName=abnormal-monitoring"
# 浏览器访问 Nacos 控制台
# http://服务器IP:8848/nacos
# 默认账号密码:nacos/nacos
7.6 性能监控
bash
# 实时监控容器资源
docker stats abnormal-monitoring
# 查看容器磁盘使用
docker exec abnormal-monitoring df -h
# 查看应用内存使用
docker exec abnormal-monitoring free -h
# 查看 JVM 内存
docker exec abnormal-monitoring jstat -gc <PID>
7.7 连接其他服务测试
bash
# 进入容器测试连接
docker exec -it abnormal-monitoring /bin/bash
# 测试 Nacos 连接
curl http://127.0.0.1:8848/nacos/v1/console/health/readiness
# 测试 Redis 连接
telnet 127.0.0.1 6379
# 或
redis-cli -h 127.0.0.1 -p 6379 ping
# 测试数据库连接(如果有 psql)
psql -h 127.0.0.1 -U username -d database
exit
八、自动化部署脚本
8.1 完整自动化部署脚本
bash
cat > /home/smart-brain/deploy.sh << 'EOF'
#!/bin/bash
#============================================
# Spring Boot Docker 自动化部署脚本
# 作者: Greatek
# 版本: v1.0
# 说明: 用于自动化部署 Spring Boot 应用到 Docker
#============================================
set -e # 遇到错误立即退出
#============================================
# 配置区域(根据实际情况修改)
#============================================
CONTAINER_NAME="abnormal-monitoring"
IMAGE_NAME="abnormal-monitoring"
IMAGE_TAG="v0.0.1"
JAR_FILE="greatek-smart-brain-1.0.jar"
APP_PORT="8089"
WORK_DIR="/home/smart-brain"
BACKUP_DIR="${WORK_DIR}/backup"
VOLUME_DIR="/home/rkg/templateFile"
#============================================
# 颜色输出
#============================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
#============================================
# 1. 环境检查
#============================================
check_environment() {
log_info "=========================================="
log_info " 环境检查"
log_info "=========================================="
# 检查 Docker
if ! command -v docker &> /dev/null; then
log_error "Docker 未安装,请先安装 Docker"
exit 1
fi
log_info "✓ Docker 已安装: $(docker --version)"
# 检查 Docker 服务
if ! systemctl is-active --quiet docker; then
log_error "Docker 服务未运行,请启动 Docker: systemctl start docker"
exit 1
fi
log_info "✓ Docker 服务运行正常"
# 检查工作目录
if [ ! -d "$WORK_DIR" ]; then
log_error "工作目录不存在: $WORK_DIR"
exit 1
fi
log_info "✓ 工作目录存在: $WORK_DIR"
# 检查 jar 包
if [ ! -f "$WORK_DIR/$JAR_FILE" ]; then
log_error "jar 包不存在: $WORK_DIR/$JAR_FILE"
exit 1
fi
log_info "✓ jar 包存在: $JAR_FILE ($(ls -lh $WORK_DIR/$JAR_FILE | awk '{print $5}'))"
# 检查 Dockerfile
if [ ! -f "$WORK_DIR/Dockerfile" ]; then
log_error "Dockerfile 不存在: $WORK_DIR/Dockerfile"
exit 1
fi
log_info "✓ Dockerfile 存在"
# 检查挂载目录
if [ ! -d "$VOLUME_DIR" ]; then
log_warn "挂载目录不存在,正在创建: $VOLUME_DIR"
mkdir -p "$VOLUME_DIR"
fi
log_info "✓ 挂载目录存在: $VOLUME_DIR"
# 检查备份目录
if [ ! -d "$BACKUP_DIR" ]; then
mkdir -p "$BACKUP_DIR"
log_info "✓ 创建备份目录: $BACKUP_DIR"
fi
echo ""
}
#============================================
# 2. 备份旧服务
#============================================
backup_old_service() {
log_info "=========================================="
log_info " 备份旧服务"
log_info "=========================================="
if docker ps -a | grep -q "$CONTAINER_NAME"; then
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# 备份日志
log_info "备份容器日志..."
docker logs "$CONTAINER_NAME" > "$BACKUP_DIR/${CONTAINER_NAME}-${TIMESTAMP}.log" 2>&1
log_info "✓ 日志已备份: ${CONTAINER_NAME}-${TIMESTAMP}.log"
# 备份配置
log_info "备份容器配置..."
docker inspect "$CONTAINER_NAME" > "$BACKUP_DIR/${CONTAINER_NAME}-config-${TIMESTAMP}.json"
log_info "✓ 配置已备份: ${CONTAINER_NAME}-config-${TIMESTAMP}.json"
else
log_warn "未找到运行中的容器,跳过备份"
fi
# 清理旧备份(保留最近 5 个)
log_info "清理旧备份文件(保留最近 5 个)..."
cd "$BACKUP_DIR"
ls -t ${CONTAINER_NAME}-*.log 2>/dev/null | tail -n +6 | xargs -r rm -f
ls -t ${CONTAINER_NAME}-config-*.json 2>/dev/null | tail -n +6 | xargs -r rm -f
echo ""
}
#============================================
# 3. 停止并删除旧容器
#============================================
remove_old_container() {
log_info "=========================================="
log_info " 清理旧容器"
log_info "=========================================="
if docker ps -a | grep -q "$CONTAINER_NAME"; then
# 停止容器
log_info "停止容器: $CONTAINER_NAME"
docker stop "$CONTAINER_NAME" 2>/dev/null || true
log_info "✓ 容器已停止"
# 删除容器
log_info "删除容器: $CONTAINER_NAME"
docker rm "$CONTAINER_NAME" 2>/dev/null || true
log_info "✓ 容器已删除"
else
log_warn "容器不存在,跳过删除"
fi
echo ""
}
#============================================
# 4. 删除旧镜像
#============================================
remove_old_image() {
log_info "=========================================="
log_info " 清理旧镜像"
log_info "=========================================="
if docker images | grep -q "$IMAGE_NAME.*$IMAGE_TAG"; then
log_info "删除镜像: ${IMAGE_NAME}:${IMAGE_TAG}"
docker rmi "${IMAGE_NAME}:${IMAGE_TAG}" 2>/dev/null || true
log_info "✓ 镜像已删除"
else
log_warn "镜像不存在,跳过删除"
fi
# 清理悬空镜像
log_info "清理悬空镜像..."
docker image prune -f > /dev/null 2>&1
log_info "✓ 悬空镜像已清理"
echo ""
}
#============================================
# 5. 构建新镜像
#============================================
build_image() {
log_info "=========================================="
log_info " 构建新镜像"
log_info "=========================================="
cd "$WORK_DIR"
log_info "开始构建镜像: ${IMAGE_NAME}:${IMAGE_TAG}"
log_info "构建上下文: $WORK_DIR"
if docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" .; then
log_info "✓ 镜像构建成功"
# 显示镜像信息
IMAGE_SIZE=$(docker images "${IMAGE_NAME}:${IMAGE_TAG}" --format "{{.Size}}")
log_info "镜像大小: $IMAGE_SIZE"
else
log_error "镜像构建失败"
exit 1
fi
echo ""
}
#============================================
# 6. 启动新容器
#============================================
start_container() {
log_info "=========================================="
log_info " 启动新容器"
log_info "=========================================="
log_info "启动容器: $CONTAINER_NAME"
log_info "网络模式: host"
log_info "重启策略: unless-stopped"
log_info "数据挂载: $VOLUME_DIR"
docker run -dit \
--name "$CONTAINER_NAME" \
--network host \
--restart=unless-stopped \
-e TZ=Asia/Shanghai \
-v "${VOLUME_DIR}:${VOLUME_DIR}" \
"${IMAGE_NAME}:${IMAGE_TAG}"
if [ $? -eq 0 ]; then
log_info "✓ 容器启动成功"
else
log_error "容器启动失败"
exit 1
fi
echo ""
}
#============================================
# 7. 等待应用启动
#============================================
wait_for_app() {
log_info "=========================================="
log_info " 等待应用启动"
log_info "=========================================="
log_info "等待应用启动(最多等待 60 秒)..."
for i in {1..60}; do
sleep 1
if docker ps | grep -q "$CONTAINER_NAME"; then
# 检查端口是否监听(仅适用于 host 网络)
if netstat -tlnp 2>/dev/null | grep -q ":${APP_PORT}"; then
log_info "✓ 应用启动成功(${i}秒)"
return 0
fi
else
log_error "容器已停止"
docker logs --tail 50 "$CONTAINER_NAME"
exit 1
fi
# 每 10 秒显示一次进度
if [ $((i % 10)) -eq 0 ]; then
log_info "仍在等待... (${i}/60 秒)"
fi
done
log_warn "应用启动超时,请检查日志"
echo ""
}
#============================================
# 8. 验证部署
#============================================
verify_deployment() {
log_info "=========================================="
log_info " 验证部署"
log_info "=========================================="
# 检查容器状态
if docker ps | grep -q "$CONTAINER_NAME"; then
log_info "✓ 容器运行正常"
docker ps | grep "$CONTAINER_NAME"
else
log_error "✗ 容器未运行"
exit 1
fi
echo ""
# 检查端口
if netstat -tlnp 2>/dev/null | grep -q ":${APP_PORT}"; then
log_info "✓ 端口监听正常: $APP_PORT"
else
log_warn "✗ 端口未监听: $APP_PORT"
fi
echo ""
# 显示最近日志
log_info "最近 20 行日志:"
docker logs --tail 20 "$CONTAINER_NAME"
echo ""
}
#============================================
# 9. 部署总结
#============================================
show_summary() {
log_info "=========================================="
log_info " 部署完成"
log_info "=========================================="
echo ""
echo "容器名称: $CONTAINER_NAME"
echo "镜像: ${IMAGE_NAME}:${IMAGE_TAG}"
echo "应用端口: $APP_PORT"
echo "网络模式: host"
echo ""
echo "常用命令:"
echo " 查看日志: docker logs -f $CONTAINER_NAME"
echo " 查看状态: docker ps | grep $CONTAINER_NAME"
echo " 重启服务: docker restart $CONTAINER_NAME"
echo " 停止服务: docker stop $CONTAINER_NAME"
echo " 进入容器: docker exec -it $CONTAINER_NAME /bin/bash"
echo ""
echo "应用访问:"
echo " http://localhost:${APP_PORT}"
echo ""
}
#============================================
# 主流程
#============================================
main() {
echo ""
log_info "=========================================="
log_info " Spring Boot Docker 自动化部署"
log_info " 开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
log_info "=========================================="
echo ""
# 执行部署流程
check_environment
backup_old_service
remove_old_container
remove_old_image
build_image
start_container
wait_for_app
verify_deployment
show_summary
log_info "部署完成时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo ""
}
# 执行主流程
main
EOF
# 赋予执行权限
chmod +x /home/smart-brain/deploy.sh
8.2 快速部署脚本(精简版)
bash
cat > /home/smart-brain/quick-deploy.sh << 'EOF'
#!/bin/bash
set -e
CONTAINER_NAME="abnormal-monitoring"
IMAGE_NAME="abnormal-monitoring:v0.0.1"
WORK_DIR="/home/smart-brain"
echo "=== 快速部署 ==="
cd "$WORK_DIR"
# 停止并删除旧容器
docker stop "$CONTAINER_NAME" 2>/dev/null || true
docker rm "$CONTAINER_NAME" 2>/dev/null || true
# 删除旧镜像
docker rmi "$IMAGE_NAME" 2>/dev/null || true
# 构建新镜像
echo "构建镜像..."
docker build -t "$IMAGE_NAME" .
# 启动容器
echo "启动容器..."
docker run -dit \
--name "$CONTAINER_NAME" \
--network host \
--restart=unless-stopped \
-v /home/rkg/templateFile:/home/rkg/templateFile \
"$IMAGE_NAME"
# 等待启动
sleep 5
# 检查状态
docker ps | grep "$CONTAINER_NAME"
echo "=== 部署完成 ==="
echo "查看日志: docker logs -f $CONTAINER_NAME"
EOF
chmod +x /home/smart-brain/quick-deploy.sh
8.3 回滚脚本
bash
cat > /home/smart-brain/rollback.sh << 'EOF'
#!/bin/bash
set -e
CONTAINER_NAME="abnormal-monitoring"
BACKUP_DIR="/home/smart-brain/backup"
echo "=== 回滚到旧版本 ==="
# 查找最新的备份镜像
LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/*.tar 2>/dev/null | head -1)
if [ -z "$LATEST_BACKUP" ]; then
echo "错误: 未找到备份镜像"
exit 1
fi
echo "找到备份: $LATEST_BACKUP"
# 停止当前容器
echo "停止当前容器..."
docker stop "$CONTAINER_NAME"
docker rm "$CONTAINER_NAME"
# 加载备份镜像
echo "加载备份镜像..."
docker load -i "$LATEST_BACKUP"
# 启动容器
echo "启动容器..."
docker run -dit \
--name "$CONTAINER_NAME" \
--network host \
--restart=unless-stopped \
-v /home/rkg/templateFile:/home/rkg/templateFile \
abnormal-monitoring:v0.0.1
echo "=== 回滚完成 ==="
EOF
chmod +x /home/smart-brain/rollback.sh
8.4 使用脚本
bash
# 完整部署(推荐)
/home/smart-brain/deploy.sh
# 快速部署
/home/smart-brain/quick-deploy.sh
# 回滚
/home/smart-brain/rollback.sh
九、常用管理命令
9.1 容器管理
bash
# 查看所有容器
docker ps -a
# 查看运行中的容器
docker ps
# 启动容器
docker start abnormal-monitoring
# 停止容器
docker stop abnormal-monitoring
# 重启容器
docker restart abnormal-monitoring
# 强制停止容器
docker kill abnormal-monitoring
# 删除容器
docker rm abnormal-monitoring
# 强制删除运行中的容器
docker rm -f abnormal-monitoring
# 暂停容器
docker pause abnormal-monitoring
# 恢复容器
docker unpause abnormal-monitoring
9.2 日志管理
bash
# 实时查看日志
docker logs -f abnormal-monitoring
# 查看最后 100 行
docker logs --tail 100 abnormal-monitoring
# 查看带时间戳的日志
docker logs -f --timestamps abnormal-monitoring
# 查看指定时间后的日志
docker logs --since "2024-12-10T10:00:00" abnormal-monitoring
docker logs --since "1h" abnormal-monitoring
# 查看指定时间范围的日志
docker logs --since "2024-12-10T10:00:00" --until "2024-12-10T12:00:00" abnormal-monitoring
# 导出日志
docker logs abnormal-monitoring > app.log 2>&1
9.3 容器操作
bash
# 进入容器
docker exec -it abnormal-monitoring /bin/bash
# 在容器中执行命令
docker exec abnormal-monitoring ls -la /rkg
# 查看容器进程
docker top abnormal-monitoring
# 查看容器资源使用
docker stats abnormal-monitoring
# 查看容器详细信息
docker inspect abnormal-monitoring
# 复制文件到容器
docker cp /path/to/file abnormal-monitoring:/rkg/
# 从容器复制文件
docker cp abnormal-monitoring:/rkg/file /path/to/
9.4 镜像管理
bash
# 查看所有镜像
docker images
# 查看镜像详情
docker inspect abnormal-monitoring:v0.0.1
# 查看镜像历史
docker history abnormal-monitoring:v0.0.1
# 删除镜像
docker rmi abnormal-monitoring:v0.0.1
# 强制删除镜像
docker rmi -f abnormal-monitoring:v0.0.1
# 导出镜像
docker save abnormal-monitoring:v0.0.1 -o abnormal-monitoring.tar
# 导入镜像
docker load -i abnormal-monitoring.tar
# 给镜像打标签
docker tag abnormal-monitoring:v0.0.1 abnormal-monitoring:latest
9.5 清理命令
bash
# 清理停止的容器
docker container prune
# 清理悬空镜像
docker image prune
# 清理未使用的卷
docker volume prune
# 清理未使用的网络
docker network prune
# 清理所有未使用资源
docker system prune
# 清理所有未使用资源(包括未使用的镜像)
docker system prune -a
# 查看 Docker 磁盘使用
docker system df
# 查看详细磁盘使用
docker system df -v
9.6 网络管理
bash
# 查看所有网络
docker network ls
# 查看网络详情
docker network inspect host
# 查看容器网络
docker inspect -f '{{.NetworkSettings.Networks}}' abnormal-monitoring
# 查看容器 IP(bridge 模式)
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' abnormal-monitoring
十、故障排查指南
10.1 容器无法启动
症状:
bash
docker ps -a
# STATUS 显示 Exited (1) 或 Exited (137)
排查步骤:
- 查看日志
bash
docker logs abnormal-monitoring
- 常见原因及解决方案
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
Error: Could not find or load main class |
jar 包损坏或路径错误 | 检查 jar 包完整性 |
Address already in use |
端口被占用 | 检查端口占用: `netstat -tlnp |
Cannot connect to database |
数据库连接失败 | 检查数据库配置和网络 |
OOMKilled |
内存溢出 | 增加容器内存限制 |
Permission denied |
权限问题 | 检查挂载目录权限 |
10.2 应用启动慢或卡住
排查步骤:
bash
# 1. 查看实时日志
docker logs -f abnormal-monitoring
# 2. 进入容器检查进程
docker exec -it abnormal-monitoring /bin/bash
ps aux | grep java
top
# 3. 检查资源使用
docker stats abnormal-monitoring
# 4. 检查磁盘空间
df -h
docker exec abnormal-monitoring df -h
# 5. 检查网络连接
docker exec abnormal-monitoring ping -c 3 127.0.0.1
10.3 端口无法访问
排查步骤:
bash
# 1. 检查容器是否运行
docker ps | grep abnormal-monitoring
# 2. 检查端口监听(host 模式)
netstat -tlnp | grep 8089
ss -tlnp | grep 8089
# 3. 检查防火墙
firewall-cmd --list-ports
firewall-cmd --add-port=8089/tcp --permanent
firewall-cmd --reload
# 4. 检查 SELinux
getenforce
setenforce 0 # 临时关闭
# 5. 测试本地访问
curl http://localhost:8089
# 6. 检查应用日志
docker logs abnormal-monitoring | grep -i error
10.4 容器频繁重启
排查步骤:
bash
# 1. 查看容器重启次数
docker inspect abnormal-monitoring | grep RestartCount
# 2. 查看退出代码
docker ps -a | grep abnormal-monitoring
# 3. 查看日志找出崩溃原因
docker logs --tail 200 abnormal-monitoring
# 4. 禁用自动重启进行调试
docker update --restart=no abnormal-monitoring
# 5. 检查系统资源
free -h
df -h
10.5 数据卷挂载问题
排查步骤:
bash
# 1. 检查挂载配置
docker inspect abnormal-monitoring | grep -A 10 Mounts
# 2. 检查宿主机目录权限
ls -ld /home/rkg/templateFile
# 3. 检查容器内目录
docker exec abnormal-monitoring ls -la /home/rkg/templateFile
# 4. 修复权限
chmod 755 /home/rkg/templateFile
chown -R root:root /home/rkg/templateFile
# 5. 测试读写
docker exec abnormal-monitoring touch /home/rkg/templateFile/test.txt
10.6 镜像构建失败
常见错误及解决:
- Dockerfile 解析错误
bash
# 错误: dockerfile parse error on line 1: unknown instruction: cd
# 解决: 删除 Dockerfile 中的 shell 命令
rm Dockerfile
# 重新创建正确的 Dockerfile
- 找不到 jar 包
bash
# 错误: COPY failed: file not found
# 解决: 检查文件名
ls -lh /home/smart-brain/*.jar
# 修改 Dockerfile 中的 COPY 指令或重命名文件
- 基础镜像拉取失败
bash
# 错误: Error response from daemon: pull access denied
# 解决: 手动拉取镜像
docker pull openjdk:17.0.2
- 磁盘空间不足
bash
# 错误: no space left on device
# 解决: 清理 Docker 资源
docker system prune -a
10.7 网络连接问题
排查步骤:
bash
# 1. 检查网络模式
docker inspect abnormal-monitoring | grep NetworkMode
# 2. 测试容器网络(进入容器)
docker exec -it abnormal-monitoring /bin/bash
# 测试外网连接
ping -c 3 8.8.8.8
# 测试 DNS
nslookup baidu.com
# 测试 Nacos
curl http://127.0.0.1:8848/nacos/v1/console/health/readiness
# 测试 Redis
redis-cli -h 127.0.0.1 -p 6379 ping
exit
# 3. 检查宿主机网络
ping -c 3 127.0.0.1
netstat -tlnp | grep 8848
10.8 性能问题
排查步骤:
bash
# 1. 查看容器资源使用
docker stats abnormal-monitoring
# 2. 查看 JVM 内存
docker exec abnormal-monitoring jmap -heap <PID>
# 3. 查看线程数
docker exec abnormal-monitoring jstack <PID> | grep "java.lang.Thread.State" | wc -l
# 4. 导出堆转储(OOM 时)
docker exec abnormal-monitoring jmap -dump:format=b,file=/tmp/heap.hprof <PID>
# 5. 增加容器资源限制
docker update --memory="4g" --cpus="2" abnormal-monitoring
10.9 日志排查技巧
bash
# 1. 查找错误日志
docker logs abnormal-monitoring | grep -i error
# 2. 查找异常日志
docker logs abnormal-monitoring | grep -i exception
# 3. 查找启动日志
docker logs abnormal-monitoring | grep -i "started"
# 4. 统计错误数量
docker logs abnormal-monitoring | grep -c "ERROR"
# 5. 过滤特定时间段
docker logs --since "2024-12-10T10:00:00" --until "2024-12-10T11:00:00" abnormal-monitoring
# 6. 导出完整日志进行分析
docker logs abnormal-monitoring > /tmp/app-full.log 2>&1
10.10 应急处理流程
快速恢复服务:
bash
#!/bin/bash
# 应急恢复脚本
CONTAINER_NAME="abnormal-monitoring"
echo "=== 应急恢复流程 ==="
# 1. 重启容器
echo "1. 尝试重启容器..."
docker restart $CONTAINER_NAME
sleep 10
# 2. 检查状态
if docker ps | grep -q $CONTAINER_NAME; then
echo "✓ 容器重启成功"
exit 0
fi
# 3. 查看日志
echo "2. 容器重启失败,查看日志..."
docker logs --tail 50 $CONTAINER_NAME
# 4. 删除并重新创建
echo "3. 删除容器并重新创建..."
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
docker run -dit \
--name $CONTAINER_NAME \
--network host \
--restart=unless-stopped \
-v /home/rkg/templateFile:/home/rkg/templateFile \
abnormal-monitoring:v0.0.1
sleep 10
# 5. 最终检查
if docker ps | grep -q $CONTAINER_NAME; then
echo "✓ 服务恢复成功"
else
echo "✗ 服务恢复失败,请手动排查"
exit 1
fi
附录
A. 完整示例配置文件
application.yml(host 网络模式):
yaml
server:
port: 8089
spring:
application:
name: abnormal-monitoring
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: public
datasource:
url: jdbc:postgresql://127.0.0.1:54321/smart_brain
username: SYSTEM
password: 123456
redis:
host: 127.0.0.1
port: 6379
B. 检查清单
部署前检查:
- Docker 已安装并运行
- jar 包已上传
- Dockerfile 已创建
- 挂载目录已创建
- 端口未被占用
- 磁盘空间充足
部署后检查:
- 容器运行正常
- 端口正常监听
- 应用日志正常
- 服务注册成功(如使用 Nacos)
- 接口可正常访问
C. 常用链接
- Docker 官方文档: https://docs.docker.com
- Spring Boot 官方文档: https://spring.io/projects/spring-boot
- Nacos 官方文档: https://nacos.io
文档版本 : v1.0
最后更新 : 2025年12月9日
适用范围: Spring Boot + Docker + CentOS/RHEL