E01 虚拟机部署docker容器的一些常用命令和部署中的错误

虚拟机部署 Docker 容器:常用命令与踩坑记录

环境信息
  • 虚拟机 IP:192.168.168.100
  • 操作系统:CentOS 7
  • Docker Compose 项目目录:/root/java_project
  • Nginx 配置/前端目录:/root/nginx/

一、常用 Docker & Docker Compose 命令

容器生命周期

启动所有服务(后台)

docker compose up -d

启动指定服务

docker compose up -d app docker compose up -d elasticsearch

带构建启动(用于 Dockerfile 有修改时)

docker compose up -d --build elasticsearch

强制重建容器(拉最新镜像/换新 jar)

docker compose up -d app --force-recreate

停止并设置超时(默认 10s,可调)

docker compose stop -t 30

停止所有服务

docker compose stop

启动所有服务(不重建)

docker compose start

重启服务

docker compose restart app

删除容器(保留数据卷)

docker compose rm -fs elasticsearch
▎ 注意:stop + start 不会重建容器,jar 包更新后必须用 up -d --force-recreate 或用 stop + rm + up -d。

日志查看

查看最新 50 行日志

docker compose logs app --tail=50(打包过程中el)

持续跟踪日志

docker compose logs -f app

导出完整日志到文件

docker compose logs app > /tmp/app.log
容器内操作

进入容器

docker exec -it sheep-app sh

在容器内执行命令

docker exec sheep-app wget -qO- http://app:8080/api/category/tree --timeout=5

查看容器网络

docker inspect sheep-app --format '{{json .NetworkSettings.Networks}}'

查看容器 IP

docker inspect sheep-app --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'

查看容器所在网络

docker inspect sheep-nginx --format '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}'

查看容器状态(含健康检查)

docker ps --filter name=sheep-app --format "table {{.Names}}\t{{.Status}}"

网络排查

从 Nginx 容器 ping app 容器

docker exec sheep-nginx ping -c 2 app

从宿主机直接访问后端

通过 Nginx 代理访问

查看 Nginx 错误日志

docker exec sheep-nginx cat /var/log/nginx/error.log | tail -20(访问前端页面时报错,原因:后端el查询开启较慢,项目制作过程中使用该命令查看前端错误原因)

二、部署中遇到的错误与解决方案

  1. CentOS 7 yum 源失效
错误:Cannot find a valid baseurl for repo: base/7/x86_64
原因:CentOS 7 于 2024 年 6 月 EOL,官方源已下线。
解决:
切换至 vault.centos.org 镜像源
sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/CentOS-.repo sed -i 's/^#.baseurl=http/baseurl=http/g' /etc/yum.repos.d/CentOS-.repo sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/CentOS-.repo
  1. Docker Hub 拉取镜像超时
错误:context canceled / network is unreachable
原因:香港 VM 无法直连 Docker Hub。
解决:

推荐使用的镜像加速器:

Docker 配置 daemon.json

vim /etc/docker/daemon.json { "registry-mirrors": ["https://registry.cn-hongkong.aliyuncs.com"] } systemctl restart docker
  1. ES 容器启动失败 — IK 分词器未安装
错误: mapper_parsing_exception: analyzer [ik_smart] has not been configured in mappings
NoSuchFileException: /usr/share/elasticsearch/plugins/ik/plugin-descriptor.properties
原因:Spring Data ES 在创建索引时使用了 IK 分词器,但 ES 容器中未安装 IK 插件。手动复制文件会导致目录结构不完整。
解决:使用 Dockerfile 构建带 IK 的 ES 镜像。

es-dockerfile

FROM elasticsearch:7.17.24
COPY elasticsearch-analysis-ik-7.17.24.zip /tmp/ik.zip RUN ./bin/elasticsearch-plugin install -b file:///tmp/ik.zip && rm /tmp/ik.zip

docker-compose.yml

elasticsearch:
build:
context: /root/java_project
dockerfile: es-dockerfile
  1. App 无法启动 — ES 连接失败(循环引用/空 URI)
错误:容器启动后 ES 连接异常,导致 Bean 创建失败。
原因:应用使用了 @ConditionalOnProperty(name = "spring.elasticsearch.uris"),但当环境变量 SHEEP_ELASTICSEARCH_URIS="" 时,该注解仍判定属性"存在"(空字符串不等于 "false"),导致 ES 客户端继续加载。
解决:将注解改为 SpEL 表达式,仅当 URI 非空时才加载:
// 改前
@ConditionalOnProperty(name = "spring.elasticsearch.uris")
// 改后
@ConditionalOnExpression("'${spring.elasticsearch.uris:}' != ''")
涉及 4 个文件:ElasticsearchConfig、ProductSearchServiceImpl、SpuDocumentRepository、MerchantDocumentRepository。

