平时本地部署Java项目的Docker流程,整理了一个可直接复用的版本。
1. 新建Docker服务
首先在你打包好的JAR包同级目录下,新建一个配置文件,文件名必须固定叫 Dockerfile,不能加后缀,文件内容直接复制下面的,对应改自己的项目信息就行:
# 基础镜像,这里一定要换成和你项目编译打包用的JDK版本完全匹配的!版本不对会直接启动报错
FROM openjdk:8-jre-alpine3.9
# 时区和证书配置,解决容器时间不对、中文乱码的问题
RUN apk update && apk upgrade && apk add ca-certificates && update-ca-certificates \
&& apk add --update tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& rm -rf /var/cache/apk/*
ENV TZ=Asia/Shanghai
# 镜像维护人信息,换成你自己的名字和邮箱就行,不想留的话直接删掉这行也完全不影响
LABEL maintainer="yourname <your-email@example.com>"
# 补全时区依赖,和上面的配置配套
RUN apk add --no-cache tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
# 容器内的工作目录
WORKDIR /app
# 重点注意!
# 前面是你本地maven/gradle打出来的jar包全名,必须和这个Dockerfile放在同一个文件夹里
# 后面是容器里自定义的jar包名,后面的启动命令要和这个名字完全对上
COPY spring-boot-demo.jar app.jar
# 端口号!必须和你Spring Boot配置文件里的server.port一模一样
EXPOSE 8080
# 启动命令,指定UTF-8避免中文乱码,只需要确认最后jar包名和上面COPY的一致就行
ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-jar", "/app/app.jar"]
镜像构建命令
在Dockerfile所在的文件夹里打开终端,执行下面的命令:
# 构建镜像,--no-cache是不用缓存构建,避免旧文件影响
# -t 后面的是「镜像名:版本号」,你自己随便定,但是后面所有步骤都要和这里保持一致
docker build --no-cache -t java-spring-boot-demo:v1 .
容器启动命令
# 启动容器
# -p 是端口映射,前后两个端口要和上面EXPOSE的、你项目里的端口完全一致
# --name 后面是容器名,自己起个好记的,后面重启、看日志都要用
# 最后面的镜像名:版本号,必须和上面build命令里的一模一样
docker run -d -p 8080:8080 --name spring-boot-demo-service java-spring-boot-demo:v1
服务重启命令
# 重启服务,后面换成你自己上面起的容器名
docker restart spring-boot-demo-service
服务日志查看命令
# 查看服务运行日志,换成你自己的容器名
docker logs spring-boot-demo-service
# 实时滚动查看日志,排查启动问题用这个,同样换自己的容器名
docker logs -f spring-boot-demo-service
2. 代码更新后,替换jar包重启流程
日常改了代码重新打包,不用从头写配置,按这三步来就行,容器名、镜像名还是和之前保持一致,别乱改:
- 先停掉正在运行的服务
# 后面换成你自己的容器名
docker stop spring-boot-demo-service
- 删掉旧的容器(不删的话新容器同名会报错)
# 同样换成你自己的容器名
docker rm spring-boot-demo-service
- 把文件夹里的旧jar包换成新打的包,然后重新构建+启动,命令和之前的保持一致就行
# 重新构建镜像,镜像名和版本号和之前的一样
docker build --no-cache -t java-spring-boot-demo:v1 .
# 启动新容器,端口、容器名、镜像名全和之前统一
docker run -d -p 8080:8080 --name spring-boot-demo-service java-spring-boot-demo:v1
# 实时看启动日志,排查有没有报错
docker logs -f spring-boot-demo-service
最后说几个我踩过的坑
- 所有你自己定的名字,镜像名、版本号、容器名、端口号,全程一定要统一!比如build的时候叫java-demo:v1,run的时候就不能改成java-app:v1,不然肯定找不到镜像报错。
- 你打的jar包,必须和Dockerfile放在同一个文件夹里,不然COPY命令会找不到文件,直接构建失败。
- 端口号三处必须完全一致:Spring Boot配置里的server.port、Dockerfile里的EXPOSE、run命令里的-p映射,少一个不对都访问不到服务。
- 基础镜像的JDK版本,一定要和你本地打包用的JDK大版本对上!比如你本地用JDK8打包,就不能用JDK11的镜像,不然会出现版本不兼容的启动报错。