學習目標
- 用
services在 job 旁邊開暫時的 Redis、PostgreSQL。 - 用
alias當主機名稱連線。 - 知道 job 變數會傳給 service,以及怎麼等 service 準備好。
- 會用
image:entrypoint覆寫映像的進入點。
觀念
┌──────── 同一個 job 的網路 ────────┐
│ job 容器 (postgres:17-alpine) │
│ psql -h db ───────────────┐ │
│ service 容器 (alias: db) ◀───┘ │
└───────────────────────────────────┘
job 結束 → 兩個容器都刪掉,資料不會留下來| 設定 | 說明 |
|---|---|
services[].name | 服務的映像,請固定版本 |
services[].alias | 在 job 裡用來連線的主機名稱 |
variables | job 與 service 都拿得到,postgres 用 POSTGRES_DB 等變數初始化 |
image:entrypoint: [""] | 不跑映像預設的進入點,避免它搶先啟動資料庫 |
等服務準備好
service 啟動需要幾秒,直接連可能失敗。本關用迴圈等:
sh
for i in $(seq 1 30); do pg_isready -h db -U tutorial && break; sleep 1; done安全提醒
本關的 PostgreSQL 用 POSTGRES_HOST_AUTH_METHOD: trust 免密碼,只因為它是 job 結束就刪掉的測試資料庫,而且只在 job 自己的網路裡。正式環境一律要密碼,密碼放 CI/CD 變數並勾選 Masked。
動手做
- 看
postgres-test的紀錄,最後會印出 10 筆課程。 - 把
schema.sql多加一筆,grep -qx 10會失敗:測試真的有讀資料庫。 - 把
alias: db改成alias: database,連線會失敗,記得 script 一起改。
常見錯誤
- 用
localhost連 service:service 是另一個容器,要用 alias。 - service 用了
latest:哪天大版本升級,測試突然失敗。 - 以為 service 的資料會保留到下一個 job:不會,要保存請用 artifacts。
下一關
Lv.9 把部署變成看得見的環境:environments。
範例檔案
資料夾 lv08-services/ 的全部檔案。.gitlab-ci.yml 可以直接複製到自己的專案根目錄執行。
lv08-services/.gitlab-ci.yml
lv08-services/.gitlab-ci.yml
# Lv.8 Services:在 job 旁邊開一個暫時的資料庫或服務,做整合測試
# service 是另一個容器,和 job 在同一個網路,用 alias 當主機名稱連線;job 結束就刪掉。
stages:
- integration
redis-test:
stage: integration
image:
name: redis:7.4-alpine
entrypoint: [""] # 不用映像預設的進入點,直接跑我們的 script
services:
- name: redis:7.4-alpine
alias: cache
script:
- redis-cli -h cache ping
- redis-cli -h cache set lesson lv08
- test "$(redis-cli -h cache get lesson)" = "lv08"
- echo "Redis 讀寫正常"
postgres-test:
stage: integration
image:
name: postgres:17-alpine
entrypoint: [""]
services:
- name: postgres:17-alpine
alias: db
# job 的變數也會傳給 service,postgres 映像用這些變數初始化資料庫
variables:
POSTGRES_DB: tutorial
POSTGRES_USER: tutorial
# 只有這個一次性的測試資料庫用免密碼登入;正式環境一律要密碼,密碼放 CI/CD 變數
POSTGRES_HOST_AUTH_METHOD: trust
script:
- for i in $(seq 1 30); do pg_isready -h db -U tutorial && break; sleep 1; done
- psql -h db -U tutorial -d tutorial -v ON_ERROR_STOP=1 -f lv08-services/schema.sql
- psql -h db -U tutorial -d tutorial -tAc "SELECT count(*) FROM lessons" | grep -qx 10
- psql -h db -U tutorial -d tutorial -c "SELECT id, title FROM lessons ORDER BY id"lv08-services/schema.sql
lv08-services/schema.sql
-- Lv.8 整合測試用的資料表:十關課程
CREATE TABLE lessons (
id integer PRIMARY KEY,
title text NOT NULL
);
INSERT INTO lessons (id, title) VALUES
(1, '第一條 Pipeline'),
(2, 'Stages 與 Jobs'),
(3, 'Artifacts'),
(4, 'Variables'),
(5, 'Cache'),
(6, 'Rules 與 workflow'),
(7, 'Needs 與 DAG'),
(8, 'Services'),
(9, 'Environments'),
(10, '實機部署到 k8s');