GitLabでCDを行う（オープンデータ活用③）

※この記事はドラフト版です。

# 目的
- ソースが更新されたタイミングで本番環境を更新したい
- モダンな開発に必須といわれる噂のCI/CDを試してみたい

# 方法
- GitLabのCI/CDを使用する
下記の記事を参考に設定しました。
 https://qiita.com/Mochieyan/items/6a71c6908bc6d86d0fc1


# 実施
## 秘密鍵と公開鍵の作成
GitLabから本番環境のサーバへ接続する際に使用する鍵を作ります
Powershellで次のコマンドを実行
```powershell
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
```
次のファイルが作成される
- 秘密鍵「id_rsa」
- 公開鍵「id_rsa.pub」

## 本番環境のサーバに公開鍵を置く
次のファイルに公開鍵「id_rsa.pub」の内容をコピペして保存する
※サーバへの接続は説明省略
```sh
nano ~/.ssh/authorized_keys
```

## GitLab（SaaS版）への登録とプロジェクトの作成
説明は省略
次の構成でサーバと同じ内容のmain.pyを配置
[fastapi]
　[imari_city_opendata]
 　　main.py
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/73b9a8df-7d43-641a-2e27-2bb807ede008.png)


## GitLabに秘密鍵を登録する
[Settings]→[CI/CD]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/3bdac281-0c75-0c78-89a1-b1971e106156.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/d79c8310-510a-a34d-6011-28fdd1ff04ff.png)  

[Variables]→[expand]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/0d57c189-5436-0ff9-d7fd-82c4eda6c808.png)
[Add variable]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/c6456203-f4ef-1a53-0ee1-dda7f0c805b2.png)


次のKeyとValueを設定する
- Key：SSH_PRIVATE_KEY
- Value：秘密鍵「id_rsa」の内容をコピペ

## GitLabのYAMLファイルを作成する
[Build]→[Pipeline editor]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/78bc2686-1712-0f0e-c86c-64eadb86c1ac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/67108849-b11f-c3d4-5e7b-25005eb8d551.png)

### 次の内容を記載
本番環境のサーバにGitLabのfastapiフォルダをコピーする内容です
（先ほど設定した環境変数「$SSH_PRIVATE_KEY」から秘密鍵を取得してsshの接続情報として使う）
```sh
build-job:
  stage: build
  script:
    - echo "Hello, $GITLAB_USER_LOGIN!"

deploy-prod:
  stage: deploy
  before_script:
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$SSH_PRIVATE_KEY" >> ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - eval "$(ssh-agent -s)"
    - ssh-add ~/.ssh/id_rsa
    - ssh-add -l
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
  script:
    - scp -i ~/.ssh/id_rsa -r fastapi ubuntu@example.sakura.ne.jp:/home/ubuntu/app
    - ssh -tt ubuntu@example.sakura.ne.jp -i ~/.ssh/id_rsa -C "sudo systemctl restart fastapi_imari_opendata_gunicorn"
  environment: production

```
### [Commit Change]ボタンを押下
リポジトリにYAMLファイルがプッシュされる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/70b98247-61d7-4f71-9f1e-51948a2c58c6.png)

### pipelineが走る
[Build]→[Pipelines]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/78bc2686-1712-0f0e-c86c-64eadb86c1ac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/14fe4d30-84c0-557b-3252-484f056e6b13.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/7c67e88e-735d-ee46-32b5-33706ac0469d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/2e08b0a1-314e-543a-68f3-8e8cd7d58e66.png)

### 詳細（#番号のリンクをクリック）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/d6e8ae49-4427-9129-17a5-6058aaaee3d3.png)
さらに、[deploy]などをクリックすると詳細が表示される
※色々見えてるので折りたたんでいます。別途要検討。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/cac1681c-c462-be3d-65f5-dd706f1c2689.png)

## main.pyの中身を変更してpushする
### 変更前
```py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}
```

### 変更後
```py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World 20240325"}
```
### コミットとプッシュ
```powershell
git add .
git commit -m "test"
git push
```
### pipelineが走る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/b9be4abe-178c-4531-7b06-67ebdb89b735.png)
### ブラウザで確認
変わっていることが確認できたらCDは成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/f599c185-329c-b3ca-206d-f6deacb9cef9.png)