Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

Bash 스크립트로 브랜치별 Netlify 설정 자동화하기: 단계별 완벽 가이드

여러 환경(예: 스테이징과 프로덕션)을 운영하는 프로젝트에서 백엔드 API와 프론트엔드 배포를 관리하다 보면, 저장소의 각 브랜치마다 올바른 설정과 명령어를 적용해야 한다는 사실을 깨닫게 됩니다.

특히 여러 개발자가 동시에 코드베이스에서 작업하며 서로 다른 브랜치를 수정하거나, 브랜치별로 개별 설정을 관리해야 하는 상황이라면 이 작업은 만만치 않게 느껴질 수 있습니다.

브랜치에 푸시되는 모든 변경 사항이나 풀 리퀘스트마다 무엇을 병합할지 결정하기 전에 추가·수정·삭제된 모든 코드를 검토해야 합니다. 설정 파일도 예외는 아니며, 사소한 하나의 변경이 전체 CI(지속적 통합) 파이프라인에 영향을 줄 수 있기 때문에 오류가 발생하기 쉬운 부분입니다.

스테이징 또는 프로덕션 브랜치에 변경 사항이 반영되고 빌드가 트리거될 때, 해당 브랜치에 연결된 올바른 리소스가 유지되도록 해야 합니다. 경우에 따라서는 클라이언트마다 다른 리다이렉트 규칙, 빌드 명령어, 기타 브랜치별 설정을 정의해야 할 수도 있습니다.

이 글에서는 간단한 Bash 스크립트를 활용해 여러 브랜치의 리다이렉트를 포함한 브랜치별 설정을 자동으로 관리하는 방법을 소개합니다. 또한 Netlify에서 스테이징 및 프로덕션 브랜치의 컨텍스트별 규칙을 안전하게 병합하는 방법도 함께 알아봅니다.

다룰 내용

  • 프로젝트 구조와 시나리오
  • 리다이렉트(Redirect)/리라이트(Rewrite)란?
  • Netlify가 리다이렉트를 처리하는 방식
    • _redirects 파일 문법 사용하기
    • netlify.toml 설정 파일 문법 사용하기
  • 문제점: 브랜치마다 다른 netlify.toml 파일 관리하기
  • 설정 파일을 자동 생성하는 스크립트 작성 방법
    • netlify.toml 샘플 파일
    • 1단계: scripts 폴더 생성 및 스크립트 파일 추가
    • 2단계: package.json에 스크립트 명령어 추가
  • 클라이언트를 Netlify에 배포하는 방법
    • 첫 배포 진행하기
    • 이후 배포 / 브랜치 배포 설정 방법
      • 1단계: 브랜치별(프로덕션, 스테이징 등) 환경 변수 설정
      • 2단계: 새 배포 트리거하기
  • 배포 결과 확인하기
  • 마무리

프로젝트 구조와 시나리오

하나의 프로젝트를 위해 두 대의 서버를 각각 배포한 상황을 가정해 보겠습니다. 하나는 스테이징 환경(Render에 배포), 다른 하나는 프로덕션 환경(Google Cloud Run에 배포)의 요청을 처리하는 서버입니다.

그리고 Netlify에는 두 개의 클라이언트 배포본이 존재하며, 각각 고유의 API_BASE_URL을 가지고 자신에게 맞는 서버에서 처리됩니다. 아래 그림과 같은 구조입니다.

아래 이미지는 api 폴더와 client 폴더를 포함하는 sample-project 저장소입니다. 앞서 언급한 각 브랜치의 구조 개요이기도 합니다. 각 디렉터리는 자체적인 package.json 파일을 포함하며 독립적인 구성 요소로 취급되어, 두 개의 별도 서비스에 각각 배포될 수 있습니다.

