GitLab 온프레미스 CI/CD 파이프라인 구성하기

우분투 24.04에서 GitLab Runner를 활용한 스프링부트 + Go 프로젝트 자동 배포 환경 구성

·약 3분·조회 676·수정일: 2026년 10월 5일

새 서버를 세팅하면서 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-server
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-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 -y
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner -y

Runner 등록

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_ed25519
sudo -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/project
sudo -u gitlab-runner git config --global --add safe.directory /path/to/project

4. 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.target

5. .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-server
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-server

결과

main 브랜치에 push 하면,

  1. GitLab이 Runner에 작업을 전달.

  2. Runner가 서버에서 git pull 진행

  3. 빌드 실행 (gradlew / go build)

  4. systemctl restart로 서비스 재기동

이제 수동으로 배포하지않고 main 브랜치에 push만으로 코드 반영이 자동화되었다.

공유