GitLab 온프레미스 CI/CD 파이프라인 구성하기
우분투 24.04에서 GitLab Runner를 활용한 스프링부트 + Go 프로젝트 자동 배포 환경 구성
새 서버를 세팅하면서 GitLab CI/CD를 처음부터 구성할일이 생겨 과정을 담아봤다.
아키텍처
┌──────────────┐ push to main ┌─────────────────────┐
│ 개발자 │ ───────────────────> │ GitLab (온프레미스) │
└──────────────┘ └──────────┬──────────┘
│ CI/CD 트리거
▼
┌─────────────────────┐
│ 배포 서버 │
│ (GitLab Runner) │
│ │
│ git pull → build │
│ → systemctl restart│
└─────────────────────┘┌──────────────┐ push to main ┌─────────────────────┐
│ 개발자 │ ───────────────────> │ GitLab (온프레미스) │
└──────────────┘ └──────────┬──────────┘
│ CI/CD 트리거
▼
┌─────────────────────┐
│ 배포 서버 │
│ (GitLab Runner) │
│ │
│ git pull → build │
│ → systemctl restart│
└─────────────────────┘배포 대상은 스프링 부트(Gradle, Java 17) 프로젝트와, Go 프로젝트로,
각각 다른 레포지토리로 운영되며, main 브랜치에 push 또는 MR(Merge Request)가 되면
Gitlab Runner를 통해 자동 빌드 및 배포까지 진행되도록 한다.
1.계정 권한 분리
배포 전용 유저 생성
서비스 실행용 유저와, CI/CD를 실행 유저를 분리하였다.
# 서비스 실행용 유저 생성
sudo useradd -m -s /bin/bash service-username# 서비스 실행용 유저 생성
sudo useradd -m -s /bin/bash service-username최소 권한 sudoers 설정
gitlab-runner가 서비스 재시작만 할 수 있도록 제한했다.
sudo visudo -f /etc/sudoers.d/gitlab-runner
gitlab-runner ALL=(ALL) NOPASSWD: /bin/systemctl restart springboot-server
gitlab-runner ALL=(ALL) NOPASSWD: /bin/systemctl restart go-serversudo visudo -f /etc/sudoers.d/gitlab-runner
gitlab-runner ALL=(ALL) NOPASSWD: /bin/systemctl restart springboot-server
gitlab-runner ALL=(ALL) NOPASSWD: /bin/systemctl restart go-server이렇게 설정하면, gitlab-runner는 다른 sudo 명령은 실행할 수 없고 위 명령만 실행 가능하다.
2.GitLab Runner 설치
설치
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner -ycurl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner -yRunner 등록
sudo gitlab-runner register \
--non-interactive \
--url "사용하고있는 깃랩 주소" \
--registration-token "토큰" \
--description "deploy-server" \
--tag-list "deploy" \
--executor "shell"sudo gitlab-runner register \
--non-interactive \
--url "사용하고있는 깃랩 주소" \
--registration-token "토큰" \
--description "deploy-server" \
--tag-list "deploy" \
--executor "shell"executor 를 shell로 설정하여, 서버에서 직접 명령을 실행할 수 있다.
url에는 사용하고 있는 깃랩 주소를, registration-token에는 레포지토리-CI/CD Runner 설정에서 확인가능한 토큰을 입력한다.
3.SSH 키 설정
등록한 gitlab-runner 유저가 GitLab에서 코드를 pull 받을 수 있도록, SSH 키를 설정해야한다.
sudo -u gitlab-runner ssh-keygen -t ed25519 -C "gitlab-runner@server" -N "" -f /home/gitlab-runner/.ssh/id_ed25519sudo -u gitlab-runner ssh-keygen -t ed25519 -C "gitlab-runner@server" -N "" -f /home/gitlab-runner/.ssh/id_ed25519공개키를 GitLab 프로젝트의 Settings -> Repository -> Deploy keys 에 등록한다.
Git safe.directory 설정
소유권 문제가 발행하지 않도록 아래와 같이 safe.directory를 설정한다.
sudo -u gitlab-runner git config --global --add safe.directory /path/to/projectsudo -u gitlab-runner git config --global --add safe.directory /path/to/project4. systemd 서비스 구성
스프링 부트 서비스와 Go 서비스 각각 systemd 서비스를 구성한다.
# /etc/systemd/system/springboot-server.service
[Unit]
Description=springboot-server
After=network.target mongod.service
Requires=mongod.service
[Service]
Type=simple
User=service-username
Group=service-username
WorkingDirectory=/path/to/project
ExecStart=/usr/bin/java -jar /path/to/project/build/libs/springboot-server-0.0.1-SNAPSHOT.jar
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target# /etc/systemd/system/springboot-server.service
[Unit]
Description=springboot-server
After=network.target mongod.service
Requires=mongod.service
[Service]
Type=simple
User=service-username
Group=service-username
WorkingDirectory=/path/to/project
ExecStart=/usr/bin/java -jar /path/to/project/build/libs/springboot-server-0.0.1-SNAPSHOT.jar
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target5. .gitlab-ci.yml 파이프라인
마찬가지로 gitlab-ci.yml 설정을 스프링부트 서비스와 Go 레포지토리에 각각 설정한다.
stages:
- deploy
deploy:
stage: deploy
tags:
- console
only:
- main
script:
- cd /path/to/project
- git reset --hard HEAD
- git pull origin main
- ./gradlew build -x test
- sudo systemctl restart springboot-serverstages:
- deploy
deploy:
stage: deploy
tags:
- console
only:
- main
script:
- cd /path/to/project
- git reset --hard HEAD
- git pull origin main
- ./gradlew build -x test
- sudo systemctl restart springboot-server결과
main 브랜치에 push 하면,
GitLab이 Runner에 작업을 전달.
Runner가 서버에서 git pull 진행
빌드 실행 (gradlew / go build)
systemctl restart로 서비스 재기동
이제 수동으로 배포하지않고 main 브랜치에 push만으로 코드 반영이 자동화되었다.