---
# System prepended metadata

title: Gitlab CI/CD pipeline 簡單實作
tags: [DevOps]

---

# Gitlab CI/CD pipeline
Gitlab 提供 CI/CD pipeline 讓使用者實踐持續整合與持續部署
撰寫.gitlab-ci.yml做為CI/CD pipeline自動執行各階段指令的腳本

pipeline可自行定義stages
常見如:
* test
* build
* deploy

stage中又定義了幾個jobs
例如:
* test stage的test_job1、test_job2
* build stage的build_api、build_ui
* deploy stage的deploy_prod

stage與job在Gitlab中的圖像呈現:
![](https://hackmd.io/_uploads/SkBQ2Xk-T.png)
圖片來源:Gitlab documentation

stage可以定義順序並按照順序執行
若前面的stage中有一job執行失敗
則後面的stage都不會執行

而每個job都由不同的Gitlab runner獨立執行job
各runner環境獨立不互相影響
所以每個job可以同時進行

**Gitlab CI/CD pipeline 的結構與流程:**
![](https://hackmd.io/_uploads/H1v1sXJZa.png)
圖片來源:gitlab.com

# 實作
### 簡介
用Gitlab CI/CD pipeline自動化完成
Build docker image跟上傳至docker hub的動作
此例使用一簡單Flask App實作
### Push to Gitlab
將程式碼與Dockerfile一同上傳至Gitlab專案中

![](https://hackmd.io/_uploads/BJGXzXk-6.png)

此例Flask App內容:
```python=
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World from Flask"

if __name__ == "__main__":
    # Only for debugging while developing
    app.run(host='0.0.0.0', debug=True, port=80)
```

Dockerfile內容:
```dockerfile!
FROM tiangolo/uwsgi-nginx-flask:python3.11
COPY ./app /app
```

### 變數設置
登入docker hub時需要使用到的User Id跟密碼
可以透過設置變數的方式帶入Script
設置位置: project settings > CI/CD > Variables
![](https://hackmd.io/_uploads/rkaDDm1Zp.png)

已新增的變數:
![](https://hackmd.io/_uploads/Hya3DQ1Z6.png)

### Add .gitlab-ci.yml
新增並撰寫.gitlab-ci.yml 來自動執行pipeline裡各stage中job的script

.gitlab-ci.yml內容:
```yml
#定義有哪些stage
stages:
    - build
#要使用的image
image: docker:latest
#定義job
push_docker_image:
  services:
    - docker:dind
  #此job屬於哪一stage
  stage: build
  #執行script前的script
  before_script:
    # 登入docker hub
    - docker login -u $dockerhub_userID -p $dockerhub_password
  #主要script
  script: 
    # build docker image
    - docker build -t flask_image .
    # add tag to image
    - docker tag flask_image  $dockerhub_userID/flask_image
    # push to docker hub
    - docker push $dockerhub_userID/flask_image
```

Commit changes之後就會開始自動執行pipeline
每個stage會依順序執行
若stage中有一job執行fail 後面的stage就不會執行

pipeline開始執行後可到job裡查看script執行過程
![](https://hackmd.io/_uploads/Hk91r7kW6.png)
![](https://hackmd.io/_uploads/S1R6VXkZ6.png)

執行成功
可見Build完成的docker image已經上傳至docker hub
![](https://hackmd.io/_uploads/ByG7L7yZ6.png)

project repository:
https://gitlab.com/leefangyu/flaskapp

# Reference
https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/?source=post_page-----b8bdc60d1dc7--------------------------------

https://docs.gitlab.com/ee/ci/variables/