클라이언트의 프론트엔드 배포에서는 /api/v1/로 시작하는 엔드포인트에 대한 모든 요청이 서버로 라우팅됩니다. 나머지 라우트는 프론트엔드 내부에 남아 클라이언트의 페이지로 이동하도록 안내합니다. 따라서 이러한 요청을 어떻게 처리할지 안내하는 올바른 규칙을 작성해야 하는데, 이것이 바로 리다이렉트 규칙 또는 리라이트입니다.

리다이렉트(Redirect)/리라이트(Rewrite)란?

리다이렉트 혹은 리라이트는 특정 URL을 인터넷상의 새로운 위치로 자동 이동시키기 위해 만드는 규칙입니다(WPengine 참고). 흔히 URL 포워딩(URL forwarding)이라고도 불리며, 웹사이트 전체, 웹사이트의 일부 섹션, 또는 웹 애플리케이션 어디에서든 사용할 수 있습니다.

웹 애플리케이션에서 리다이렉트는 주로 요청 처리 방식을 결정하는 데 활용됩니다. Netlify나 Vercel 같은 웹 호스팅 플랫폼 역시 이를 지원하여, 개발자가 자신의 웹 애플리케이션이 요청을 처리하는 방식을 직접 정의할 수 있도록 하고 있습니다.

Netlify가 리다이렉트를 처리하는 방식

Netlify에서 리다이렉트 규칙을 지정하는 방법은 두 가지가 있습니다. _redirects 파일 문법을 사용하거나 netlify.toml 설정 파일 문법을 사용하는 것입니다. 두 방법 모두 동일한 목표를 달성하지만, netlify.toml 문법이 더 많은 옵션과 기능을 제공합니다.

_redirects 파일 문법 사용하기

리다이렉트 문법을 사용하기로 했다면, 클라이언트 앱의 public 폴더에 _redirects 파일을 생성하고 그 안에 리다이렉트 규칙을 작성하면 됩니다. 아주 간단합니다. 아래는 파일 내 리다이렉트 규칙의 예시입니다.

