真香,GitLab 和 Docker自动化部署SpringBoot应用
更多精彩 第一时间直达
GitLab CI
易于学习,使用和可扩展
维护容易
整合容易
CI完全属于GitLab存储库的一部分
良好的Docker集成
镜像托管(Container registry)-基本上是你自己的私有Docker Hub
从成本上来说,GitLab CI是一个很好的解决方案。每个月你有2000分钟的免费构建时间,对于某些项目来说,这是绰绰有余的
为什么GitLab CI超越Jenkins
那为什么选择GitLab?
使用GitLab CI 前提条件
你已经在GitLab上推送了Spring Boot项目
你已在应用程序服务器上安装了Docker(指南)
你具有Docker镜像的镜像托管(本文中将使用Docker Hub)
你已经在服务器上生成了SSH RSA密钥(指南)
你要创建什么
构建应用程序Jar文件
构建Docker镜像
将镜像推送到Docker存储库
在应用程序服务器上运行镜像
基本项目信息
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版本
Java 8-构建时间:约4分钟,镜像大小为 约180 MB Java 11-构建时间:约14分钟,镜像大小约为480 MB
Docker镜像
备注:动态的变量
ENTRYPOINT [ “ java”,“ -Dspring.profiles.active = development”,“ -jar”,“ appdemo.jar” ]
ENTRYPOINT [ “ java”,“ -Dspring.profiles.active = $ SPRINT_ACTIVE_PROFILE”,“ -jar”,“ appdemo.jar” ]
gitlab-ci.yml
创建.env文件和分支
.develop.env .qa.env .master.env
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"
SPRING_ACTIVE_PROFILE:不言自明,我们要使用哪些Spring应用程序属性。 DOCKER_REPO:这是Docker镜像的存储库;在这里,我们唯一需要注意的是Docker image TAG,对于每种环境,我们将使用不同的标签,这意味着我们将使用dev,qa 和prod 标签。
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私钥。
你需要复制完整的密钥值,包括:—– BEGIN RSA PRIVATE KEY —–和—– END RSA PRIVATE KEY —–
创建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
before_script: - source .${CI_COMMIT_REF_NAME}.env
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"
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
停止正在运行的Docker容器:docker stop $APP_NAME。(这就是我们要在.env文件中定义APP_NAME的原因 )
删除所有未运行的Docker镜像: docker system prune -a -f,这实际上不是强制性的,但我想删除服务器上所有未使用的镜像。
拉取最新版本的Docker镜像(该镜像是在上一个阶段中构建并推送的)。
最后,使用以下命令运行Docker镜像:
docker container run -d --name $APP_NAME -p $PORT:8080 -e SPRING_PROFILES_ACTIVE=$SPRING_ACTIVE_PROFILE $DOCKER_REPO