Self managed repository and CI #7 - Gitlab-CI

Jinwon Seo·2022년 12월 5일
0
post-thumbnail

Gitlab에 프로젝트를 생성하고 소스를 울려 gitlab-ci 구성을 하도록 하겠습니다.

Gitlab-CI

Gitlab-CI 설명이 잘 되어있는 영상입니다. 참고하시면 좋겠습니다.

YouTube - GitLab CI CD Tutorial for Beginners

Test project

Initialize

Spring initializr를 통해 test ptoject를 생성 합니다.

Spring initializr

Maven 프로젝트로 선택해 주시고 나머지는 원하는 대로 구성해 주시면 됩니다.

압축을 풀면 아래와 비슷한 구조가 나타납니다.

├─ src
│   ├─ main/...
│   └─ test/...
├─ .gitignore
└─ pom.xml

Maven profile 설정

./pom.xml 에 profile과 repository 설정을 추가합니다.

├─ src
│   ├─ main/...
│   └─ test/...
├─ .gitignore
└─ pom.xml # this!

Maven Deploy 단계에서 두 개의 maven repository에 병렬로 배포하기 위해 profile을 분리했습니다. 하나는 gitlab의 pacakge regisitry, 나머지 하나는 nexus3 maven repository에 배포됩니다.

<!-- ./pom.xml -->

