개요
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
등을 받을 수 있음
설정하지 않으면 블록친 부분에 호스트이름 혹은 컨테이너 이름으로 등록되어 외부에서 저장소에 접근할 수 없었음.
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를 등록해주자.
그럼 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_
아래 코드와 같이 여러 옵션 지정이 가능하다.
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 접속 화면을 볼 수 있다.
하단의 Register Now를 통해 회원 가입을 진행하면 서버 관리자의 승인 이후에 gitlab 접근이 가능하다.
관리자 비밀번호 변경
관리자(root
) 비밀번호 변경
$ docker exec -it gitlab /bin/bash
> gitlab-rails console -e production
컨테이너 내부로 진입한 뒤 gitlab-rails ...
명령을 입력해주자. 아래의 사진과 같은 내용이 뜰 때까지 기다려야 한다.
user = User.where(id: 1).first
첫번째 아이디 값을 user에 넣는 명령어이다.
#<User id:1 @root>
라는 응답이 올것이며, 관리자 계정은 root
이다.
user.password='변경할비밀번호'
user.password_confirmation='변경할비밀번호'
root라는 계정이 들어간 user에 변경할 비밀번호를 넣어주자.
user.save
마지막으로 user.save
를 입력하면 끝이다. 정상적으로 root 비밀번호가 변경이 완료되었다면 true
, 변경되지 않았다면 false
가 리턴된다.
보통 false
가 리턴되는 경우는 비밀번호의 글자 수가 8자리가 안되어서 그렇다.
메일 발송 설정
추가로 비밀번호 분실시 메일을 발송할 수 있는 smtp 옵션도 gitlab에서 제공하고 있다.
자세한 내용은 아래 gitlab 가이드 문서를 참고해보자.
‣ gitlab smtp settings
SSH Key 등록
github처럼 gitlab에도 SSH key를 등록하여 프로젝트에 간편하게 접근할 수 있다.