위 규칙은 다음과 같이 해석할 수 있습니다.

  1. /api/v1과 일치하는 모든 요청을 지정된 API URL로 보내고 200 성공 상태 코드를 반환합니다. /api/v1/*에서 볼 수 있듯 /api/v1/ 뒤의 별표(*)는 원래 URL의 나머지 경로를 지정된 API URL 뒤에 붙이라는 의미입니다. 예를 들어 프론트엔드에 /api/v1/users 라우트가 있다면, 해당 요청은 https://your-api-base-url.com/api/v1/users로 리다이렉트됩니다. API URL에 있는 :splat은 단순한 자리 표시자(placeholder)입니다.
  2. 나머지 모든 기본 라우트는 index.html을 통해 서빙합니다. 이는 다른 페이지로 이동한 뒤 "뒤로 가기" 버튼으로 이전 페이지에 접근할 때 페이지가 깨지는 현상을 방지하기 위해 필요합니다.

netlify.toml 설정 파일 문법 사용하기

netlify.toml 설정 파일은 리다이렉트 규칙을 지정할 때 훨씬 더 유연한 기능을 제공합니다. 원본 요청 경로 매칭, 목적지, 원하는 상태 코드 응답, 헤더 규칙, 서명(signature), 국가 제한, 역할(role) 등을 포함한 다양한 옵션을 사용할 수 있습니다.

아래는 Netlify 공식 문서에서 가져온 netlify.toml 샘플 파일입니다.

참고: API로 특정 요청을 리다이렉트하는 용도라면 redirects 파일을 사용하는 것도 충분히 괜찮습니다. 하지만 API_BASE_URL이 비공개여야 한다면, redirects 파일에 API URL을 평문으로 담는 것은 보안 위험으로 간주될 수 있습니다. public 폴더의 모든 파일은 이름 그대로 '공개'되어 누구나 접근할 수 있기 때문입니다.

앱에서 사용하려는 대상 URL이 공개 URL이라면 자유롭게 _redirects 파일 문법을 활용하세요. 하지만 비공개 URL을 선호한다면, netlify.toml 설정 파일과 환경 변수를 함께 사용하는 것이 일반적으로 더 좋은 선택입니다.

문제점: 브랜치마다 다른 netlify.toml 파일 관리하기

netlify.toml 파일로 빌드 명령어와 환경별 설정을 정의하고, 변경 사항을 저장소에 푸시한 후 풀 리퀘스트를 열면, 각 브랜치의 netlify.toml 파일을 수동으로 무시하거나 편집해야 합니다. 결국 이 과정은 매우 번거로워지고 오류에 취약해집니다.

또한 보안상의 이유로 API URL을 프로젝트 코드베이스의 _redirectsnetlify.toml 파일에 하드코딩하지 않고 싶습니다. 대신 Netlify UI에서 제공하는 환경 변수를 프로덕션과 스테이징 컨텍스트에 활용할 것입니다.

위 문제들을 피하기 위해, 우리는 코드베이스에 작은 스크립트를 두어 각 브랜치에 맞는 netlify.toml 파일을 동적으로 생성할 것입니다. 이 접근 방식은 충돌을 없애고, 브랜치를 전환하거나 풀 리퀘스트를 처리할 때 수작업이 필요 없게 만들어 줍니다.

설정 파일을 자동 생성하는 스크립트 작성 방법

netlify.toml 샘플 파일

아래는 각 빌드에서 최종적으로 만들고자 하는 netlify.toml 샘플 파일의 스크린샷입니다. 코드베이스에서 api/v1/과 일치하는 모든 요청이 API로 라우팅되는 것을 확인할 수 있습니다.

API 엔드포인트 구조가 다를 수 있습니다. 예를 들어 /api/your-endpoint처럼요. 그런 경우 스크립트를 그에 맞게 조정하면 됩니다. 이 샘플 프로젝트에서는 api/v1/your-endpoint 구조를 사용합니다.

1단계: scripts 폴더 생성 및 스크립트 파일 추가

client 디렉터리 안에 scripts/ 디렉터리와 configure-netlify.sh 스크립트 파일을 생성합니다. 저장소의 각 브랜치마다 이 작업을 수행해야 하지만, 파일 내용은 모든 브랜치에서 동일합니다.

configure-netlify.sh 스크립트 파일을 열고 다음 내용을 붙여넣습니다:

#!/bin/bash
# Ensure API_BASE_URL is set
if [ -z "$API_BASE_URL" ]; then
 echo "Error: API_BASE_URL environment variable is not set."
 exit 1 # Exit the script to stop the deployment
fi
echo "Using API endpoint: $API_BASE_URL"
# Define the desired Netlify configuration
NETLIFY_CONFIG="
[build]
 command = \"npm install && npm run build\"
 base = \"client\"
 publish = \"dist\"
[[redirects]]
 from = \"/api/v1/*\"
 to = \"$API_BASE_URL/:splat\"
 status = 200
 force = true
[[redirects]]
 from = \"/*\"
 to = \"/index.html\"
 status = 200
"
# Create or update the netlify.toml file
if [ ! -f "netlify.toml" ]; then
 echo "Creating netlify.toml file..."
else
 echo "Updating existing netlify.toml file..."
fi
echo "$NETLIFY_CONFIG" > netlify.toml
# Confirm successful configuration
echo "netlify.toml file has been configured successfully!"

이 스크립트가 하는 일은 다음과 같습니다:

  1. 환경 변수를 확인해 API_BASE_URL이 설정되어 있는지 검사합니다. 설정되어 있지 않으면 스크립트를 종료하고 빌드를 실패시킵니다. 이는 실수로 유효하지 않은 URL이 포함된 배포가 프로덕션에서 성공하는 상황을 막기 위함입니다.
  2. 위 샘플과 같은 내용의 netlify.toml 파일을 생성합니다. API 엔드포인트 구조가 api/v1/your-endpoint와 다르다면, 원하는 구조에 맞게 스크립트를 조정할 수 있습니다.
  3. netlify.toml 파일이 이미 존재하는지 확인합니다. 존재하지 않으면 새로 만들고 내용을 기록하며, 존재하면 빌드 시 환경 변수에 설정된 API_BASE_URL을 사용해 올바른 내용으로 업데이트합니다.

2단계: package.json에 스크립트 명령어 추가

이 스크립트를 빌드 프로세스에 통합하기 위해, 실제 빌드 실행 전에 스크립트를 호출하는 명령어를 package.json 파일에 추가합니다.

package.json의 scripts 항목에 다음과 같이 configure-netlify 명령어를 추가합니다: "configure-netlify": "bash scripts/configure-netlify.sh"

그리고 실제 빌드 전에 스크립트가 먼저 실행되도록 빌드 명령어를 수정합니다: "build": "npm run configure-netlify && vite build".

변경 사항을 저장하고 원격 저장소에 푸시하는 것도 잊지 마세요.

클라이언트를 Netlify에 배포하는 방법

Netlify에 클라이언트를 배포할 때는 세 가지 옵션이 주어집니다:

  1. 기존 프로젝트 가져오기(GitHub, GitLab 같은 Git 저장소 서비스에 존재하는 프로젝트)
  2. 템플릿에서 가져오기
  3. Netlify Drop(드래그 앤 드롭) 인터페이스로 정적 사이트 수동 배포

저장소의 설정이 빌드 과정에서 의도대로 작동하려면, GitHub 같은 기존 프로젝트를 가져오는 옵션을 사용해야 합니다. 드래그 앤 드롭 인터페이스로는 작동하지 않습니다. 부득이하게 드래그 앤 드롭을 사용해야 한다면, 리다이렉트 정의 시 _redirects 파일 문법 옵션을 선택하세요.

첫 배포 진행하기

프로젝트를 처음 배포할 때는 처음에 하나의 브랜치만 배포할 수 있습니다. 다른 브랜치 같은 추가 옵션은 이후 배포 단계에서 지정할 수 있습니다.

프로젝트를 배포하려면 다음 단계를 따르세요:

  1. Netlify 로그인(netlify.com)
  2. "Add new site" 클릭 > "Import an existing project" > "Deploy with GitHub" 선택
  3. "Configure Netlify on GitHub" 클릭 > 저장소 검색 > 선택
  4. 프로젝트의 고유한 사이트 이름 입력
  5. 배포 설정 구성. 여기서 배포할 브랜치를 선택해야 합니다. 첫 배포에서는 프로덕션 브랜치로 사용하는 main 브랜치를 배포합니다.
    • Branch: main/master
    • Build command: npm run build
    • Publish directory: dist (정적 파일이 위치한 디렉터리를 선택하세요. 이 샘플 프로젝트에서는 dist 디렉터리로 내보내지만, 도구에 따라 build 디렉터리로 내보내기도 합니다.)
  6. 프로젝트의 환경 변수를 입력합니다. 서버의 API_BASE_URL을 입력하는 것을 잊지 마세요. Bash 스크립트상 필수 요건입니다.
  7. "Deploy site" 클릭

프로젝트가 정상적으로 배포되면, 성공한 배포 페이지 하단의 배포 상세 정보를 통해 스크립트가 생성한 netlify.toml 설정을 확인할 수 있습니다.

이 파일을 로컬 머신으로 다운로드해 생성된 설정을 살펴볼 수도 있습니다. 위의 netlify.toml 샘플 파일과 일치해야 합니다. 생성된 사이트 링크로 실제 작동 여부를 테스트해 볼 수도 있습니다.

이후 배포 / 브랜치 배포 설정 방법

1단계: 브랜치별(프로덕션, 스테이징 등) 환경 변수 설정

프로젝트가 성공적으로 배포되면, 스테이징 브랜치에 대한 배포를 설정할 수 있습니다. 설정을 편집하려면:

  1. 사이트 목록으로 이동
  2. 성공적으로 배포된 사이트 선택
  3. 왼쪽 메뉴에서 "site configuration" 클릭
  4. "environment variables" 선택 > "Add a variable" 버튼 클릭

변수를 하나씩 추가하거나 .env 파일 전체를 가져오는 옵션이 제공됩니다. 어느 쪽이든 선택할 수 있습니다. 아래 이미지에서는 ".env 파일에서 가져오기"를 선택했습니다.

프로덕션 환경 변수와 함께 main 브랜치에서 배포된 프로덕션 사이트가 이미 배포되어 있으므로, 다음을 수행해야 합니다:

  1. 프로덕션 브랜치 체크 해제 (처음 배포된 main 브랜치가 덮어써지지 않도록 합니다. 브랜치별 환경 변수를 서로 섞지 않도록 주의하세요.)
  2. "branch deploys" 선택
  3. .env 파일의 내용을 복사해 입력란에 붙여넣기
  4. 스테이징 환경용 API_BASE_URL 환경 변수를 추가하는 것을 잊지 마세요.

branch deploys를 선택하면, 여기서 가져온 환경 변수는 프로덕션 브랜치를 제외한 모든 브랜치 배포에 적용됩니다. 커스텀 브랜치를 선택해 컨텍스트를 더 세분화할 수도 있지만, 이는 완전히 다른 접근 방식으로 netlify.toml 설정 파일이나 Bash 스크립트를 추가로 커스터마이징해야 할 수 있습니다.

환경 변수를 각각 개별적으로 가져오기로 결정했다면, 아래와 유사한 옵션이 제공됩니다. 각 브랜치에 맞는 올바른 컨텍스트를 선택했는지 반드시 확인하세요.

모든 컨텍스트에 동일한 값을 사용하지 마세요. 아래 이미지에서 볼 수 있듯 "deploy context마다 다른 값 사용"을 선택하면 각 컨텍스트의 값을 개별적으로 정의할 수 있습니다. 이 경우 branch deploys에 대한 값을 정의합니다. 초기에 사용한 프로덕션 변수는 이미 존재하고 있을 것입니다.

모든 변수를 가져온 후에는, 각 변수 오른쪽의 드롭다운을 선택해 값을 확인함으로써 올바르게 가져와졌는지 검증할 수 있습니다.

2단계: 새 배포 트리거하기

모든 컨텍스트(이 글에서는 프로덕션과 스테이징)의 환경 변수를 모두 가져왔다면, 화면 왼쪽 패널의 "deploys"로 이동하세요. 그다음 "Trigger deploy" 버튼을 누르고, 캐시를 지운 뒤 새 배포를 시작합니다.

배포 결과 확인하기

아무 배포나 선택한 뒤 "Deploy log"에서 build 드롭다운을 열면 스크립트가 의도대로 작동하는지 확인할 수 있습니다. 명령어 실행 과정과 출력값, 그리고 해당 컨텍스트에 정의된 대로 각 배포의 API URL을 확인할 수 있습니다.

마무리

이 가이드의 단계를 따르고, 저장소의 각 브랜치에 스크립트와 업데이트된 명령어를 적용하면, 변경 사항을 푸시할 때마다 Netlify가 각 브랜치의 netlify.toml 파일을 자동으로 생성하거나 업데이트합니다. 이를 통해 빌드 시점에 각 환경에 맞는 올바른 설정과 환경 변수가 사용되도록 보장할 수 있습니다.

스크립트 자체는 모든 브랜치에서 동일하게 유지됩니다. 덕분에 올바른 설정을 스크립트가 안전하고 손쉽게 처리하는 동안, 여러분은 다른 코드 변경에 집중할 수 있습니다.

아무 브랜치나 변경 사항을 푸시해서 직접 확인해 보세요.

Twitter(@francisihej)나 LinkedIn을 통해 저와 연결하실 수도 있습니다!