Spring Boot 应用 Docker 部署完整指南 - 教程

Spring Boot 应用 Docker 部署完整指南

本文档提供从零开始的 Docker 部署完整流程,包括环境检查、旧服务清理、镜像构建、容器运行及故障排查。


目录

  1. 环境准备与检查
  2. 目录结构规划
  3. Dockerfile 编写规范
  4. 旧服务清理流程
  5. 镜像构建与验证
  6. 容器运行配置
  7. 部署验证与检查
  8. 自动化部署脚本
  9. 常用管理命令
  10. 故障排查指南

一、环境准备与检查

1.1 检查 Docker 环境

# 检查 Docker 版本
docker --version
# 检查 Docker 服务状态
systemctl status docker
# 如果 Docker 未启动,执行启动
systemctl start docker
systemctl enable docker
# 检查当前运行的容器
docker ps -a
# 检查现有镜像
docker images

1.2 检查系统资源

# 检查磁盘空间
df -h
# 检查内存使用
free -h
# 检查 Docker 存储使用情况
docker system df

1.3 检查端口占用

# 检查应用端口是否被占用(假设应用端口是 8089)
netstat -tlnp | grep 8089
lsof -i:8089
# 如果端口被占用且需要释放
kill -9 <PID>

1.4 检查基础镜像

# 检查是否有 OpenJDK 17 镜像
docker images | grep openjdk
# 如果没有,拉取镜像
docker pull openjdk:17.0.2

二、目录结构规划

2.1 创建项目目录

# 创建主目录
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 设置目录权限

# 设置目录权限
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

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
# 方法二:使用 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

# 查看 Dockerfile 内容(第一行必须是 FROM)
cat Dockerfile
# 检查文件格式(不应有 Windows 换行符)
file Dockerfile
# 如果有 Windows 换行符,转换格式
dos2unix Dockerfile
# 检查是否有隐藏字符
hexdump -C Dockerfile | head -20

3.5 常见错误避免

错误示例(包含 shell 命令):

cd /home/smart-brain
FROM openjdk:17.0.2

正确示例

FROM openjdk:17.0.2
LABEL authors="greatek"

关键点

  • Dockerfile 第一行必须是 FROM 指令
  • 不能包含 cdlsecho 等 shell 命令
  • 每行指令独立,不能有 shell 脚本语法

四、旧服务清理流程

4.1 查看现有服务

# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止)
docker ps -a
# 查看指定容器
docker ps -a | grep abnormal-monitoring
# 查看现有镜像
docker images | grep abnormal-monitoring

4.2 备份旧服务数据

# 备份容器日志
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 停止旧容器

# 优雅停止容器(等待 10 秒)
docker stop abnormal-monitoring
# 强制停止容器
docker stop -t 0 abnormal-monitoring
# 验证容器已停止
docker ps | grep abnormal-monitoring

4.4 删除旧容器

# 删除容器
docker rm abnormal-monitoring
# 强制删除(即使容器正在运行)
docker rm -f abnormal-monitoring
# 验证容器已删除
docker ps -a | grep abnormal-monitoring

4.5 删除旧镜像

# 查看镜像 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 清理无用资源

# 清理悬空镜像(<none>)
  docker image prune
  # 清理停止的容器
  docker container prune
  # 清理未使用的卷
  docker volume prune
  # 清理所有未使用资源(慎用)
  docker system prune -a

4.7 完整清理脚本

# 创建清理脚本
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 准备构建文件

cd /home/smart-brain
# 确认文件存在
ls -lh
# 应该看到:
# - Dockerfile
# - greatek-smart-brain-1.0.jar
# 检查 jar 包完整性
file greatek-smart-brain-1.0.jar

5.2 构建镜像

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 验证镜像

# 查看镜像
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 镜像测试(可选)

# 临时启动容器测试镜像
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 访问宿主机服务
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 或容器名通信
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 容器启动参数详解

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 环境变量配置

# 常用环境变量
-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 数据卷挂载

# 挂载单个目录
-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 完整启动命令(生产环境)

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 容器状态检查

# 查看运行状态
docker ps | grep abnormal-monitoring
# 查看详细信息
docker inspect abnormal-monitoring
# 查看容器资源使用
docker stats abnormal-monitoring --no-stream
# 查看容器进程
docker top abnormal-monitoring

7.2 日志检查

# 实时查看日志(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 应用健康检查

# 检查端口监听(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 进入容器检查

# 进入容器
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)

# 查看 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 性能监控

# 实时监控容器资源
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 连接其他服务测试

# 进入容器测试连接
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 完整自动化部署脚本

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 快速部署脚本(精简版)

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 回滚脚本

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 使用脚本

# 完整部署(推荐)
/home/smart-brain/deploy.sh
# 快速部署
/home/smart-brain/quick-deploy.sh
# 回滚
/home/smart-brain/rollback.sh

九、常用管理命令

9.1 容器管理

# 查看所有容器
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 日志管理

# 实时查看日志
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 容器操作

# 进入容器
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 镜像管理

# 查看所有镜像
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 清理命令

# 清理停止的容器
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 网络管理

# 查看所有网络
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 容器无法启动

症状

docker ps -a
# STATUS 显示 Exited (1) 或 Exited (137)

排查步骤

  1. 查看日志
docker logs abnormal-monitoring
  1. 常见原因及解决方案
错误信息原因解决方案
Error: Could not find or load main classjar 包损坏或路径错误检查 jar 包完整性
Address already in use端口被占用检查端口占用: netstat -tlnp | grep 8089
Cannot connect to database数据库连接失败检查数据库配置和网络
OOMKilled内存溢出增加容器内存限制
Permission denied权限问题检查挂载目录权限

10.2 应用启动慢或卡住

排查步骤

# 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 端口无法访问

排查步骤

# 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 容器频繁重启

排查步骤

# 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 数据卷挂载问题

排查步骤

# 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 镜像构建失败

常见错误及解决

  1. Dockerfile 解析错误
# 错误: dockerfile parse error on line 1: unknown instruction: cd
# 解决: 删除 Dockerfile 中的 shell 命令
rm Dockerfile
# 重新创建正确的 Dockerfile
  1. 找不到 jar 包
# 错误: COPY failed: file not found
# 解决: 检查文件名
ls -lh /home/smart-brain/*.jar
# 修改 Dockerfile 中的 COPY 指令或重命名文件
  1. 基础镜像拉取失败
# 错误: Error response from daemon: pull access denied
# 解决: 手动拉取镜像
docker pull openjdk:17.0.2
  1. 磁盘空间不足
# 错误: no space left on device
# 解决: 清理 Docker 资源
docker system prune -a

10.7 网络连接问题

排查步骤

# 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 性能问题

排查步骤

# 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 日志排查技巧

# 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 应急处理流程

快速恢复服务

#!/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 网络模式)

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

posted @ 2026-01-30 11:57  gccbuaa  阅读(9)  评论(0)    收藏  举报