Post

[DevOps] 깃허브 액션으로 main branch와 sync하는 CD workflow 작성하기

Django CD 깃허브 액션 Workflow

SSH 키 발급

  • 참고로, 아래에서는 구글 클라우드 엔진을 이용해 Django 서버를 돌리고 있다.

  • 우선 방화벽(default로 설정)에서 깃허브 액션이 접근하는 22번 포트를 연다.

  • SSH에서 SSH 키(public-private)쌍을 발급한다. 아래에 나오는 인스턴스와 관련 값들은 이미 삭제되었다.

    • ssh-keygen -t rsa -b 4096 -C "이메일주소"

      1
      2
      3
      4
      5
      
      (myenv) id@instance-20240226-065155:~/.ssh$ ssh-keygen -t rsa -b 4096 -C "이메일주소"
      Generating public/private rsa key pair.
      Enter file in which to save the key (/home/id/.ssh/id_rsa):
      Enter passphrase (empty for no passphrase):
      Enter same passphrase again:
      

      첫 줄과 같이 입력하면 public/private 키 쌍을 만드는 과정에 들어가게 된다. 아무것도 입력하지 않아도 생성되고, 보안이 중요한 상황에서는 설정하는 것이 좋을 것 같다. 입력을 마치면 아래와 같이 키 값이 생성된다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      
      Your identification has been saved in /home/id/.ssh/id_rsa
      Your public key has been saved in /home/id/.ssh/id_rsa.pub
      The key fingerprint is:
      ...
      The key's randomart image is:
      +---[RSA 4096]----+
      ...
      +----[SHA256]-----+
      
      
      (myenv) id@instance-20240226-065155:~/.ssh$ cat /home/id/.ssh/id_rsa
      -----BEGIN OPENSSH PRIVATE KEY-----
      ...
      -----END OPENSSH PRIVATE KEY-----
      

      참고로 PRIVATE KEY를 입력해야 하는 상황에서는 -----BEGIN OPENSSH PRIVATE KEY-----이 줄과 -----END OPENSSH PRIVATE KEY----- 이 줄까지 모두 입력해야 한다.

      1
      2
      
      (myenv) id@instance-20240226-065155:~/.ssh$ cat /home/id/.ssh/id_rsa.pub
      ssh-rsa ...
      

      위 명령어로는 public key를 알 수 있다.(아무것도 입력하지 않았다면)

발급한 키 쌍을 인스턴스와 깃허브에 등록

  • VM 인스턴스에 방금 발급한 SSH public키를 등록한다.
  • 깃허브 secret actions에는 SSH private키와 여러 비밀 변수들을 등록한다.

깃허브 액션 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
name: Django CD

on:
  push:
    branches: ["main"]
    paths:
      - "web/**"
      - ".github/workflows/**"
  pull_request:
    branches: ["main"]
    paths:
      - "web/**"
      - ".github/workflows/**"

  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      SECRET_KEY: $
      DATABASE_USER: $
      DATABASE_PASSWORD: $
      DATABASE_HOST: $
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python 3.12
        uses: actions/setup-python@v3
        with:
          python-version: 3.12

      - name: Execute Remote SSH Commands
        uses: appleboy/ssh-action@master
        with:
          host: $
          username: $
          key: $
          port: 22
          script: |
            source myenv/bin/activate || exit 1
            cd stock_pipeline || exit 1
            git pull origin main || exit 1
            cd web/stock_data_flow || exit 1
            python3 manage.py collectstatic --noinput || exit 1
            python3 manage.py migrate || exit 1
            sudo systemctl daemon-reload || exit 1
            sudo systemctl restart gunicorn.service || exit 1
            sudo systemctl reload nginx || exit 1

  • branches:에는 해당 워크플로우가 동작하게 할 브랜치를 정할 수 있다.
  • paths:에는 해당 워크플로우가 돌아갈 디렉토리를 정할 수 있다.
  • env:에 Django 프로젝트에서 쓰이는 비공개 변수들을 등록한다.
  • username:에 키 발급 주체(id)를 넣는데, secret actions를 이용한다.
  • || exit 1은 실패시 워크플로우 중지를 위한 과정으로 쓰지 않거나 첫줄에만 써도 사실상 관계 없다.
This post is licensed under CC BY 4.0 by the author.