使用 GitLab CI 和 Docker 自动部署 Spring Boot 应用
点击▲ “Java编程鸭”关注并标星
更多精彩 第一时间直达
Docker和Spring Boot是非常流行的组合,我们将利用GitLab CI的优势,并在应用程序服务器上自动构建,推送和运行Docker镜像。
GitLab CI
Gitlab CI/CD服务是GitLab的一部分,每当开发人员将代码推送到GitLab存储库时,它都会在所需的环境中构建,测试和存储最新的更改。
选择GitLab CI的一些主要原因:
1. 易于学习,使用和可扩展
2. 维护容易
3. 整合容易
4. CI完全属于GitLab存储库的一部分
5. 良好的Docker集成
6. 镜像托管(Container registry)-基本上是你自己的私有Docker Hub
7. 从成本上来说,GitLab CI是一个很好的解决方案。每个月你有2000分钟的免费构建时间,对于某些项目来说,这是绰绰有余的
我把 Docker 的教程和文章整理成了 PDF,关注微信关注号 Java后端,回复 666 就能下载了。
为什么GitLab CI超越Jenkins
1. 你已经在GitLab上推送了Spring Boot项目
2. 你已在应用程序服务器上安装了Docker(指南)
3. 你具有Docker镜像的镜像托管(在本指南中将使用Docker Hub)
4. 你已经在服务器上生成了SSH RSA密钥(指南)
Docker文件
FROM maven:3.6.3-jdk-11-slim AS MAVEN_BUILD
#FROM maven:3.5.2-jdk-8-alpine AS MAVEN_BUILD FOR JAVA 8
ARG SPRING_ACTIVE_PROFILE
MAINTAINER Jasmin
COPY pom.xml /build/
COPY src /build/src/
WORKDIR /build/
RUN mvn clean install -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE && mvn package -B -e -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE
FROM openjdk:11-slim
#FROM openjdk:8-alpine FOR JAVA 8
WORKDIR /app
COPY --from=MAVEN_BUILD /build/target/appdemo-*.jar /app/appdemo.jar
ENTRYPOINT ["java", "-jar", "appdemo.jar"]
Java版本
Docker镜像
备注:动态的变量
ENTRYPOINT
中,与环境相关的属性,我们只能写死,如下:ENTRYPOINT [ “ java”,“ -Dspring.profiles.active = development”,“ -jar”,“ appdemo.jar” ]
ENTRYPOINT [ “ java”,“ -Dspring.profiles.active = $ SPRINT_ACTIVE_PROFILE”,“ -jar”,“ appdemo.jar” ]
gitlab-ci.yml
export SPRING_ACTIVE_PROFILE='development'
export DOCKER_REPO='username/demo_app:dev'
export APP_NAME='demo_app_dev'
export PORT='8080'
export SERVER_IP='000.11.222.33'
export SERVER_SSH_KEY="$DEV_SSH_PRIVATE_KEY"
APP_NAME: 此属性非常重要,它是对容器的命名。如果你未设置此属性,则Docker将为你的容器随机命名。这可能是一个问题,因为你将无法以干净的方式停止运行容器。
端口:这是我们希望运行Docker容器的端口。
SERVER_IP:应用程序使用的服务器IP。通常,每个环境都将位于不同的服务器上。
SERVER_SSH_KEY:这是我们已经在每台服务器上生成的SSH密钥。
$DEV_SSH_PRIVATE_KEY
实际上是来自GitLab存储库的变量。
创建GitLab变量
DOCKER_USER:用于访问Docker Hub或其他镜像托管的用户名
DOCKER_PASSWORD: 用于访问镜像托管的密码
$ ENV_SSH_PRIVATE_KEY: 先前在服务器上生成的SSH私钥。
创建gitlab-ci.yml文件
services:
- docker:19.03.7-dind
stages:
- build jar
- build and push docker image
- deploy
build:
image: maven:3.6.3-jdk-11-slim
stage: build jar
before_script:
- source .${CI_COMMIT_REF_NAME}.env
script:
- mvn clean install -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE && mvn package -B -e -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE
artifacts:
paths:
- target/*.jar
docker build:
image: docker:stable
stage: build and push docker image
before_script:
- source .${CI_COMMIT_REF_NAME}.env
script:
- docker build --build-arg SPRING_ACTIVE_PROFILE=$SPRING_ACTIVE_PROFILE -t $DOCKER_REPO .
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD docker.io
- docker push $DOCKER_REPO
deploy:
image: ubuntu:latest
stage: deploy
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- source .${CI_COMMIT_REF_NAME}.env
script:
- ssh root@$SERVER "docker login -u $DOCKER_USER -p $DOCKER_PASSWORD docker.io; docker stop $APP_NAME; docker system prune -a -f; docker pull $DOCKER_REPO; docker container run -d --name $APP_NAME -p $PORT:8080 -e SPRING_PROFILES_ACTIVE=$SPRING_ACTIVE_PROFILE $DOCKER_REPO; docker logout"
services:
- docker:19.03.7-dind
stages:
- build jar
- build and push docker image
- deploy
build:
image: maven:3.6.3-jdk-11-slim
stage: build jar
before_script:
- source .${CI_COMMIT_REF_NAME}.env
script:
- mvn clean install -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE && mvn package -B -e -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE
artifacts:
paths:
- target/*.jar
docker build:
image: docker:stable
stage: build and push docker image
before_script:
- source .${CI_COMMIT_REF_NAME}.env
script:
- docker build --build-arg SPRING_ACTIVE_PROFILE=$SPRING_ACTIVE_PROFILE -t $DOCKER_REPO .
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD docker.io
- docker push $DOCKER_REPO
deploy:
image: ubuntu:latest
stage: deploy
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- source .${CI_COMMIT_REF_NAME}.env
script:
- ssh root@$SERVER "docker stop $APP_NAME; docker system prune -a -f; docker pull $DOCKER_REPO; docker container run -d --name $APP_NAME -p $PORT:8080 -e SPRING_PROFILES_ACTIVE=$SPRING_ACTIVE_PROFILE $DOCKER_REPO"
before_script
大部分来自官方文档,但是,当然,我们可以对其进行一些调整以满足我们的需求。为不对私钥进行验证,添加了以下代码行:- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
docker stop $APP_NAME
。(这就是我们要在.env文件中定义APP_NAME
的原因 )docker system prune -a -f
。这实际上不是强制性的,但我想删除服务器上所有未使用的镜像。docker container run -d --name $APP_NAME -p $PORT:8080 -e SPRING_PROFILES_ACTIVE=$SPRING_ACTIVE_PROFILE $DOCKER_REPO
END
看完本文有收获?请转发分享给更多人
关注「Java编程鸭」,提升Java技能
关注Java编程鸭微信公众号,后台回复:码农大礼包 可以获取最新整理的技术资料一份。涵盖Java 框架学习、架构师学习等!
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)