Profile picture

[Docker] 깃랩(gitlab) CE(Community Edition) 서버 구축

JaehyoJJAng2023년 06월 16일

개요

xx 기업은 내부 소프트웨어 개발팀에 필요한 새로운 솔루션을 평가하고 있다.

기존의 협업 및 버전 관리 도구가 가지고 있는 기능은 매우 제한적이고 보안 문제가 있기 때문에 새로운 솔루션으로 변경하고자 한다.

솔루션에 요구되는 사항들은 아래와 같다.

  • 보안 및 데이터 소유권
    • 기업은 보안 및 데이터 소유권을 강화하고자 함
    • 외부 호스팅 솔루션은 기업 데이터의 외부 저장소로의 이동을 필요로 하므로 보안적인 이슈가 우려됨
  • 사용자 정의와 통제
    • 개발팀은 자체적으로 사용자 정의 및 통제를 할 수 있는 솔루션을 원함
    • 내부 보안 정책에 맞게 사용자 접근을 제어하고 서버를 관리할 필요가 있음
  • 성능 및 확장성
    • 대규모 소프트웨어 프로젝트를 다루기 위해 성능이 우수하고 확장 가능한 솔루션
  • 비용 절감
    • 오픈 소스이거나 비용이 효율적인 솔루션
  • 오프라인 환경 지원
    • 보안 및 규정 준수를 위해 오프라인(폐쇄망) 환경에서도 사용 가능한 솔루션

이러한 요구사항을 충족시키기 위해 자체 Gitlab 서버를 구축하고 운영하기로 결정함.

Gitlab은 보안, 사용자 정의, 성능, 확장성 등을 지원하는 강력한 협업 및 버전 관리 플랫폼으로 인정받고 있다.

자체 Gitlab 서버를 구축함으로써 보안 및 데이터 소유권을 강화하고 사용자 접근과 통제를 유지할 수 있게된다.

또한 비용 절감을 위해 클라우드 기반 호스팅 솔루션 대신 자체 Gitlab 서버 구축을 할 것이므로 오프라인 환경에서도 사용 가능한 보안 요구 사항을 충족시킬 수 있게된다.


서버 스펙

  • Server OS: Proxmox VE 8.0
  • VM OS: Ubuntu 22.04
  • Spec
    • CPU: AMD Ryzen 5600X (6 Core / 12 Thread)
    • RAM: DDR4 64GB

사전 준비

  • Docker / Docker Compose 설치 필수

Gitlab 설치


Docker run

gitlab 이미지 pull

docker pull gitlab/gitlab-ce

gitlab 컨테이너 실행

docker run -d -it \
--hostname gitlab.waytothem.store \
--name gitlab \
--restart always \
--env GITLAB_OMNIBUS_CONFIG="external_url 'http://{서버IP주소}:8080'; gitlab_rails['gitlab_shell_ssh_port'] = 2422" \
--env GITLAB_TIMEZONE=Asia/Seoul \
-p 443:443 -p 8080:80 -p 2422:22 \
-v "$(pwd)/gitlab/config:/etc/gitlab" \
-v "$(pwd)/gitlab/logs:/var/log/gitlab" \
-v "$(pwd)/gitlab/data:/var/opt/gitlab" \
gitlab/gitlab-ce

--hostname {서버 IP주소} \

컨테이너의 호스트 이름을 지정. 원하는 이름으로 지어도 무방


--env GITLAB_OMNIBUS_CONFIG="external_url 'http://{서버 IP주소}:8080'; gitlab_rails['gitlab_shell_ssh_port'] = 2422" \
--publish 443:443 --publish 8080:80 --publish 2422:22 \

도커 실행시 해당 컨테이너의 환경설정을 추가해서 실행시킬 수 있음

필자의 경우 80번 포트가 서버에서 이미 사용 중이었기에 호스트 포트를 8080으로 변경하였다.

그리고 external_url에 포트 번호(=여기서는 8080)를 명시해줬다면 호스트 포트, 컨테이너 포트를 동일하게 맞춰주어야 한다!

이유는 external_url 포트 지정 문제에서 확인하도록 하자.
(해당 설정은 gitlab.rd 파일에 적용됨)



gitlab의 external_url 설정을 해야지만 저장소의 주소에 접근할 수 있어 git clone or git pull 등을 받을 수 있음

