GitHub Action 을 통해 NGINX 로드 밸런서 배포 자동화 구현

이 블로그 포스트는 GitHub Action을 사용하여 NGINX 로드 밸런서 설정의 자동화된 배포 프로세스를 구현하는 방법을 설명합니다. GitHub Action을 활용하여 코드 변경 시 로드 밸런서 설정이 자동으로 업데이트 되도록 구성하고, 이를 통해 효율적이고 안정적인 배포 환경을 구축할 수 있습니다. 이 글에서는 GitHub Action Workflow의 구성 단계, 주요 설정 파일 배포 및 테스트 방법에 대해 설명합니다.

목차

1. GitHub Action을 통한 NGINX로드 밸런서 자동화 개요
 1-1. GitHub Action 과 NGINX 연동을 통한 자동화 이점
2. GitHub Action을 사용한 NGINX 설정 파일 배포 구성

2-1. GitHub Action 과 NGINX 로드 밸런서 연결 Pipeline을 위한 Secret 추가
 2-2. GitHub Action Workflow 작성 (yaml)
  2-1-1. 설정 파일 배포 자동화 과정
  2-1-2. nginx -t를 통한 구성 테스트 자동화
  2-1-3. nginx -s reload로 로드 밸런서 재시작
3. 구성 테스트 및 로드 밸런서 배포 자동화

4. 결론

1. GitHub Action을 통한 NGINX 로드 밸런서 자동화 개요

1-1. GitHub Action 과 NGINX 연동을 통한 자동화 이점

GitHub Action과 NGINX Plus를 연동하면 코드 변경 시 NGINX Plus의 구성 파일이 자동으로 배포 및 테스트되어 운영 환경에 신속하게 반영됩니다. 수동 배포에서 발생할 수 있는 실수와 시간을 줄일 수 있고, 빠른 롤백 및 수정이 가능해지므로 운영 효율성이 높아집니다.

또한 이러한 자동화는 지속적인 배포 환경을 구축하는 데 중요한 역할을 하며, 코드 관리 및 구성 관리의 일관성을 유지하는 데 도움을 줍니다.

2. GitHub Action을 사용한 NGINX 설정 파일 배포 구성

GitHub Action을 통해 NGINX Plus 설정 파일을 자동으로 배포하는 과정과 설정 파일을 관리하는 방법을 설명합니다. 이를 통해 실시간 구성 변경이 가능한 Workflow를 구현합니다.

배포 자동화를 진행할 GitHub Repository와 설정 파일이 변경될 NGINX 서버가 존재해야 합니다.

NGINX 혹은 NGINX Plus를 설치하는 방법은 아래 링크를 참고하세요.

NGINX STORE Docs: nginx 설치
NGINX STORE Docs: NGINX Plus 설치

2-1. GitHub Action 과 NGINX 로드 밸런서 연결 Pipeline을 위한 Secret 추가

NGINX 로드 밸런서 배포 자동화를 위한 Pipeline 작성 전, GitHub Action과 안전한 통합을 위해 Pipeline 스크립트 내에서 사용될 Secret을 지정합니다.

GitHub Repository의 Settings > Secrets and variables > Actions 탭에서 NGINX 로드 밸런서 서버 연결에 필요한 Secrets을 작성합니다.

연결에 필요한 Secrets의 목록은 다음과 같습니다.

  • REMOTE_SSH_HOST: NGINX 로드 밸런서 서버의 IP 혹은 도메인
  • REMOTE_SSH_PRV_KEY: NGINX 로드 밸런서 서버의 SSH Private Key
  • REMOTE_SSH_USERNAME: NGINX 로드 밸런서 서버의 NGINX 실행 사용자

2-2. GitHub Action Workflow 작성 (yaml)

GitHub Action을 통해 자동화된 배포를 수행하는 YAML Workflow 파일 작성 방법을 다룹니다. 이 Workflow 파일은 구성 파일 변경 시 자동으로 배포 및 테스트를 실행하도록 설정됩니다.

파이프라인 스크립트의 작성은 다음과 같습니다.

name: Deploy NGINX Configuration

on:
  push:
    branches:
      - prod
    paths:
      - "nginx.conf"
      - "conf.d/**"
      
  workflow_dispatch:

Workflow 이름은 “Deploy NGINX Configuration“으로 설정되어 있으며, prod 브랜치의 nginx.conf 파일 및 conf.d/ 디렉토리 내에 push가 발생할 시 이를 감지하여 Workflow가 실행됩니다.

workflow_dispatch 옵션을 추가하여, 사용자가 수동으로 Workflow를 실행할 수 있도록 설정합니다.

jobs:
  deploy:
    runs-on: [self-hosted, linux, x64]

deploy 작업(job)은 self-hosted Linux 서버에서 실행됩니다. 자체 호스팅된 환경은 NGINX 서버와의 네트워크 연결을 쉽게 설정할 수 있도록 해줍니다.

