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查询开启较慢,项目制作过程中使用该命令查看前端错误原因)
二、部署中遇到的错误与解决方案
- 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
- 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
- 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
- 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)
排查步骤:
- 直接访问后端端口 curl http://192.168.168.100:8080/api/category/tree → 正常返回 JSON
- 检查 Nginx 是否在同一个 Docker 网络 → docker inspect 确认都在 java_project_sheep-net
- 检查 Nginx 能否解析 app 主机名 → docker exec sheep-nginx ping app 正常
- 检查 Nginx 内部能否请求后端 → docker exec sheep-nginx wget -qO- http://app:8080/api/category/tree 正常
- 最终原因: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 检测 /
- 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_project2.目录结构规范
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(网络正常后执行)
curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash
设置开机自启
sudo systemctl start cpolar
sudo systemctl enable cpolar
后台同时穿透前端80、后端8080(单终端无需多窗口)
cpolar http 80 &
cpolar http 8080 &
停止所有临时隧道
pkill cpolar
七、域名 & CDN 线上正式部署(可选,生产环境)
等待云服务器后完成
核心经验:
- Docker 网络:用容器名通信,不用 IP
- 条件加载:@ConditionalOnProperty 空值时仍会匹配,用 SpEL 表达式更安全
- 重建容器:stop/start 不重建容器,jar 更新必须用 up -d --force-recreate
- 排查 502:逐层排查 — 后端直接访问 → Nginx 内访问 → Nginx 日志 → server_name 匹配
Previous
SheepAiMail
Next
SheepAiMail