GitLab
GitLab 은 팀의 코드를 한곳에 모아 둡니다. 그 코드를 고쳐서 서비스에 올리기까지 필요한 일도 같은 제품 안에서 합니다. 동료가 코드를 읽고 합치는 일이 같은 화면에서 이어집니다. 회사가 운영하는 서버에 직접 설치해 쓸 수도 있습니다.
쉽고 빠른 이해
GitLab 은 팀의 코드 창고이면서 그 코드를 내보내는 공장입니다. 코드를 올리면 기계가 곧바로 빌드와 테스트를 돌립니다. 통과한 것만 동료가 읽고 합칩니다.
창고와 공장이 따로 있으면 둘을 이어 붙이는 일을 사람이 합니다. 어느 코드가 어느 빌드를 거쳤는지도 두 서비스를 오가며 맞춰 봐야 합니다. 한 제품 안에 두면 그 연결이 이미 되어 있습니다.
돌아가는 방식은 이렇습니다.
- 내 컴퓨터에서 코드를 고쳐 서버에 올립니다
- 서버가 빌드와 테스트를 돌려 결과를 붙여 줍니다
- 동료가 바뀐 줄과 그 결과를 읽고 합칩니다
대가가 있습니다. 직접 설치해 쓰면 그 서버를 굴리는 일이 팀 몫으로 넘어옵니다. 백업도 새 판으로 갈아 끼우는 일도 우리가 합니다. 무료로 받는 판에 없는 기능은 돈을 내야 열립니다.
상세
GitLab 은 Git 저장소를 맡아 두는 웹 서비스입니다. 저장소만 맡는 것이 아니라 코드가 서비스에 올라가기까지 거치는 단계를 같은 제품 안에 함께 넣어 둔 것이 이 제품의 정체입니다.
인터넷 서버에 맡아 두는 Git 저장소
Git 은 파일이 바뀐 이력을 남기는 프로그램입니다. 이렇게 이력을 남기고 되돌리는 일을 버전관리라고 합니다. Git 은 각자의 컴퓨터에 설치해서 씁니다.
이력 전체가 내 컴퓨터 안의 저장소에 들어 있습니다. 저장소는 파일과 그 파일이 바뀐 기록을 함께 담은 폴더입니다. 그래서 Git 은 인터넷이 없어도 돕니다.
여럿이 함께 고치려면 모두가 바라보는 저장소가 하나 있어야 합니다. 내 컴퓨터 밖에 두는 그 저장소를 원격 저장소라고 합니다. GitLab 이 맡는 첫째 일이 이 원격 저장소를 보관하는 것입니다.
원격 저장소와 주고받는 단위는 커밋입니다. 커밋은 한 번에 고친 묶음을 이력에 남긴 것입니다. 내가 만든 커밋을 올리는 동작이 푸시이고, 남이 올린 커밋을 받아 오는 동작이 풀입니다.
내 서버에 직접 설치하는 길
GitLab 을 쓰는 길은 둘입니다. 하나는 GitLab 이 운영하는 웹사이트에 계정을 만들어 쓰는 것이고, 다른 하나는 우리 회사 서버에 이 제품을 설치해 직접 돌리는 것입니다. 둘 다 같은 제품입니다.
직접 설치하는 길이 있다는 것이 이 제품을 고르는 흔한 이유입니다. 코드를 회사 밖 서버에 두면 안 되는 조직이 있습니다. 금융이나 공공처럼 규정이 자료의 보관 장소를 정해 두는 곳입니다. 남의 서버에 맡기는 제품만 있으면 그런 조직은 아예 쓸 수 없습니다.
설치본은 여러 프로그램을 한 덩이로 묶은 것입니다. 화면을 그리는 웹 서버, 데이터를 담는 데이터베이스, 자주 읽는 값을 담아 두는 캐시, 작업을 줄 세우는 큐가 함께 들어 있습니다. 한 번에 설치되지만 굴러가는 조각은 여럿입니다.
flowchart TD
subgraph 우리["우리가 운영하는 서버"]
W["웹 서버"]
R["원격 저장소"]
DB["데이터베이스"]
Q["작업 큐"]
end
subgraph 러너서버["빌드를 돌리는 컴퓨터"]
RUN["러너"]
end
DEV["개발자 컴퓨터"] -->|푸시| W
W --> R
W --> DB
W --> Q
Q -->|빌드 작업을 넘김| RUN
RUN -->|결과를 돌려줌| W
네모 하나가 따로 굴러가는 조각입니다. 러너는 GitLab 이 시킨 명령을 대신 실행해 주는 프로그램입니다. 빌드를 돌리는 이 러너는 따로 떼어 다른 컴퓨터에 두는 것이 보통입니다. 빌드는 시간과 메모리를 많이 쓰기 때문에 웹 서버와 같이 두면 서로 방해합니다.
그래서 직접 설치하는 길에는 품이 듭니다. 이 조각들을 살려 두는 일, 백업과 복구를 챙기는 일, 새 판으로 갈아 끼우는 판올림이 전부 우리 몫이 됩니다. 남의 서버에 맡기면 그 일은 GitLab 이 합니다. 대신 코드가 우리 손 밖에 놓입니다.
합치기 전에 읽는 머지 리퀘스트
여럿이 한 저장소를 고칠 때는 작업마다 브랜치를 따로 냅니다. 브랜치는 이력을 갈래로 나눠 두는 것입니다. 갈라 둔 갈래에서 고치면 남의 작업을 건드리지 않습니다. 여러 갈래 중 모두가 바라보는 본줄기를 기준 브랜치라고 합니다.
다 고친 브랜치는 기준 브랜치에 합쳐야 합니다. 두 갈래를 하나로 잇는 일이 병합입니다. 병합이 끝나면 기준 브랜치에 내 커밋이 들어갑니다.
GitLab 은 병합 앞에 한 단계를 끼워 넣습니다. 그것이 머지 리퀘스트입니다. 머지 리퀘스트는 「내 브랜치를 기준 브랜치에 합쳐 달라」는 요청을 웹 페이지 하나로 만든 것입니다. 그 페이지에 바뀐 줄이 모여 보이고, 동료는 줄마다 의견을 답니다. 남의 코드를 읽고 의견을 주는 이 일이 코드 리뷰입니다.
flowchart TD
M0["기준 브랜치"] --> BR["브랜치"]
BR --> C1["커밋"]
C1 --> C2["커밋"]
C2 --> MR["머지 리퀘스트"]
MR --> MG["병합"]
MG --> M1["기준 브랜치"]
갈라진 갈래가 병합으로 다시 합쳐집니다. 머지 리퀘스트는 그 병합 바로 앞에 끼어 있습니다.
같은 것을 GitHub 는 풀 리퀘스트라고 부릅니다. 이름만 다르고 하는 일은 같습니다.
제품 안에 든 파이프라인
코드가 올라올 때마다 빌드와 테스트를 기계가 돌려 깨진 것을 일찍 찾는 일을 지속적 통합이라고 합니다. 사람이 매번 돌리면 빠뜨리기 쉬워서 기계에 맡깁니다. GitLab 은 이 기능을 제품 안에 갖고 있습니다.
무엇을 돌릴지는 저장소 맨 위에 .gitlab-ci.yml 이라는 설정 파일 하나로 적습니다. 이 파일도
코드와 같은 저장소에 들어 있어서 커밋 이력에 함께 남습니다.
test:
script:
- npm test # 테스트를 돌린다
build:
script:
- npm run build # 결과물을 만든다
test 와 build 는 우리가 이름 붙인 작업입니다. 작업 하나는 명령 몇 줄입니다. 이 작업들을
차례로 엮은 한 벌을 파이프라인이라고 부릅니다. 파이프라인은 푸시가 들어오면 알아서
시작합니다.
작업을 실제로 돌리는 것은 앞에서 본 러너입니다. 러너를 여러 대 두면 작업이 나뉘어 돌아갑니다.
flowchart TD
subgraph P["파이프라인 한 벌"]
T["test 작업"]
B["build 작업"]
end
T --> RA["러너 A"]
B --> RB["러너 B"]
한 벌 안에 작업이 들어 있고, 작업 하나는 러너 한 대가 맡습니다.
빌드가 끝난 결과물을 서버에 올려 서비스를 갈아 끼우는 데까지 이 파이프라인을 이어 붙일 수 있습니다. 사람 손을 거치지 않고 여기까지 자동으로 가는 것을 지속적 배포라고 합니다.
sequenceDiagram
participant 개발자
participant GitLab
participant 러너
개발자->>GitLab: 브랜치를 푸시한다
GitLab->>러너: 파이프라인의 작업을 넘긴다
러너->>GitLab: 통과·실패를 돌려준다
GitLab->>개발자: 머지 리퀘스트에 결과를 붙여 보여 준다
개발자->>GitLab: 통과했으면 병합한다
GitLab->>러너: 배포 작업을 넘긴다
한 번의 고침이 지나가는 순서입니다. 리뷰어는 테스트가 통과했는지 먼저 보고 코드를 읽습니다. 빌드 결과를 보러 다른 서비스로 옮겨 갈 일이 없습니다. 한 제품에 묶어 두어 얻는 것이 이것입니다.
코드 옆에 붙는 일감과 결과물
GitLab 은 저장소 옆에 일을 굴리는 도구를 더 붙여 둡니다. 코드와 같은 제품 안에 있어서 서로 이어 볼 수 있습니다.
| 도구 | 하는 일 |
|---|---|
| 이슈 | 버그 제보와 할 일을 글로 남기고 담당자를 붙입니다 |
| 이슈 보드 | 이슈를 「할 일 · 하는 중 · 끝」 같은 칸에 놓고 옮깁니다 |
| 컨테이너 레지스트리 | 빌드가 만든 실행 꾸러미를 저장소마다 보관합니다 |
| 위키 | 저장소에 딸린 문서를 웹에서 고칩니다 |
이슈는 할 일 하나를 적어 둔 글입니다. 머지 리퀘스트 설명에 이슈 번호를 적으면 어느 고침이 어느 문제를 풀었는지 이어서 볼 수 있습니다.
컨테이너 레지스트리는 컨테이너 이미지를 모아 두는 저장소입니다. 컨테이너 이미지는 프로그램과 그것이 돌아가는 데 필요한 것들을 한 덩이로 묶은 실행 꾸러미입니다. 파이프라인이 만든 이미지를 이 저장소에 두고 배포할 때 꺼내 씁니다.
병합과 배포 기록이 같은 제품 안에 쌓입니다. GitLab 은 그 기록으로 고친 코드가 실제 서비스에 올라가기까지 걸린 시간을 계산해 보여 줍니다. 이 값을 변경 리드 타임이라고 부릅니다. 배포를 다른 도구가 맡고 있으면 이런 값은 기록을 두 곳에서 모아야 나옵니다.
flowchart TD
I["이슈"] -->|번호를 설명에 적는다| MR["머지 리퀘스트"]
MR -->|결과가 붙는다| PL["파이프라인"]
PL -->|만든 이미지를 넣는다| REG["컨테이너 레지스트리"]
REG -->|꺼내 쓴다| DP["배포"]
DP -->|기록이 쌓인다| REC["배포 기록"]
한 줄로 이어져 있어서 어느 고침이 어느 문제를 풀고 어디까지 나갔는지를 한 제품 안에서 따라갈 수 있습니다.
한 제품에 몰아넣어서 잃는 것
저장소·리뷰·빌드·배포·일감을 한 제품이 다 맡습니다. 포기한 것이 그 반대편에 있습니다.
첫째로 무겁습니다. 앞에서 본 조각들이 전부 돌아야 합니다. 직접 설치하면 메모리와 디스크를 많이 씁니다. 저장소만 맡기면 되는 팀에게는 쓰지 않을 기능까지 굴리는 것이 됩니다.
둘째로 하나가 멈추면 같이 멈춥니다. 이 제품이 내려가면 리뷰도 빌드도 배포도 함께 서 있습니다. 도구를 따로 골라 쓰면 하나가 멈춰도 나머지는 돕니다. 이력 전체는 각자의 컴퓨터에 남아 있어서 코드를 잃지는 않습니다.
셋째로 기능이 판마다 갈립니다. GitLab 은 소스를 공개한 판 위에 돈을 내야 쓸 수 있는 기능을 얹는 방식입니다. 무료로 받아 설치한 판에는 없는 기능이 있습니다. 그래서 문서에서 본 화면이 우리 서버에 안 보이는 일이 생깁니다.
쓰지 않는 때
혼자 한 컴퓨터에서만 작업하면 이 제품이 없어도 됩니다. Git 만으로 이력을 남기고 되돌릴 수 있습니다. 다만 그 컴퓨터가 망가지면 이력도 함께 사라집니다.
저장소를 맡아 두는 일만 필요하고 빌드를 돌릴 계획이 없다면 더 작은 서비스로 충분합니다. 쓰지 않는 조각까지 굴릴 이유가 없습니다.
이미 다른 곳에 저장소가 있고 팀이 그 화면에 익어 있다면 옮기는 품도 따져야 합니다. 저장소 자체는 Git 이라 그대로 옮겨지지만 이슈·리뷰 이력·빌드 설정은 제품마다 모양이 달라 손이 갑니다.
관련 항목
GitLab 이 맡아 주는 버전관리 도구와 단위
Git · 버전관리 · 저장소 · 원격 저장소 · 커밋 · 브랜치 · 태그
원격 저장소와 주고받는 Git 동작
클론 · 푸시 · 풀 · 페치 · 병합 · 리베이스 · 충돌 해소
GitLab 위에서 굴러가는 협업 방식
머지 리퀘스트 · 코드 리뷰 · 이슈 · 이슈 보드 · 마일스톤 · 브랜치 전략
GitLab 안에서 코드를 빌드하고 내보내는 기능
파이프라인 · 러너 · 지속적 통합 · 지속적 전달 · 지속적 배포 · 배포 · 워크플로 · 웹훅
파이프라인이 만들어 두는 결과물과 보관소
컨테이너 이미지 · 컨테이너 레지스트리 · 아티팩트 저장소 · Docker
GitLab 서버를 굴릴 때 챙기는 운영 항목
백업과 복구 · 데이터베이스 · 캐시 · 큐 · 셀프 호스팅 · 판올림
GitLab 에 접근할 때 거치는 인증과 권한
인증 · 인가 · SSH · 액세스 토큰 · 권한 · 접근 제어 · 시크릿 관리
배포 기록에서 뽑아내는 팀 지표
DORA · 변경 리드 타임 · 배포 빈도 · 변경 실패율 · Four Keys
같은 역할을 두고 겨루는 저장소 호스팅 서비스
GitHub · Bitbucket · Gitea · Azure DevOps
GitLab 에서 일어난 사건과 그 뒤의 이야기
GitLab 데이터 삭제 사고 · 백업 검증 · 사후 분석
다른 이름: 깃랩 · gitlab · gitlab.com