self-hosted 작업 환경을 구성하는 방법은 하기 링크를 참고하세요.

GitHub Docs: self-hosted runner 추가

- name: Check out the repository
  uses: actions/checkout@v4

GitHub Action의 checkout 액션을 사용하여 저장소의 코드를 가져옵니다. prod 브랜치에 push 된 최신 코드가 작업 환경에 다운로드됩니다.

Checkout Version은 포스트 작성 기준 최신 버전인 V4를 사용합니다.

2-2-1. 설정 파일 배포 자동화 과정

GitHub Action에서 SCP(Secure Copy Protocol)를 사용해 NGINX Plus 서버로 구성 파일을 전송하는 단계입니다. SCP는 SSH를 기반으로 하여 안전하게 파일을 전송할 수 있도록 지원합니다.

안전한 SSH 연결을 위해 REMOTE_SSH_PRVKEY Secret을 기반으로 NGINX 로드 밸런서 서버의 SSH Key를 생성합니다.

- name: Create SSH private key file
  run: |
    echo "${{ secrets.REMOTE_SSH_PRVKEY }}" > priv.key
    chmod 600 priv.key

GitHub Secrets (REMOTE_SSH_USERNAME, REMOTE_SSH_HOST, REMOTE_SSH_PRVKEY)를 활용하여 NGINX Plus 서버와 안전한 연결을 설정합니다.

