springboot项目打包docker镜像并部署
1. 为什么要使用docker
首先我们不使用docker去启动,那么我想项目的部署需要通过maven将项目打包成jar包,丢到环境上去启动,如果服务发生异常springboot挂掉项目是需要手动重启的。
而且别人使用你的项目也需要下载源码,里面里面的一些配置改成自己的,然后再打包成jar,按照同样的步骤去部署,不是很友好。
而通过docker我们可以将一下自定义的内容比如对象存储服务、数据库等通过环境变量的形式,在启动容器的时候去设置,而镜像可以发布到镜像仓库,使用者拉取就可以直接使用非常的方便。
2. 打包步骤
2.1 配置修改
修改application.yaml将里面一下配置挪到prod文件中
server:
# 端口号
port: 8081
spring:
profiles:
active: dev
jackson:
# 设置后台返参,若字段值为 null, 是否返回
# default-property-inclusion: non_null
date-format: yyyy-MM-dd HH:mm:ss
servlet:
multipart:
# 限制上传文件大小
max-file-size: 10MB
jwt:
# 签发人
issuer: chengzi
# 秘钥
secret: gR6cytlUlgMfVh08nLKlksl898JGFUIBVlsCbKvRlWcLwNRU6+rIPcLx21x191kJgP8udtoZuHt5yUDWtgg==
# token 过期时间(单位:分钟) 24*60
tokenExpireTime: 1440
# token Header 中的 key 值
tokenHeaderKey: Authorization
# token Header 中的 value 值前缀
tokenPrefix: Bearer
#=================================================================
# IP归属地信息库文件路径 ip2region.xdb
#=================================================================
xdb:
profile: xxx
application-prod.yaml:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
hikari:
minimum-idle: 5
maximum-pool-size: 9
auto-commit: true
idle-timeout: 30000
pool-name: Weblog-HikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
#=================================================================
# log
#=================================================================
logging:
config: classpath:logback-weblog.xml
#=================================================================
# minio (上传图片需要,需配置成自己的地址)
#=================================================================
minio:
endpoint: ${MINIO_ENDPOINT}
accessKey: ${MINIO_ACCESS_KEY}
secretKey: ${MINIO_SECRET_KEY}
bucketName: ${MINIO_BUCKET_NAME}
#=================================================================
# Lucene 全文检索
#=================================================================
lucene:
indexDir: /app/weblog/lucene-index # lucene 索引存放的位置
2.2 Dockerfile
# FROM 指定使用哪个镜像作为基准
FROM openjdk:8-jdk-alpine
# 创建目录, 并设置该目录为工作目录
RUN mkdir -p /windblog
WORKDIR /windblog
# 复制文件到镜像中
COPY windblog-web-0.0.1-SNAPSHOT.jar app.jar
COPY application-prod.yaml application-prod.yaml
COPY application.yaml application.yaml
# 设置时区
ENV TZ=Asia/Shanghai
# 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV JAVA_OPTS="-Xms300m -Xmx300m -Djava.security.egd=file:/dev/./urandom"
# 应用参数,可通过 docker run -e "ARGS=" 来设置,如 -e "ARGS=--spring.profiles.active=prod"
ENV ARGS="--spring.profiles.active=prod"
# 暴露 8081 端口
EXPOSE 8081
# 启动后端服务
CMD java ${JAVA_OPTS} -jar app.jar $ARGS
2.3 打包镜像
将maven打包好的windblog-web-0.0.1-SNAPSHOT.jar、application-prod.yaml、application.yaml和dockerfile放到服务器的同一目录下
执行命令
docker build -t windblog:v1.0 -f Dockerfile .
-t后面是你自定义的镜像名字
执行完成后可以通过
docker images
查看已完成的镜像列表
3. 部署项目
在项目目录下新建docker-compose.yml文件
version: '3.8'
services:
app:
image: windblog:v1.0 # 替换为你的镜像名称
container_name: windblog # 容器名称
network_mode: "host"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://127.0.0.1:3306/windblog?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
SPRING_DATASOURCE_USERNAME: windblog
SPRING_DATASOURCE_PASSWORD: windblog
MINIO_ENDPOINT: http://windblog:9000
MINIO_ACCESS_KEY: jNcxxxxxJWDG7PX5
MINIO_SECRET_KEY: CTkVKu4Sxxxxxxxxxxx9pV5D0aBDc8H2
MINIO_BUCKET_NAME: winblog
ports:
- "8081:8081"
volumes:
- /mnt/data/docker/windblog/lucene:/app/weblog/lucene-index
- /mnt/data/docker/windblog/logs:/app/weblog/logs
注意 volumes,因为我的项目中日志和全文索引都需要创建文件夹使用,所以需要指定我在容器中的相应路径应该指向哪里,这个路径是可以自定义的
3.1 后端服务
在docker-compose.yml下执行命令启动服务
docker-compose up --detach
可以去挂载的日志目录查看项目的启动日志
3.2 前端
在宝塔中新建一个纯静态的php网站,绑定域名,然后将前端打包的dist文件上传到网站的跟路径下解压,注意不保留dist文件夹,将dist文件夹里的内容剪切粘贴到网站的根目录下
点击网站设置nginx反向代理
location / {
root /www/wwwroot/test.nasfly.top;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
/api/请根据你的前端项目的实际追加接口前缀设置,注意端口号最后的斜杆,很关键
proxy_pass http://127.0.0.1:8081/:
当 proxy_pass 的 URL 末尾有斜杠 / 时,Nginx 会将匹配到的 location 路径从原始请求路径中移除,然后将剩余部分附加到 proxy_pass 的 URL 后面。
例如,如果请求路径是 /api/some/endpoint,Nginx 会将请求代理到 http://127.0.0.1:8081/some/endpoint。
proxy_pass http://127.0.0.1:8081:
当 proxy_pass 的 URL 末尾没有斜杠 / 时,Nginx 会将匹配到的 location 路径保留在原始请求路径中,然后将整个路径附加到 proxy_pass 的 URL 后面。
例如,如果请求路径是 /api/some/endpoint,Nginx 会将请求代理到 http://127.0.0.1:8081/api/some/endpoint。
不设置对你的接口都会404
然后访问你的域名,就可以访问网站了
4. 镜像发布
为了别人也能使用我们的镜像,因为现在镜像是我们build在本地的,还没有发布到docker的仓库,我们需要再服务器上登录我们的dockerhub账号,然后更名镜像,push到公共仓库
去镜像查看已经有镜像啦
别人想使用直接新建一个docker-compose.yml文件将image: windblog:v1.0修改为image: chengzi1220/windblog:latest,然后执行
docker-compose up --detach
会自动拉取镜像并启动容器,记得前端单独部署哦
5. 总结
至于为什么没有将数据库也写入compose的文件中,是因为我们一般服务器都会安装宝塔和1panel,都是自带了mysql等数据库服务
如果再启动一个数据库容器会占用内存,所以在compose中将windblog的容器指定为host网络,可以直接使用宿主机创建的数据库,这样既节省内存也更加方便管理数据库