后端启动后 502 Bad Gateway

错误: 502 Bad Gateway - nginx/1.26.3 Nginx 错误日志:connect() failed (111: Connection refused)
排查步骤:
  1. 直接访问后端端口 curl http://192.168.168.100:8080/api/category/tree → 正常返回 JSON
  1. 检查 Nginx 是否在同一个 Docker 网络 → docker inspect 确认都在 java_project_sheep-net
  1. 检查 Nginx 能否解析 app 主机名 → docker exec sheep-nginx ping app 正常
  1. 检查 Nginx 内部能否请求后端 → docker exec sheep-nginx wget -qO- http://app:8080/api/category/tree 正常
  1. 最终原因:server_name localhost 导致 Host 头不匹配
解决:

改前

server_name localhost;

改后 — 匹配任意域名/IP

server_name _;
同时记得重启或重载 Nginx: docker exec sheep-nginx nginx -s reload

日志被 HEALTHCHECK 刷屏

错误:日志持续重复输出: NoResourceFoundException: No static resource actuator/health.
原因:Dockerfile 中 HEALTHCHECK 使用 wget http://localhost:8080/actuator/health,但项目未引入 spring-boot-starter-actuator 依赖,导致每次健康检查都 404。
解决:改 Dockerfile,去掉 HEALTHCHECK 或换成能响应的路径:

方案一:直接删掉 HEALTHCHECK

sed -i '/HEALTHCHECK/d' Dockerfile

方案二:改为检测首页

HEALTHCHECK 检测 /

  1. Docker Compose 重建后 IP 变化
现象:docker compose up -d --force-recreate 后,容器的 IP 地址发生变化(如 172.28.0.6 → 172.28.0.2)。
说明:Docker 每次重建容器会重新分配 IP,属于正常行为。不要硬编码 IP,应使用容器名称(如 app)通过 Docker 内置 DNS 解析。

三、完整部署流程总结

安装 Docker → 上传项目文件 → 编写 Dockerfile/compose/nginx 配置 → Maven 打包 jar → docker compose up -d --build 启动容器 → 日志调试业务 → cpolar 内网穿透对外访问(如果使用云服务器ip能够连接公网可直接进行访问) → 自有域名 + CDN 正式上线

一、项目文件上传与目录规划

1.windows 使用 FinalShell 将项目压缩包上传至虚拟机 /root/java_project
2.目录结构规范
java_project/ ├── docker-compose.yml # 容器编排核心配置 ├── nginx/ │ ├── nginx.conf # Nginx反向代理配置 │ └── html/ # 前端静态资源 ├── app/ │ └── Dockerfile # Java后端镜像构建文件 ├── mysql/ # MySQL数据持久化挂载目录 └── redis/ # Redis缓存持久化目录
3.解压项目包

三、编写核心配置文件

1. 后端 Dockerfile(SpringBoot)
dockerfile
FROM openjdk:17-jdk-slim WORKDIR /app COPY target/demo.jar app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar"]
上方仅为示例代码
2. docker-compose.yml(统一管理所有中间件 + 业务)
包含 nginx、java-app、mysql、redis、elasticsearch,配置端口映射、数据卷挂载、开机重启策略
3. Nginx 配置 nginx.conf
反向代理前端静态页面、转发后端 8080 接口,配置跨域、静态资源缓存

四、项目打包 & 镜像构建

1. Java 后端本地打包(Windows)
使用 Maven 打包 jar 包
将 target 下 jar 上传至虚拟机相应目录
2. 一键构建全部镜像(虚拟机内)
bash
运行
# 构建镜像,后台启动容器 docker compose up -d --build
  • -build:修改 Dockerfile / 依赖后必须加,重新构建镜像
  • d:后台静默运行,不占用终端
 

六、内网穿透(cpolar 对外演示配套,由于本人没有云服务器,暂时使用cpolar穿透展示)

1. 虚拟机安装 cpolar(网络正常后执行)
设置开机自启
sudo systemctl start cpolar sudo systemctl enable cpolar
后台同时穿透前端80、后端8080(单终端无需多窗口)
cpolar http 80 & cpolar http 8080 &
停止所有临时隧道
pkill cpolar

七、域名 & CDN 线上正式部署(可选,生产环境)

等待云服务器后完成

核心经验:

  1. Docker 网络:用容器名通信,不用 IP
  1. 条件加载:@ConditionalOnProperty 空值时仍会匹配,用 SpEL 表达式更安全
  1. 重建容器:stop/start 不重建容器,jar 更新必须用 up -d --force-recreate
  1. 排查 502:逐层排查 — 后端直接访问 → Nginx 内访问 → Nginx 日志 → server_name 匹配
 

Previous

SheepAiMail

Next

SheepAiMail