gitlab-runner
===
###### tags: `git`, `gitlab`, `git-lab`, `github`, `git-hub`, `gitlab-runner`, `pipeline`, `job`
<br>
[TOC]
<br>
## 準備 build 環境 (架設 Runner)
> 官方文件
> - [runner / install / Install GitLab Runner manually on GNU/Linux](https://docs.gitlab.com/runner/install/linux-manually.html#using-binary-file)
> - [runner / configure / Advanced configuration](https://docs.gitlab.com/runner/configuration/advanced-configuration.html)
<br>
### 1. 安裝 runner
```
$ curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
$ sudo apt install gitlab-runner
```
- 關於 `script.deb.sh`
- 沒執行 `script.deb.sh`,會影響 executor: docker 的運作,見 [#executor-docker](#executor-docker) 說明
- 會出現 Unable to pull gitlab-runner-helper
- repository 更新**前**:gitlab-runner 11.2.0 (11.2.0)
- repository 更新**後**:gitlab-runner 15.2.0 (7f093137)
- 沒執行 `script.deb.sh`,不影響 executor: shell 的運作
- 參考資料
- 和艦長一起 30 天玩轉 GitLab系列
- [架設 GitLab CI Runner](https://ithelp.ithome.com.tw/articles/10218938)
<br>
### 2. 建立 runner (註冊 runner)
- #### gitlab UI 上的 runner 資訊
> Settings / CI/CD

---

---

- #### 在 build 環境上建立 runner
- 在 terminal 執行註冊 runner (executor 使用 shell)
```
$ sudo gitlab-runner register
ERRO[0000] Docker executor: prebuilt image helpers will be loaded from /var/lib/gitlab-runner.
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://10.78.26.44:30000/
Please enter the gitlab-ci token for this runner:
wyi4doz9JXZcJgwm7DSZ
Please enter the gitlab-ci description for this runner:
[AA1600128-PLX]: run on the Tj's desktop
Please enter the gitlab-ci tags for this runner (comma separated):
tj tsai, tj-desktop, 153.144, 154.119
Registering runner... succeeded runner=wyi4doz9
Please enter the executor: kubernetes, docker, parallels, shell, docker+machine, docker-ssh+machine, docker-ssh, ssh, virtualbox:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
```
- 在 terminal 執行註冊 runner (executor 使用 docker)
```
(同上)
...
[AA1600128-PLX]: run on the Tj's desktop via docker
Please enter the gitlab-ci tags for this runner (comma separated):
tj tsai:docker, tj-desktop:docker, 153.144:docker, 154.119:docker
Registering runner... succeeded runner=wyi4doz9
Please enter the executor: docker+machine, kubernetes, docker-ssh, parallels, virtualbox, docker-ssh+machine, docker, shell, ssh:
docker
Please enter the default Docker image (e.g. ruby:2.1):
docker:20.10.17
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/home/tj/.gitlab-runner/config.toml"
```
- 相關設定,請查看 [executor: docker](#executor-docker)
- executor
- ~~docker: build 完 image 就不見,除非 build 完立刻 push image~~
- shell: image 會留著
查看設定檔
```toml
$ sudo cat /etc/gitlab-runner/config.toml
concurrent = 1
check_interval = 0
[[runners]]
name = "run on the Tj's desktop"
url = "http://10.78.26.44:30000/"
token = "9wDW8uWJCsUPxdpuWq-C"
executor = "shell"
[runners.cache]
```
- #### 建立完成後
同頁面下會出現 runner 資訊
http://10.78.26.44:30000/ai_maker_template/ml_sklearn/-/settings/ci_cd#js-runners-settings

<br>
### 3. 啟動 runner
- #### :warning: 最初狀態:尚未連線

:::warning
:warning: **注意狀態**:New runner, has not connected yet
:::
<br>
- #### 若此時執行 pipeline,會出現 pending 狀態
> (建立 pipeline,詳見後面說明),會出現 `stuck` 標籤

<br>
- #### 執行驗證 :exclamation:
```
$ gitlab-runner verify
ERRO[0000] Docker executor: prebuilt image helpers will be loaded from /var/lib/gitlab-runner.
WARNING: Running in user-mode.
WARNING: The user-mode requires you to manually start builds processing:
WARNING: $ gitlab-runner run
WARNING: Use sudo for system-mode:
WARNING: $ sudo gitlab-runner...
```
- snapshot
[](https://i.imgur.com/V786W3G.png)
<br>
- #### 啟動 runner :exclamation:
```
$ sudo gitlab-runner run
```
- snapshot
[](https://i.imgur.com/1OpTXHM.png)
<br>
- 此時立刻看到剛剛卡住的 pipeline,立刻接收執行
- Before
[](https://i.imgur.com/CslM6ix.png)
- After
[](https://i.imgur.com/vMxMi97.png)
<br>
### 4. 中斷 runner
```
$ sudo gitlab-runner run
...
...
^C (Control+C 中斷)
All workers stopped. Can exit now builds=0
WARNING: Requested service stop: interrupt builds=0
```
- #### runner 狀態仍正常

- #### pipeline 處於 pending

<br>
### 5. 移除 runner
- **Case1**: gitlab 上的 runner **尚未移除**
```
$ sudo gitlab-runner unregister -u http://10.78.26.44:30000/ -t 9wDW8uWJCsUPxdpuWq-C
ERRO[0000] Docker executor: prebuilt image helpers will be loaded from /var/lib/gitlab-runner.
Running in system-mode.
Unregistering runner from GitLab succeeded runner=9wDW8uWJ
Updated /etc/gitlab-runner/config.toml
```
- **Case2**: gitlab 上的 runner **已經被移除**
```
$ sudo gitlab-runner verify --delete -u http://10.78.26.44:30000/ -t 9wDW8uWJCsUPxdpuWq-C
ERRO[0000] Docker executor: prebuilt image helpers will be loaded from /var/lib/gitlab-runner.
Running in system-mode.
ERROR: Verifying runner... is removed runner=9wDW8uWJ
Updated /etc/gitlab-runner/config.toml
```
- 參考資料
- [How do I delete/unregister a GitLab runner](https://stackoverflow.com/questions/66616014/)
<br>
### executor: docker
- ### [Troubleshooting] Unable to pull gitlab-runner-helper
- #### 問題:無法 pull gitlab-runner-helper:11.2.0
- log (before)
```
Running with gitlab-runner 11.2.0 (11.2.0)
on run on the Tj's desktop via docker d3SMcbVJ
Using Docker executor with image ubuntu:18.04 ...
Pulling docker image gitlab-runner-helper:11.2.0 ...
```

- #### 解法:需要更新 gitlab repository
```
$ curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
$ sudo apt-get install gitlab-runner
```
- log (after)
```
Running with gitlab-runner 15.2.0 (7f093137)
on run on the Tj's desktop via docker d3SMcbVJ
Preparing the "docker" executor
```

- #### 參考資料
- [Unable to pull gitlab-runner-helper](https://forum.gitlab.com/t/unable-to-pull-gitlab-runner-helper/41115)
- [Installing GitLab Runner](https://docs.gitlab.com/runner/install/linux-repository.html#installing-gitlab-runner)
- ### 執行 docker images, docker ps -a
- #### 問題
```
$ docker images
error during connect: Get "http://docker:2375/v1.24/images/json": dial tcp: lookup docker on 172.22.44.53:53: server misbehaving
ERROR: Job failed: exit code 1
```
- snapshot
[](https://i.imgur.com/e6ADgiP.png)
- #### 解法:修改 `config.toml`
```
$ sudo nano /etc/gitlab-runner/config.toml
```
- diff
- before
`volumes = ["/cache"]`
- after
`volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]`
(跟 host 共用)
- config
```toml
[[runners]]
name = "run on the Tj's desktop via docker"
url = "http://10.78.26.44:30000/"
token = "1Pwx8YEjBGzYPJZT276B"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "docker:20.10.17"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
shm_size = 0
```
- `privileged = true` 並非必要條件
<br>
### 補充資料:241 runner
- executor: shell

- executor: docker

```
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
```
<br>
<hr>
<br>
## 開始 build (建立 pipeline)
### 建立 `.gitlab-ci.yml` 檔
1. ### 前往 CI/CD > Pipelines 來建立 Pipeline

- 專案裡一開始沒有 `.gitlab-ci.yml` 檔,就去建立 pipeline 會有 error:
Missing CI config file
[](https://i.imgur.com/GTEtGZq.png)
- 參考資料
- ["Missing CI config file" message on run pipeline, but .gitlab-ci.yml exists](https://stackoverflow.com/questions/67885054/)
- `.gitlab-ci.yml` 檔名,亦可以變更
2. ### 前往 CI/CD > Editor 來建立 `.gitlab-ci.yml` 檔
- #### 點選 **Create new CI/CD pipeline**

- #### 編輯 `.gitlab-ci.yml` 檔,單純印出簡易資訊

範本內容:
```yml
stages:
- build
default:
tags:
- '153.144'
build-image:
stage: build
script:
- echo hello
- echo $USER@$(hostname)
```
- 若沒有添加 tags 資訊,pipeline 會不知道要被送往哪個 runner
[](https://i.imgur.com/NH5Cc8a.png)
pending + stuck
- tags 資訊是聯合的
```
tags:
- abc
- xyz
```
表示指定的 runner ,必須同時具備 `abc`, `xyz` 才符合條件
不然會有 stuck label
- #### `.gitlab-ci.yml` 存檔後,pipeline 會立即自動啟動
:::warning
- 若 runner 尚未連線成功,會有 stuck 標籤
:::danger
:warning: 建立 runner 後,尚未執行 `sudo gitlab-runner verify`
:::
[](https://i.imgur.com/zerJ6uX.png)
<br>
- 若 runner 已連線成功,則會進入 running 狀態
[](https://i.imgur.com/Y9HX1lb.png)
:::
<br>
### 查看 Pipeline 內容
[](https://i.imgur.com/5UFpaol.png)
- 只有一個 job
<br>
### 查看 job 內容 (執行過程)
[](https://i.imgur.com/9hYbYHV.png)
- 只執行兩個簡易 cmd

<br>
### 查看 build 環境
- executor: docker
```
$ echo 'whoami:' `whoami`
whoami: root
$ echo 'pwd:' `pwd`
pwd: /builds/ai_maker_template/ml_sklearn
```
- executor: shell
```
$ echo 'whoami:' `whoami`
whoami: gitlab-runner
$ echo 'pwd:' `pwd`
pwd: /var/lib/gitlab-runner/builds/Wf1FzSgH/0/ai_maker_template/ml_sklearn
```
<br>
<hr>
<br>
## 解讀 `.gitlab-ci.yml`
### 任務結構
```yaml
stages:
- task0
- task1
- task2
- task3
default:
tags:
- '153.144'
# stage: task0
.job0:
stage: task0
script:
- echo '名稱以 . (dot) 開始的 job,將被忽略'
# stage: task1
job1:
stage: task1
script:
- echo 'doing task1'
# stage: task2
job2.1:
stage: task2
script:
- echo 'doing task2.1'
job2.2:
stage: task2
script:
- echo 'doing task2.2'
# stage: task3
job3-a:
stage: task3
script:
- echo 'doing job3-a'
job3-b:
stage: task3
script:
- echo 'doing job3-b'
job3-c:
stage: task3
script:
- echo 'doing job3-c'
```
- 進入執行
[](https://i.imgur.com/ajgUhk6.png)
[](https://i.imgur.com/94RZdEW.png)
- 執行完畢


### 如何動態除錯?
打幾個字,parser 就會在 Edior 上方出現錯誤訊息,並給予提示
- ### [when](http://10.78.26.44:30000/help/ci/yaml/README#when)
[](https://i.imgur.com/hpuSHsS.png)
- 錯誤訊息
:::warning
This GitLab CI configuration is invalid: jobs:job1 when should be one of: on_success, on_failure, always, manual, delayed. [Learn more](http://10.78.26.44:30000/help/ci/yaml/README)
:::
- ### runing time


[](https://i.imgur.com/nImB01j.png)
<br>
### [Job Keywords](http://10.78.26.44:30000/help/ci/yaml/README)
- ### 環境參數
- ### [environment](https://docs.gitlab.com/ee/ci/yaml/index.html#environment)
> - 情境:用於讀取不同環境的帳號/密碼
詳見 [#環境建置](#環境建置) 章節
- ### 條件相關
- ### [when](https://docs.gitlab.com/ee/ci/yaml/index.html#when)
> - http://10.78.26.44:30000/help/ci/yaml/README#when
> - http://gitlab.com/help/ci/yaml/README#when
> - 情境:prod 佈署,使用手動觸發
- 觸發前:

- 觸發後:

- 參考資料
- [Day08 - GitLab CI 流水線上的每個工作都要執行嗎?談工作執行條件設定](https://ithelp.ithome.com.tw/articles/10242771)
- ### [rules](https://docs.gitlab.com/ee/ci/yaml/index.html#rules)
> - http://10.78.26.44:30000/help/ci/yaml/README#rules
> - https://gitlab.com/help/ci/yaml/README#rules
- You cannot use dotenv variables created in job scripts in rules, because rules are evaluated before any jobs run.
- ### [workflow](https://docs.gitlab.com/ee/ci/yaml/index.html#workflow)
> - http://10.78.26.44:30000/help/ci/yaml/README#workflow
> - http://gitlab.com/help/ci/yaml/README#workflow
- ### 任務繼承
- ### [extends](https://docs.gitlab.com/ee/ci/yaml/index.html#extends)
```yaml
stages:
- prod
default:
tags:
- '153.144:docker'
- 'tj tsai:docker'
.dev:
variables:
NAME: 'dev'
script:
- echo [dev] name:$NAME, repo:$REPO
.staging:
variables:
NAME: 'staging'
REPO: 'http://staging'
script:
- echo [staging] name:$NAME, repo:$REPO
# stage: prod
job1:
extends:
- .dev
- .staging
stage: prod
variables:
NAME: 'prod'
script:
- echo [prod] name:$NAME, repo:$REPO
- echo 'Done!'
```
- variable:都是後面蓋掉前面的
- script: 只留最後一個
<br>
<br>
### 他人範例
- http://10.78.26.44:30000/ai_maker_template/ml_ai_maker/-/blob/feature/cicd/.gitlab-ci.yml
- [Gitlab CI/CD: New runner has not been connected yet](https://stackoverflow.com/questions/67820925/)
<br>
<hr>
<br>
## 內建 CI 變數
```
$ env | sort
CI=true
CI_API_V4_URL=http://10.78.26.44:30000/api/v4
CI_BUILDS_DIR=/builds
CI_BUILD_BEFORE_SHA=31f29584414f0c3eaf752391a2b3e199c5f13f8f
CI_BUILD_ID=102558
CI_BUILD_NAME=job2.2
CI_BUILD_REF=9b670b94b08fa57c334bd16ac78c4dc1c911000e
CI_BUILD_REF_NAME=master
CI_BUILD_REF_SLUG=master
CI_BUILD_STAGE=task2
CI_BUILD_TOKEN=[MASKED]
CI_COMMIT_AUTHOR=TJ Tsai(蔡宗容) <tj_tsai@asus.com>
CI_COMMIT_BEFORE_SHA=31f29584414f0c3eaf752391a2b3e199c5f13f8f
CI_COMMIT_BRANCH=master
CI_COMMIT_DESCRIPTION=
CI_COMMIT_MESSAGE=Update .gitlab-ci.yml file
CI_COMMIT_REF_NAME=master
CI_COMMIT_REF_PROTECTED=true
CI_COMMIT_REF_SLUG=master
CI_COMMIT_SHA=9b670b94b08fa57c334bd16ac78c4dc1c911000e
CI_COMMIT_SHORT_SHA=9b670b94
CI_COMMIT_TIMESTAMP=2022-07-26T03:16:05+00:00
CI_COMMIT_TITLE=Update .gitlab-ci.yml file
CI_CONCURRENT_ID=0
CI_CONCURRENT_PROJECT_ID=0
CI_CONFIG_PATH=.gitlab-ci.yml
CI_DEFAULT_BRANCH=master
CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX=10.78.26.44:30000/ai_maker_template/dependency_proxy/containers
CI_DEPENDENCY_PROXY_PASSWORD=[MASKED]
CI_DEPENDENCY_PROXY_SERVER=10.78.26.44:30000
CI_DEPENDENCY_PROXY_USER=gitlab-ci-token
CI_DISPOSABLE_ENVIRONMENT=true
CI_JOB_ID=102558
CI_JOB_IMAGE=ubuntu:20.04
CI_JOB_JWT=[MASKED]
CI_JOB_NAME=job2.2
CI_JOB_STAGE=task2
CI_JOB_STARTED_AT=2022-07-26T03:17:14Z
CI_JOB_STATUS=running
CI_JOB_TOKEN=[MASKED]
CI_JOB_URL=http://10.78.26.44:30000/ai_maker_template/ml_sklearn/-/jobs/102558
CI_NODE_TOTAL=1
CI_PAGES_DOMAIN=example.com
CI_PAGES_URL=http://ai_maker_template.example.com/ml_sklearn
CI_PIPELINE_CREATED_AT=2022-07-26T03:16:06Z
CI_PIPELINE_ID=33441
CI_PIPELINE_IID=57
CI_PIPELINE_SOURCE=push
CI_PIPELINE_URL=http://10.78.26.44:30000/ai_maker_template/ml_sklearn/-/pipelines/33441
CI_PROJECT_CONFIG_PATH=.gitlab-ci.yml
CI_PROJECT_DIR=/builds/ai_maker_template/ml_sklearn
CI_PROJECT_ID=787
CI_PROJECT_NAME=ml_sklearn
CI_PROJECT_NAMESPACE=ai_maker_template
CI_PROJECT_PATH=ai_maker_template/ml_sklearn
CI_PROJECT_PATH_SLUG=ai-maker-template-ml-sklearn
CI_PROJECT_REPOSITORY_LANGUAGES=python,jupyter notebook,makefile,dockerfile,shell
CI_PROJECT_ROOT_NAMESPACE=ai_maker_template
CI_PROJECT_TITLE=ML_sklearn
CI_PROJECT_URL=http://10.78.26.44:30000/ai_maker_template/ml_sklearn
CI_PROJECT_VISIBILITY=private
CI_REGISTRY_PASSWORD=[MASKED]
CI_REGISTRY_USER=gitlab-ci-token
CI_REPOSITORY_URL=http://gitlab-ci-token:[MASKED]@10.78.26.44:30000/ai_maker_template/ml_sklearn.git
CI_RUNNER_DESCRIPTION=run on the Tj's desktop via docker
CI_RUNNER_EXECUTABLE_ARCH=linux/amd64
CI_RUNNER_ID=929
CI_RUNNER_REVISION=7f093137
CI_RUNNER_SHORT_TOKEN=d3SMcbVJ
CI_RUNNER_TAGS=154.119:docker, 153.144:docker, tj-desktop:docker, tj tsai:docker
CI_RUNNER_VERSION=15.2.0
CI_SERVER=yes
CI_SERVER_HOST=10.78.26.44
CI_SERVER_NAME=GitLab
CI_SERVER_PORT=30000
CI_SERVER_PROTOCOL=http
CI_SERVER_REVISION=d98457affdf
CI_SERVER_URL=http://10.78.26.44:30000
CI_SERVER_VERSION=13.12.2
CI_SERVER_VERSION_MAJOR=13
CI_SERVER_VERSION_MINOR=12
CI_SERVER_VERSION_PATCH=2
...
GITLAB_CI=true
GITLAB_FEATURES=
GITLAB_USER_EMAIL=tj_tsai@asus.com
GITLAB_USER_ID=142
GITLAB_USER_LOGIN=Tj_Tsai
GITLAB_USER_NAME=TJ Tsai(蔡宗容)
HOME=/root
```
- 橫跨 job 的 timestamp
- `CI_COMMIT_TIMESTAMP=2022-07-27T08:57:27+00:00`
- `CI_PIPELINE_CREATED_AT=2022-07-27T08:57:28Z`
- [Day05 - GitLab CI 怎麼從外帶入參數到流水線中?談 GitLab 的變數 variable](https://ithelp.ithome.com.tw/articles/10240587)
- CI_COMMIT_REF_NAME:工作目前取得的 Git Repo 所在的 Tag 或 Branch 名稱
- CI_COMMIT_REF_SLUG:如上,但透過方法將名稱精簡至最長63個字元並調整為小寫等,使可用在 URL 使用或主機名稱使用
- CI_COMMIT_SHA:Git Repo 目前所在的 Commit Hash Code
- CI_COMMIT_SHORT_SHA:Git Repo 目前所在的 Commit Hash Code 的前 8 字元
<br>
<hr>
<br>
## 環境建置
> 用途:job 在執行時,可根據**環境參數**的選擇,載入不同的 docker login 所需要的 server IP、帳號和密碼
>
> 範例:
> ```yaml
> infra-166:
> stage: staging
> extends: .push-image
> environment: 10.78.26.166 <---
>
> ...
>
> twcc.tw:
> stage: staging
> extends: .push-image
> environment: twcc.tw <---
> ```
1. **Operations > Environments**
[](https://i.imgur.com/iA8cGen.png)
<br>
2. **New Environment**
[](https://i.imgur.com/2XBh5Xk.png)
- External URL

建立好後,可點擊此圖示連到目的地
<br>
3. **建立好相關環境**
[](https://i.imgur.com/Hah7HzA.png)
<br>
4. **Settings > CI/CD > Variables > Add variables**


5. 建立好的變數清單
>

- 關於密碼設定
- **不編碼情況**
- 密碼以明碼呈現

- **編碼情況**
- 通常以 base64 編碼

- 例如:密碼 `password_twcc_ai`
- 在 local 端,將密碼編碼成 base64
```
$ echo password_twcc_ai | base64
cGFzc3dvcmRfdHdjY19haQo=
```
- 在 `.gitlab-ci.yml` 編寫解碼
```
- echo $PASSWORD | base64 -d
```
- pipeline 執行結果
```
$ echo $PASSWORD | base64 -d
password_twcc_ai
```

- 設定
- **Masked 形式是指**
- 即便不是操作變數,用 hardcode 輸出仍然會被 mark 掉
i.e. 在 log 中有任何敏感的關鍵字,都會被置換成 `[MASKED]`
```yaml
- echo 'PASSWORD:' $PASSWORD
- echo $PASSWORD | base64 -d
- echo 'PASSWORD:cGFzc3dvcmRfdHdjY19haQo='
- X=cGFzc3dvcmRf && Y=dHdjY19haQo= && echo 'PASSWORD:'$X$Y
```


- 參考資料
- [View environments and deployments](https://docs.gitlab.com/ee/ci/environments/)
<br>
<hr>
<br>
## Troubleshooting
### [pipeline] stuck
- 不明原因卡住 pipeline,完全沒動靜

[](https://i.imgur.com/pIvIVxm.png)
[](https://i.imgur.com/vgOEmyi.png)
重新開機後,只有:
[](https://i.imgur.com/ymBCWNW.png)
- 參考資料
- [runner stuck after timeout "Submitting job to coordinator... failed ... Bad Request"](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3922)
<br>
### [executor: shell][pipeline] dial unix /var/run/docker.sock: connect: permission denied
> job url: http://10.78.26.44:30000/ai_maker_template/ml_sklearn/-/jobs/102395
```
$ make docker build -t ml-sklearn:v1 --build-arg NOW="2022/07/25 18:07:47" ./image/
Got permission denied while trying to connect to the Docker daemon socket
at unix:///var/run/docker.sock:
Post http://%2Fvar%2Frun%2Fdocker.sock/v1.24/build?buildargs=...:
dial unix /var/run/docker.sock: connect: permission denied
make: *** [Makefile:35: docker-build] Error 1
```
- snaptshot

- 簡易解決方案
- 將使用者 `gitlab-runner` 添加到 docker 群組下
```
$ sudo usermod -aG docker gitlab-runner
```
- 查看 docker 群組名單
```
$ cat /etc/group | egrep 'docker|gitlab'
docker:x:999:tj,gitlab-runner
gitlab-runner:x:137:
```
- snapshot

<br>
<hr>
<br>
## 教學範例
- [[第 11 屆 iThome 鐵人賽] 和艦長一起 30 天玩轉 GitLab 系列](https://ithelp.ithome.com.tw/users/20120986/ironman/2733)
- [[第 12 屆 iThome 鐵人賽] 用 GitLab CI 玩轉自動化測試與佈署 系列](https://ithelp.ithome.com.tw/users/20072606/ironman/3827)
<br>
<hr>
<br>
## runner 進階設定
- [runner 類型](https://repository.prace-ri.eu/git/help/ci/runners/runners_scope.md#the-scope-of-runners)
- **Shared runners** are available to all groups and projects in a GitLab instance.
- **Group runners** are available to all projects and subgroups in a group.
- **Specific runners** are associated with specific projects. Typically, specific runners are used for one project at a time.