설정하지 않으면 블록친 부분에 호스트이름 혹은 컨테이너 이름으로 등록되어 외부에서 저장소에 접근할 수 없었음.
image


external_url 포트 지정 문제

external_url을 지정하지 않을 경우 --env GITLAB_OMNIBUS_CONFIG 해당 부분의 설정은 필요없음

하지만 git clone or git pull을 받을려면 설정이 꼭 필요함.

따라서 external_url을 위처럼 추가한뒤에 -p(--publish) 설정을 아래와 같이 넣어주었음.

-p 443:443 -p 8080:80 -p 2422:22

🔴 그래도 접근할 수 없음!

-p 8080:80으로 접속 포트를 변경하였는데 gitlab에 접근할 수 없었다.

이유는 external_url에 포트번호를 지정할 경우 아래 3개의 포트가 모두 같아야 한다.

외부에서 들어오는 포트, 내부에서 listen하는 포트, gitlab.rd 파일에 설정한 포트

gitlab을 운영할때, 각 링크가 gitlab.rd 파일 기준으로 연동되기 때문에 위처럼 포트를 맞춰주지 않으면 링크가 깨지게 된다


그래서 아래와 같이 수정해줘야 한다.

외부에서 들어오는 포트: 8080, 내부에서 listen하는 포트: 80 -> 8080

정리하면 다음과 같다.

-p 443:443 -p 8080:8080 -p 2422:22

Docker Compose

docker run으로 컨테이너 실행 시 옵션이 추가될수록 명령어가 길어져 기억하기가 힘들다.

물론 아래와 같이 스크립트로 남겨놓아도 되지만

#!/bin/bash

docker=$(which docker)
$docker run -d -it --name \
--hostname gitlab.waytothem.store \
...

Docker Compose를 통해 명령어를 설정 해두면 실행 시 매우 편리하기 때문에 Docker Compose를 사용하도록 하자.


docker-compose.yaml

version: '3.8'
services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    container_name: gitlab
    hostname: 'gitlab.example.com'  # 실제 도메인을 사용하거나, IP로 사용 가능
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "8022:22"  # Git over SSH
    volumes:
      - ./data/gitlab/config:/etc/gitlab
      - ./data/gitlab/logs:/var/log/gitlab
      - ./data/gitlab/data:/var/opt/gitlab
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.example.com'
        gitlab_rails['gitlab_shell_ssh_port'] = 8022
        # 필요 시 SMTP, LDAP 설정 등 추가 가능

  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    container_name: gitlab-runner
    restart: always
    depends_on:
      - gitlab
    volumes:
      - ./data/runner/config:/etc/gitlab-runner
      - /var/run/docker.sock:/var/run/docker.sock
  • hostname, external_url 및 포트 (80, 443, 8022)등은 환경에 맞게 조정해주자.
  • Gitlab runner는 Docker 모드를 사용하기 위해 /var/run/docker.sock를 마운트해야 한다.


Gitlab Runner 등록하기

  • GitLab 웹UI(관리자 계정 로그인)에서 Admin -> Runners 메뉴 또는 Project -> Settings -> CI/CD -> Runners 메뉴에서 등록 토큰(Registration Token)을 얻을 수 있다.
  • 컨테이너 내부에서 Runner를 등록하거나, docker exec 명령으로 호스트에서 실행할 수 있다.

참고로 gitlab runner 15.6에서는 gitlab UI에서 직접 runner를 등록해줘야 한다.


1. gitlab에 접근 후, 레포지토리를 하나 생성하고 Settings -> CI/CD 순으로 이동하여 다음과 같이 Runner를 등록해주자.
Image


그럼 Step 1에서 다음 명령어를 실행하여 runner를 등록하라고 나올텐데

gitlab-runner register  --url http://192.168.219.179:8888  --token glrt-t3_ExfNMYPP4Fu7yw7gSkze

본인의 경우 runner를 도커 컨테이너로 띄워줬으니 다음과 같이 수정해주겠다.

docker exec -it <runner 컨테이너 이름> register --url <gitlab 서버 IP:포트번호> --token glrt-t3_jax_XMYDdXtTEJ19sRa_

Image


아래 코드와 같이 여러 옵션 지정이 가능하다.

