最近项目快来发完了,就寻思弄一套部署方法
技术栈是这样的
- 服务端 spring-boot
- 前端 vue+webpack
- 数据库 mysql
- 图片服务器 zimg
然后准备用docker部署、数据库用阿里云的
服务端方案
后端用的alpine-glibc:glibc-2.27
+openjdk
做基础镜像
基础镜像Dockerfile
1 | FROM frolvlad/alpine-glibc:glibc-2.27 |
接着在基础镜像基础上加入项目jar包,并加入启动命令
服务端Dockerfile
1 | FROM alpine-glibc-openjdk-8 |
前端方案
-
开发时前端打包后,将编译后的项目用nginx启动。
目录结构
1
2
3├── dist/
├── nginx.conf
└── DockerfileDockerfile
1
2
3
4
5
6
7
8
9
10FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir /app
WORKDIR /app
COPY . /app/
ENV PORT 80
RUN mkdir -p /var/www/html/dist \
&& cp -r dist/* /var/www/html/dist \
&& rm -rf /app
RUN echo "Asia/shanghai" > /etc/timezone获取nginx.conf的方法
1
2
3docker run --name tmp-nginx-container -d nginx
docker cp tmp-nginx-container:/etc/nginx/nginx.conf ./nginx.conf
docker rm -f tmp-nginx-container -
后来觉得直接让前端打包成镜像就算了,写了一个在容器打包的方案
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13FROM node:10.14.2-slim
RUN apt-get update && apt-get install -y nginx
COPY nginx.conf /etc/nginx/nginx.conf
RUN mkdir /app
WORKDIR /app
COPY . /app/
ENV PORT 80RUN mkdir /var/www/html/dist \
&& npm install \
&& npm run build \
&& cp -r dist/* /var/www/html/dist \
&& cp -r index.html /var/www/html \
&& rm -rf /app
RUN echo "Asia/shanghai" > /etc/timezoneCMD ["nginx","-g","daemon off;"]获取nginx.conf方法与上一个一样
后来觉得根据spring-boot的启动方式
前后端完全可以部署在一起,这样也省的每次前端打包都要改ip了
然后在查资料的过程中发现了一个Docker在构建项目上的一个特性
指定按照从上到下,顺序执行
每条指令都会创建一个新的镜像层,并对镜像进行提交
如果某个命令相关的内容没有变化,会使用上一次缓存(cache)的文件层
这个思路完全可行
下面演示下例子:
思路:
-
使用jenkins检测指定分支代码更新
-
使用打包工具打包并用时间戳命名(.jar、.zip)
-
创建软连接后端代码 (LTS.jar) or 前端代码(LTS.zip)并解压
ln -s -f 1547196831460.jar /LTS/LTS.jar
ln -s -f 1547196831460.zip /LTS/LTS.zip
-
构建image
- 解压前后端项目
rm -rf /LTS/java && unzip LTS.jar -d java
rm -rf /LTS/vue && unzip LTS.zip -d vue
- Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13FROM alpine-glibc-openjdk-8
LABEL maintainer "xdmdpz@foxmail.com"
COPY /LTS/java/BOOT-INF/lib/ /app/BOOT-INF/lib/
COPY /LTS/java/org /app/org
COPY /LTS/java/META-INF /app/META-INF
COPY /LTS/java/BOOT-INF/classes /app/BOOT-INF/classes
COPY /LTS/vue/* /app/BOOT-INF/classes
EXPOSE 8080
CMD ["/usr/bin/java", "-cp", "/app", "org.springframework.boot.loader.JarLauncher"] - 解压前后端项目
-
完事
Dockerfile我们把应用的内容分成5个部分COPY到镜像里面:
其中前面3个基本不变,
第4个是经常变化的后端代码,
第5个是打包后的前端代码。
最后一行是解压缩后,启动spring boot应用的方式。
这样在构建镜像时候可大大提高构建速度。
部署的时候注意一下两点:
- 不变或者变化很少的体积较大的依赖库和经常修改的自有代码分开
- 因为cache缓存在运行Docker build命令的本地机器上,建议固定使用某台机器来进行Docker build,以便利用cache。
以上是构建Spring Boot应用镜像,其他类型的应用,比如Java WAR包,Nodejs的npm模块等,可以采取类似的方式。