<project>
  <profiles>
    <profile>
      <id>private-gitlab-package-registry-deploy</id> <!--Gitlab package registry 에 배포-->
      <distributionManagement>
        <repository>
          <id>ci-gitlab-maven</id>
          <url>${CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven/</url>
        </repository>
        <snapshotRepository>
          <id>ci-gitlab-maven</id>
          <url>${CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven/</url>
        </snapshotRepository>
      </distributionManagement>
    </profile>
    <profile>
      <id>private-nexus-repository-deploy</id> <!-- Nexus3 maven repository에 배포-->
      <distributionManagement>
        <repository>
          <id>private-nexus3-maven-releases</id>
          <url>http://nexus.domain.com/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
          <id>private-nexus3-maven-snapshots</id>
          <url>http://nexus.domain.com/repository/maven-snapshots/</url>
        </snapshotRepository>
      </distributionManagement>
    </profile>
  </profiles>
  <repositories>
    <!-- private nexus maven repository -->
    <repository>
      <id>private-nexus3-maven</id>
      <url>http://nexus.domain.com/repository/maven-public/</url>
    </repository>
  </repositories>
</project>

Dockerfile 생성

spring boot application을 docker container로 만들(containerize) dockerfile을 생성합니다.

├─ src
│   ├─ main/...
│   └─ test/...
├─ .gitignore
├─ .gitlab-ci-mvn-settings.xml
├─ dockerfile # this!
└─ pom.xml
# ./dockerifle

FROM openjdk:11-jre-slim
VOLUME /tmp
EXPOSE 8080
ARG JAR_FILE=target/*.jar
ADD ${JAR_FILE} ./app.jar
ENTRYPOINT [ "java", "-jar", "./app.jar" ]

Gitlab-ci maven 설정

Runner의 Maven 옵션을 정의한 파일(./.gitlab-ci-mvn-settings.xml)을 추가합니다.

├─ src
│   ├─ main/...
│   └─ test/...
├─ .gitignore
├─ .gitlab-ci-mvn-settings.xml # this!
├─ dockerfile
└─ pom.xml
<!-- ./.gitlab-ci-mvn-settings.xml -->

<settings>
  <servers>
    <!-- private nexus maven repository -->
    <server>
      <id>private-nexus3-maven</id>
      <username>gitlab-ci</username>
      <password>change_me</password>
    </server>
    <!-- private nexus maven releases repository -->
    <server>
      <id>private-nexus3-maven-releases</id>
      <username>gitlab-ci</username>
      <password>change_me</password>
    </server>
    <!-- private nexus maven snapshots repository -->
    <server>
      <id>private-nexus3-maven-snapshots</id>
      <username>gitlab-ci</username>
      <password>change_me</password>
    </server>
    <!-- private gitlab package registry -->
    <server>
      <id>private-gitlab-maven</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Job-Token</name>
            <value>${env.CI_JOB_TOKEN}</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
    <!-- gitlab package registry (CI) -->
    <server>
      <id>ci-gitlab-maven</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Job-Token</name>
            <value>${env.CI_JOB_TOKEN}</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
  </servers>
  <mirrors>
    <!-- private nexus repository -->
    <mirror>
      <id>private-nexus</id>
      <mirrorOf>central</mirrorOf>
      <name>private-nexus3-maven</name>
      <url>http://nexus.domain.com/repository/maven-public/</url>
      <blocked>false</blocked>
    </mirror>
    <!-- private nexus maven releases repository -->
    <mirror>
      <id>private-nexus3-maven-releases</id>
      <mirrorOf>releases</mirrorOf>
      <name>private-nexus</name>
      <url>http://nexus.domain.com/repository/maven-releases/</url>
      <blocked>false</blocked>
    </mirror>
    <!-- private nexus maven snapshots repository -->
    <mirror>
      <id>private-nexus3-maven-snapshots</id>
      <mirrorOf>snapshots</mirrorOf>
      <name>private-nexus</name>
      <url>http://nexus.domain.com/repository/maven-snapshots/</url>
      <blocked>false</blocked>
    </mirror>
  </mirrors>
</settings>

Gitlab-ci 설정

Gitlab-ci가 동작할 수 있도록 .gitlab-ci.yml을 추가합니다. 작성 문법은 아래 링크를 확인해 주시면 좋겠습니다.

.gitlab-ci.yml keyword reference

├─ src
│   ├─ main/...
│   └─ test/...
├─ .gitignore
├─ .gitlab-ci-mvn-settings.xml
├─ .gitlab-ci.yml # this!
├─ dockerfile
└─ pom.xml
# ./.gitlab-ci.yml

variables:
  MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=INFO -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
  MAVEN_CLI_OPTS: "-s .gitlab-ci-mvn-settings.xml --batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"

cache:
  paths:
    - .m2/repository
    - target/

stages:
  - maven-build
  - maven-test
  - maven-deploy
  - docker-deploy

maven-build: # maven build
  image: maven:3.8.6-openjdk-11-slim
  stage: maven-build
  script:
    - mvn $MAVEN_CLI_OPTS clean package -DskipTests
  artifacts:
    paths:
      - target/*.jar
    expire_in: 10 min

maven-test: # maven test
  image: maven:3.8.6-openjdk-11-slim
  stage: maven-test
  script:
    - mvn $MAVEN_CLI_OPTS test

maven-deploy-private-gitlab-package-registry: # deploy to gitlab package registry
  image: maven:3.8.6-openjdk-11-slim
  stage: maven-deploy
  script:
    - mvn $MAVEN_CLI_OPTS clean deploy -P private-gitlab-package-registry-deploy
 
maven-deploy-private-nexus-repository: # deploy to nexus3 maven repository
  image: maven:3.8.6-openjdk-11-slim
  stage: maven-deploy
  script:
    - mvn $MAVEN_CLI_OPTS clean deploy -P private-nexus-repository-deploy
 
docker-deploy-private-gitlab-container-registry: # deploy to gitlab container registry
  image: docker:20.10.18
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_DRIVER: overlay2
    DOCKER_TLS_CERTDIR: ""
  stage: docker-deploy
  services:
    - name: docker:20.10.18-dind
      alias: docker
      command: ["--tls=false", "--insecure-registry=registry.gitlab.domain.com"]
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true;
    - docker build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .;
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA;
    - docker push $CI_REGISTRY_IMAGE:latest;

docker-deploy-private-nexus-container-registry: # deploy to nexus3 container registry
  image: docker:20.10.18
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_DRIVER: overlay2
    DOCKER_TLS_CERTDIR: ""
  stage: docker-deploy
  services:
    - name: docker:20.10.18-dind
      alias: docker
      command: ["--tls=false", "--insecure-registry=registry.nexus.domain.com"]
  before_script:
    - docker login -u "$CI_NEXUS_REGISTRY_USER" -p "$CI_NEXUS_REGISTRY_PASSWORD" $CI_NEXUS_REGISTRY
  script:
    - docker pull $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:latest || true;
    - docker build --tag $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:$CI_COMMIT_SHA --tag $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:latest .;
    - docker push $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:$CI_COMMIT_SHA;
    - docker push $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:latest;

Gitlab project 구성

Project 생성

Gitlab 그룹 & 프로젝트는 원하는 대로 구성해 주시면 됩니다.

Groups > new group > Create group

Groups > 생성한 Group > New project > Create blank project

Enable Static Application Security Testing (SAST) 를 체크하시면 gitlab-ci가 자동으로 생성되는데 그 안에 SAST를 위한 구성이 포함됩니다. 내용은 아래 링크를 확인해 주세요.

Static Application Security Testing (SAST)

빈 프로젝트가 구성되면 아래와 같이 표시 됩니다.

Gitlab-ci 변수 설정

.gitlab-ci.yml에서 사용한 CI 변수(Nexus3 접속 정보)를 정의합니다. Project > Settings > CI/CD Sttings > Variables 에서 프로젝트의 변수를 등록하는 방법과 Admin > Settings > CI/CD Sttings > Variables 에서 gitlab 전역으로 등록하는 방법 두 가지가 있습니다.

주의하실 점은 protected 변수로 정의하면 ci가 동작할 branch도 protected로 설정해야 해당 변수를 사용하실 수 있습니다.

  • CI_NEXUS_REGISTRY_USER: gitlab-ci
  • CI_NEXUS_REGISTRY_PASSWORD: change_me
  • CI_NEXUS_REGISTRY: registry.nexus.domain.com

Push

앞서 구성한 테스트 프로젝트 파일을 repository에 추가하고 push 합니다.

프로젝트의 CI/CD메뉴를 확인 해 보면 앞에서 구성한 .gitlab-ci.yml을 가지고 gitlab-ci가 동작하게 됩니다.

CI/CD > Pipelines > pipeline_no

Cache 확인

프로젝트의 pipeline 의 job의 console log를 확인 해 보면 minio에서 cache를 download하고 upload한 기록을 확인 할 수 있습니다.

CI/CD > Jobs > #job_no > console log

Checking cache for default-protected...
Downloading cache.zip from http://minio.domain.com/private-[MASKED]-cache/project/24/default-protected 
Successfully extracted cache

(생략)

Creating cache default-protected...
.m2/repository: found 2707 matching files and directories 
target/: found 32 matching files and directories   
Uploading cache.zip to http://minio.domain.com/private-[MASKED]-cache/project/24/default-protected 
Created cache

Deploy 확인

CI의 deploy단계가 성공하면 gitlab의 package, container registry와 nexus3의 maven repository, container registry에 deploy됩니다.

Gitlab package registry

CI/CD > Jobs > #job_no > console log

7405 [INFO] Uploading to ci-gitlab-maven: http://gitlab.domain.com/api/v4/projects/24/packages/maven/com/domain/sendbox/[MASKED]/1.0.1-SNAPSHOT/maven-metadata.xml
7607 [INFO] Uploaded to ci-gitlab-maven: http://gitlab.domain.com/api/v4/projects/24/packages/maven/com/domain/sendbox/[MASKED]/1.0.1-SNAPSHOT/maven-metadata.xml (777 B at 3.9 kB/s)
7607 [INFO] Uploading to ci-gitlab-maven: http://gitlab.domain.com/api/v4/projects/24/packages/maven/com/domain/sendbox/[MASKED]/maven-metadata.xml
7842 [INFO] Uploaded to ci-gitlab-maven: http://gitlab.domain.com/api/v4/projects/24/packages/maven/com/domain/sendbox/[MASKED]/maven-metadata.xml (347 B at 1.5 kB/s)
7842 [INFO] ------------------------------------------------------------------------
7842 [INFO] BUILD SUCCESS
7842 [INFO] ------------------------------------------------------------------------
7843 [INFO] Total time:  7.380 s
7843 [INFO] Finished at: 2022-12-02T05:11:54Z
7843 [INFO] ------------------------------------------------------------------------
Saving cache for successful job

Gitlab > project > Packages and registries > Package registry

Gitlab container registry

CI/CD > Jobs > #job_no > console log

$ docker build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .;
Step 1/6 : FROM openjdk:11-jre-slim

(생략)

$ docker push $CI_REGISTRY_IMAGE:latest;
The push refers to repository [registry.gitlab.domain.com/sandbox/ci]

Gitlab > project > Packages and registries > Container registry

Nexus3 maven repository(maven-snapshots)

CI/CD > Jobs > #job_no > console log

7687 [INFO] Uploading to private-nexus3-maven-snapshots: http://nexus.domain.com/repository/maven-snapshots/com/domain/sendbox/[MASKED]/1.0.1-SNAPSHOT/maven-metadata.xml
7736 [INFO] Uploaded to private-nexus3-maven-snapshots: http://nexus.domain.com/repository/maven-snapshots/com/domain/sendbox/[MASKED]/1.0.1-SNAPSHOT/maven-metadata.xml (780 B at 16 kB/s)
7736 [INFO] Uploading to private-nexus3-maven-snapshots: http://nexus.doamin.com/repository/maven-snapshots/com/domain/sendbox/[MASKED]/maven-metadata.xml
7775 [INFO] Uploaded to private-nexus3-maven-snapshots: http://nexus.domain.com/repository/maven-snapshots/com/domain/sendbox/[MASKED]/maven-metadata.xml (367 B at 9.4 kB/s)
7775 [INFO] ------------------------------------------------------------------------
7775 [INFO] BUILD SUCCESS
7775 [INFO] ------------------------------------------------------------------------
7776 [INFO] Total time:  7.281 s
7776 [INFO] Finished at: 2022-12-02T05:12:04Z
7776 [INFO] ------------------------------------------------------------------------
Saving cache for successful job

Nexus3 > maven-snapshots

Nexus3 container registry

CI/CD > Jobs > #job_no > console log

$ docker build --tag $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:$CI_COMMIT_SHA --tag $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:latest .;
Step 1/6 : FROM openjdk:11-jre-slim
11-jre-slim: Pulling from library/openjdk

(생략)

$ docker push $CI_NEXUS_REGISTRY/$CI_PROJECT_NAME:latest;
The push refers to repository [[MASKED]/ci]

Nexus3 > docker-hosted

예제코드

작성된 코드는 아래 Repository에 올려두었습니다.

Github - self-managed-repository-and-ci

EOD

궁금한 점이 있으시면 덧글로 남겨주세요. 확인 하는 대로 답변 드리도록 하겠습니다. :)

  1. Self managed repository and CI #1 - Overview
  2. Self managed repository and CI #2 - Docker network, Nginx reverse proxy
  3. Self managed repository and CI #3 - Nexus3
  4. Self managed repository and CI #4 - Minio
  5. Self managed repository and CI #5 - Gitlab
  6. Self managed repository and CI #6 - Gitlab-runner
  7. Self managed repository and CI #7 - Gitlab-CIㆍ현재 글

0개의 댓글