如何在 Docker 使用 GitLab CI
TLDR
- 使用 Docker Compose 部署 GitLab 時,務必設定
external_url以確保 SSH 與 HTTP 連結正確。 - 若需使用
artifacts功能,請務必使用 Docker Volume 而非 Bind Mount,以避免權限不足問題。 - GitLab Runner 若使用 Docker Executor,需掛載
/var/run/docker.sock以便在容器內呼叫外部 Docker Engine。 - 註冊 Runner 時,若 GitLab 未設定正確的
external_url,需在config.toml中手動指定clone_url。 .gitlab-ci.yml中的network_mode不可設為host,建議使用gitlab_default以避免網路衝突。- 部署階段若需操作 Docker,建議透過掛載
docker.sock的方式(Docker-outside-of-Docker),而非使用 DIND。
在 Docker 上安裝 GitLab
在 Docker 環境中部署 GitLab 時,建議使用 Docker Compose 進行管理。
yaml
version: '3.7'
services:
GitLab-Server:
image: 'gitlab/gitlab-ee:latest'
container_name: GitLab-Server
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://127.0.0.1:5080/'
nginx['listen_port'] = 80
gitlab_rails['gitlab_shell_ssh_port'] = 5022
ports:
- 5080:80
- 5443:443
- '5022:22'
privileged: true
volumes:
- .\Volumes\GitLab-Server\Config:/etc/gitlab
- data:/var/opt/gitlab
- .\Volumes\GitLab-Server\Logs:/var/log/gitlab
shm_size: '256m'
networks:
default:
ipv4_address: 172.20.0.2
restart: always
volumes:
data:
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1TIP
external_url必須設定,否則儲存庫的 SSH 與 HTTP 連結網址會出現異常。- 若使用非 80 port,需同時設定
nginx['listen_port']。 - 若出現「invalid port specification」錯誤,請將
ports設定中的5022:22改為字串格式(加上引號)。 /var/opt/gitlab建議使用 Volume 連結,若使用 Bind Mount 可能會導致artifacts功能因權限不足而失效。
在 Docker 上安裝與註冊 GitLab Runner
若要執行 CI/CD 任務,需額外部署 GitLab Runner。若使用 Docker Executor,必須掛載 Docker Socket。
yaml
GitLab-Runner:
image: gitlab/gitlab-runner:latest
container_name: GitLab-Runner
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- .\Volumes\GitLab-Runner\Config:/etc/gitlab-runner
networks:
default:
ipv4_address: 172.20.0.3
restart: always註冊流程
執行指令:docker exec -it GitLab-Runner gitlab-runner register。
- 什麼情況下會遇到問題:當 GitLab 未設定
external_url或使用127.0.0.1時,Runner 可能無法正確連線。 - 解決方案:在
config.toml中手動加入clone_url = "http://172.20.0.2"。 - 設定重點:在
config.toml中,將privileged設為true,並確保volumes包含/var/run/docker.sock。
WARNING
network_mode 不可設定為 host,否則可能導致 GitLab 服務忙碌無法回應。
GitLab CI 實例 (.NET 6)
透過 .gitlab-ci.yml 定義 Build、List、Deploy 三個階段。
yaml
stages:
- build
- list
- deploy
build-job:
stage: build
image: mcr.microsoft.com/dotnet/sdk:6.0
tags: ['docker', 'linux']
script:
- cd src/TestCore
- dotnet restore
- dotnet build --configuration Release
- dotnet publish --configuration Release --output ../../build/publish
artifacts:
paths:
- ./build/publish/*
deploy-job:
stage: deploy
tags: ['docker', 'linux']
script:
- cd build
- docker build --tag $CI_PROJECT_PATH_SLUG:latest .
- docker stop $CI_PROJECT_NAME || true && docker rm $CI_PROJECT_NAME || true
- docker run -d -p 9080:80 --name $CI_PROJECT_NAME $CI_PROJECT_PATH_SLUG:latest關鍵技術分析
- Artifacts 傳遞:由於每個 Stage 都是獨立的 Container,必須透過
artifacts將編譯後的檔案從build-job傳遞至deploy-job。 - Docker-outside-of-Docker:透過掛載
docker.sock,讓 Runner 能夠直接呼叫宿主機的 Docker Engine 來建置與執行容器,此方式比 DIND 更穩定且易於管理。 - 環境變數:使用
$CI_PROJECT_PATH_SLUG處理專案名稱,因為 Docker Image 名稱不支援大寫字母。


異動歷程
- 2022-10-24 初版文件建立。