docker exec -it "<RUNNER_CONTAINER_NAME>" gitlab-runner register \
  --non-interactive \
  --url "<GITLAB_SERVER_IP:PORT>" \
  --registration-token "<YOUR_TOKEN>" \
  --executor "docker" \
  --docker-image "python:3.10-slim" \
  --description "my-runner" \
  --tag-list "docker" \
  --locked="false" \
  --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
  --docker-volumes "/cache"


Gitlab Runner 설치 이유?

  • GitLab(서버)은 사용자/프로젝트/파이프라인 설정을 관리하고, CI/CD Job을 스케줄링한다.
  • 실제로 코드를 빌드·테스트·배포하는 '실행 환경'(Runner)은 별도의 프로세스 혹은 컨테이너에서 동작한다.
  • Runner를 여러 대(다른 서버나 클라우드)에 설치하고, 프로젝트마다 다른 태그나 Executor(Docker, Shell, Kubernetes 등)를 사용할 수 있다.
  • GitLab CI/CD 파이프라인이 실행되면, GitLab 서버는 등록된 Runner에게 작업을 요청(Job 할당)하고, Runner가 그 작업을 실제로 수행한다.

CI/CD 기능을 사용하려면 최소한 1대 이상의 Runner가 있어야 하고,

그렇지 않으면 GitLab에 파이프라인을 설정하더라도 실제로 작업이 실행되지 않게 되는 문제가 발생한다.

따라서 “그냥 GitLab CE만 도커로 설치한다” 는 것은 코드 저장소, 이슈 트래커, Merge Request 등의 기능은 쓰지만,

CI/CD 파이프라인을 돌릴 Runner는 따로 두지 않겠다는 의미가 되는거다.

만약 자동 빌드/배포(파이프라인 실행)를 하고 싶다면, 반드시 GitLab Runner를 추가로 설치하고 등록해야 한다.



Gitlab Runner 에러 로그

ERROR: Failed to load config stat /etc/gitlab-runner/config.toml: no such file or directory  builds=0 max_builds=1

원인

  • GitLab Runner는 실행 시 /etc/gitlab-runner/config.toml 파일을 로드해 어떤 GitLab 서버에 연결할지, 어떤 토큰을 사용해서 어떤 태그로 동작할지 등의 설정 정보를 읽는다.
  • 아직 Runner 등록을 하지 않아서(또는 볼륨 마운트/복사가 제대로 되지 않아서) config.toml이 없으면 “No such file or directory” 에러가 뜰 수 있다.

단순히 runner 등록이 되지 않아 발생하는 문제이니 gitlab runner 등록하기를 참고하여 runner를 등록해주자.



접속하기

도커를 실행한 뒤 http://{서버IP주소}:{지정포트번호}로 접속하면 아래와 같은 gitlab 접속 화면을 볼 수 있다.
image
하단의 Register Now를 통해 회원 가입을 진행하면 서버 관리자의 승인 이후에 gitlab 접근이 가능하다.


관리자 비밀번호 변경

관리자(root) 비밀번호 변경

$ docker exec -it gitlab /bin/bash
> gitlab-rails console -e production

컨테이너 내부로 진입한 뒤 gitlab-rails ... 명령을 입력해주자. 아래의 사진과 같은 내용이 뜰 때까지 기다려야 한다.
image


user = User.where(id: 1).first

첫번째 아이디 값을 user에 넣는 명령어이다.

#<User id:1 @root> 라는 응답이 올것이며, 관리자 계정은 root이다.
image


user.password='변경할비밀번호'
user.password_confirmation='변경할비밀번호'

image
root라는 계정이 들어간 user에 변경할 비밀번호를 넣어주자.


user.save

image
마지막으로 user.save를 입력하면 끝이다. 정상적으로 root 비밀번호가 변경이 완료되었다면 true, 변경되지 않았다면 false가 리턴된다.

보통 false가 리턴되는 경우는 비밀번호의 글자 수가 8자리가 안되어서 그렇다.


메일 발송 설정

추가로 비밀번호 분실시 메일을 발송할 수 있는 smtp 옵션도 gitlab에서 제공하고 있다.

자세한 내용은 아래 gitlab 가이드 문서를 참고해보자.
gitlab smtp settings


SSH Key 등록

github처럼 gitlab에도 SSH key를 등록하여 프로젝트에 간편하게 접근할 수 있다.
image


Loading script...