- name: Transfer NGINX Conf file with SCP
  run: |
    scp -i priv.key nginx.conf ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }}:/etc/nginx/
    scp -i priv.key conf.d/*.conf ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }}:/etc/nginx/conf.d/

그런 다음, 변경된 설정 파일(nginx.conf)과 하위 디렉토리의 구성 파일(conf.d/*.conf)을 각각 NGINX 로드밸런서 서버의 /etc/nginx//etc/nginx/conf.d/ 디렉토리로 전송합니다.

SCP를 사용하여 이 과정을 자동화함으로써 구성 파일이 업데이트될 때마다 수동 작업 없이 최신 상태로 배포할 수 있게 됩니다.

2-2-2. nginx -t를 통한 구성 테스트 자동화

NGINX Plus 서버에 배포된 설정 파일이 올바르게 동작하는지 확인하기 위해 nginx -t 명령어를 실행하여 구성을 검증합니다.

- name: Test NGINX configuration
  run: |
    ssh -i priv.key -o StrictHostKeyChecking=no ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }} 'nginx -t' || { echo -e "\033[31mNGINX configuration test failed!\033[0m"; exit 1; }

배포된 설정 파일이 올바르게 동작하는지 확인하기 위해 NGINX Plus 서버에서 nginx -t 명령어를 실행합니다. 이 테스트는 SSH를 통해 원격으로 실행되며, 설정 파일의 문법 오류나 구성 오류를 탐지합니다.

StrictHostKeyChecking=no 옵션은 SSH 연결 시 HostKey 체크를 비활성화하여 파이프라인 스크립트가 유연하게 실행될 수 있도록 합니다.

만약 오류가 발견되면, Pipeline Workflow가 중단되고 오류 메시지가 출력되어 문제를 즉시 파악할 수 있습니다. 이를 통해 잘못된 구성이 운영 환경에 반영되지 않도록 방지하며, 안전하고 신뢰할 수 있는 배포 프로세스를 보장합니다.

2-2-3. nginx -s reload로 로드 밸런서 재시작

- name: NGINX Reload
  run: |
    ssh -i priv.key -o StrictHostKeyChecking=no ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }} 'nginx -s reload'

구성 테스트가 성공적으로 완료되면, 최신 설정 파일을 적용하기 위해 NGINX Plus 서버에서 nginx -s reload 명령어를 실행합니다. 이 명령은 서버를 재시작하지 않고도 새로운 구성을 즉시 반영할 수 있어, 가동 중단 없이 서비스를 연속적으로 제공할 수 있도록 지원합니다.

이러한 자동화된 reload 과정은 배포 속도를 높이고 수동 개입 없이 최신 상태를 유지할 수 있게 해줍니다.

- name: Clean up private key file
  if: always()
  run: rm priv.key

마지막으로 파이프라인 실행 과정 중 생성된 priv.key 파일을 삭제하여 보안 위험을 제거합니다.

Test NGINX configuration 단계에서 파이프라인이 실패하여 종료되어도 priv.key 파일이 삭제되도록 always() 옵션을 추가합니다. 이 단계를 통해 작업 환경에서 민감한 정보가 남지 않도록 합니다.

3. 구성 테스트 및 로드 밸런서 배포 자동화

변경 전 NGINX 로드 밸런서 서버의 구성을 확인합니다. 일반적인 웹 서버의 HTML 응답이 출력되는 것을 확인합니다.

$ curl example.com:8080

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>NGINX STORE</title>

. . .
Workflow yaml 파일의 전체 내용은 다음과 같습니다.

NGINX STORE GitHub: nginx-github-cicd

name: Deploy NGINX Configuration

on:
  push:
    branches:
      - prod
    paths:
      - "nginx.conf"
      - "conf.d/**"

  workflow_dispatch:

jobs:
  deploy:
    runs-on: [self-hosted, linux, x64]

    steps:
    - name: Check out the repository
      uses: actions/checkout@v4

    - name: Create SSH private key file
      run: |
        echo "${{ secrets.REMOTE_SSH_PRVKEY }}" > priv.key
        chmod 600 priv.key
    - name: Transfer NGINX Conf file with SCP
      run: |
        scp -i priv.key nginx.conf ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }}:/etc/nginx/
        scp -i priv.key conf.d/*.conf ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }}:/etc/nginx/conf.d/
    - name: Test NGINX configuration
      run: |
        ssh -i priv.key -o StrictHostKeyChecking=no ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }} 'nginx -t' || { echo -e "\033[31mNGINX configuration test failed!\033[0m"; exit 1; }
    - name: NGINX Reload
      run: |
        ssh -i priv.key -o StrictHostKeyChecking=no ${{ secrets.REMOTE_SSH_USERNAME }}@${{ secrets.REMOTE_SSH_HOST }} 'nginx -s reload'
    - name: Clean up private key file
      if: always()
      run: rm priv.key

NGINX 배포 자동화를 위한 Git Repository를 Clone 한 뒤, 현재 branch와 경로를 확인합니다.

$ git branch

* dev
  prod
$ pwd
                                                                                                                                                                                                                                                          
/home/nginx/nginx-github-cicd/conf.d

$ ls
nginx-cicd.conf

$ cat nginx-cicd.conf

server {
    listen 8080;
    server_name example.com;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

파이프라인 자동화 테스트를 위해 nginx-cicd.conf 의 내용을 수정하여 NGINX를 로드 밸런서로 구성한 뒤, git 명령어를 통해 변경사항을 GitHub 저장소에 반영합니다.

$ cat nginx-cicd.conf

upstream backend { # 로드 밸런싱 대상 서버 정의
    server 127.0.0.1:9098;
    server 127.0.0.1:9099;
}

server {
    listen 8080;
    server_name example.com;

    location / {
        proxy_pass http://backend; # proxy_pass를 통한 NGINX 로드 밸런싱 구현
    }
}

$ git add nginx-cicd.conf

$ git commit -m "NGINX Load Balancer Conf Modify"

$ git push origin dev

GitHub의 Repository에서 "dev" branch에 push가 발생한 것을 확인합니다. Compare & pull request 버튼을 클릭하여 “prod” branch에 push 사항을 반영합니다.

GitHub Action - NGINX 로드 밸런서 변경 사항 반영#1
NGINX 로드 밸런서 변경 사항 반영#2

GitHub의 Actions 탭에서 작성한 파이프라인 스크립트에 의해 prod branch에 push된 사항을 감지하여 workflows가 실행되는 것을 확인합니다.

NGINX 로드 밸런서 변경 사항 반영#3
GitHub Action - 파이프라인 출력

파이프라인 스크립트가 정상적으로 완료되었다면 NGINX 로드 밸런서 서버의 구성과 응답을 재확인 합니다.

$ cat nginx-cicd.conf # NGINX 로드 밸런서 서버 구성 재확인

upstream backend {
    server 127.0.0.1:9098;
    server 127.0.0.1:9099;
}

server {
    listen 8080; # 변경 사항 반영
    server_name example.com;

    location / {
        proxy_pass http://backend; # proxy_pass를 통한 NGINX 로드 밸런싱 구현
    }
}

$ curl example.com:8080 # 로드 밸런싱 테스트

welcome to backend 1

$ curl example.com:8080

welcome to backend 2

$ curl example.com:8080

welcome to backend 1

$ curl example.com:8080

welcome to backend 2

GitHub Action의 Pipeline이 동작하여 NGINX 로드 밸런서의 배포가 자동화 된 것을 확인할 수 있습니다.

반대로 NGINX 구성 검사가 실패하면 파이프라인이 종료되며, SSH Private Key도 함께 삭제되는 것을 확인할 수 있습니다.

4. 결론

이러한 자동화 파이프라인은 수동 작업의 부담을 줄이고, 배포 속도를 높이며, 오류를 예방하여 운영 효율성을 크게 향상시킵니다. 결과적으로 NGINX 혹은 NGINX Plus와 GitHub Action의 조합은 현대적인 DevOps 환경에서 안정성과 생산성을 동시에 추구하는 최적의 선택이라 할 수 있습니다.

다양한 환경에서의 CI/CD 솔루션과 NGINX 혹은 NGINX Plus를 통합하는 방법을 알아보기 위해 NGINX STORE 블로그의 CI/CD 카테고리를 참고하세요.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required