Nodejs

 


 

소스 : https://github.com/braverokmc79/nestjs-netflix

1.   AWS  Elastic Beanstalk 배포

.gihub/workflows/aws-deploy.yml

name: Deploy to AWS Elastic Beanstalk

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Set Up NodeJS
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Create Env File
        env:
          ENV: ${{secrets.ENV}}
          DB_TYPE: ${{secrets.DB_TYPE}}
          DB_HOST: ${{secrets.DB_HOST}}
          DB_PORT: ${{secrets.DB_PORT}}
          DB_USERNAME: ${{secrets.DB_USERNAME}}
          DB_PASSWORD: ${{secrets.DB_PASSWORD}}
          DB_DATABASE: ${{secrets.DB_DATABASE}}
          HASH_ROUNDS: ${{secrets.HASH_ROUNDS}}
          ACCESS_TOKEN_SECRET: ${{secrets.ACCESS_TOKEN_SECRET}}
          REFRESH_TOKEN_SECRET: ${{secrets.REFRESH_TOKEN_SECRET}}
          AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
          AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
          AWS_REGION: ${{secrets.AWS_REGION}}
          BUCKET_NAME: ${{secrets.BUCKET_NAME}}
        run: |
          touch test.env
          echo ENV="test" >> test.env
          echo DB_TYPE="$DB_TYPE" >> test.env
          echo DB_HOST="localhost" >> test.env
          echo DB_PORT="$DB_PORT" >> test.env
          echo DB_USERNAME="$DB_USERNAME" >> test.env
          echo DB_PASSWORD="$DB_PASSWORD" >> test.env
          echo DB_DATABASE="$DB_DATABASE" >> test.env
          echo HASH_ROUNDS="$HASH_ROUNDS" >> test.env
          echo ACCESS_TOKEN_SECRET="$ACCESS_TOKEN_SECRET" >> test.env
          echo REFRESH_TOKEN_SECRET="$REFRESH_TOKEN_SECRET" >> test.env
          echo AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" >> test.env
          echo AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" >> test.env
          echo AWS_REGION="$AWS_REGION" >> test.env
          echo BUCKET_NAME="$BUCKET_NAME" >> test.env
          echo "test.env created"
          cat test.env

          touch env.env
          echo ENV="$ENV" >> .env
          echo DB_TYPE="$DB_TYPE" >> .env
          echo DB_HOST="$DB_HOST" >> .env
          echo DB_PORT="$DB_PORT" >> .env
          echo DB_USERNAME="$DB_USERNAME" >> .env
          echo DB_PASSWORD="$DB_PASSWORD" >> .env
          echo DB_DATABASE="$DB_DATABASE" >> .env
          echo HASH_ROUNDS="$HASH_ROUNDS" >> .env
          echo ACCESS_TOKEN_SECRET="$ACCESS_TOKEN_SECRET" >> .env
          echo REFRESH_TOKEN_SECRET="$REFRESH_TOKEN_SECRET" >> .env
          echo AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" >> .env
          echo AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" >> .env
          echo AWS_REGION="$AWS_REGION" >> .env
          echo BUCKET_NAME="$BUCKET_NAME" >> .env
          echo ".env created"
          cat .env

      - name: Create Folders
        run: |
          mkdir -p ./public/movie
          mkdir -p ./public/temp

      - name: Install Depencies
        run: npm i

      - name: Build Project
        run: npm run build

      - name: Run Test
        run: npm run test

      - name: Install Typeorm
        run: npm i -g typeorm

      - name: Run Migration
        run: typeorm migration:run -d ./dist/database/data-source.js

      - name: Zip Artfact For Deployment
        run: zip -r deploy.zip .

      - name: Upload To S3
        env:
          AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
          AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
          AWS_REGION: ${{secrets.AWS_REGION}}
        run: |
          aws configure set region $AWS_REGION
          aws s3 cp deploy.zip s3://nestjs-netflix-bucket/deploy.zip

      - name: Deploy To AWS Elastic Beanstalk
        env:
          AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
          AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
          AWS_REGION: ${{secrets.AWS_REGION}}
        run: |
          aws elasticbeanstalk create-application-version \
            --application-name "nestjs-netflix" \
            --version-label $GITHUB_SHA \
            --source-bundle S3Bucket="nestjs-netflix-bucket",S3Key="deploy.zip"

          aws elasticbeanstalk update-environment \
            --application-name "nestjs-netflix" \
            --environment-name "Nestjs-netflix-env" \
            --version-label $GITHUB_SHA

 

 

1)이름과 트리거 조건

name: Deploy to AWS Elastic Beanstalk
on:
  push:
    branches:
      - main
  • 이름: Deploy to AWS Elastic Beanstalk

  • 트리거 조건: main 브랜치에 push가 발생할 때 워크플로 실행

 

 

2)jobs: build-and-deploy

실행 환경

runs-on: ubuntu-latest

Ubuntu 최신 버전에서 워크플로 실행

 

 

3)  PostgreSQL 서비스 (CI 테스트용)

services:
  postgres:
    image: postgres:16
    ...
  • PostgreSQL 16 버전을 도커로 실행

  • 포트: 5432 사용

  • pg_isready를 통해 DB 헬스 체크 수행

 

 

 

4)1. 코드 체크아웃

- name: Checkout Code
  uses: actions/checkout@v3

현재 커밋된 코드를 워크플로에 가져옴

 

 

 

5) 2. Node.js 환경 설정

- name: Set Up NodeJS
  uses: actions/setup-node@v3
  with:
    node-version: '18'
  • Node.js 18버전 설치

 

 

 

6) 3. .env 파일 생성

- name: Create Env File
  • CI/CD에 필요한 .env 파일과 test.env 파일을 생성

  • GitHub Secrets에서 민감한 정보들을 주입

  • localhost DB로 지정한 것은 CI 환경에서 테스트용 PostgreSQL을 사용하기 위함

 

 

7)폴더 생성

- name: Create Folders



./public/movie, ./public/temp 디렉토리 생성

 

 

8) 의존성 설치

- name: Install Dependencies
  run: npm i

 

 

 

9) 프로젝트 빌드

- name: Build Project
  run: npm run build

프로젝트 빌드 (예: NestJS 빌드)

 

 

10) 테스트 실행

- name: Run Test
  run: npm run test

테스트 코드 실행

 

 

11) TypeORM CLI 설치

- name: Install Typeorm
  run: npm i -g typeorm

전역으로 TypeORM CLI 설치 (마이그레이션 실행을 위해)

 

 

12) 마이그레이션 실행

- name: Run Migration
  run: typeorm migration:run -d ./dist/database/data-source.js

 

빌드된 data-source.js를 기반으로 DB 마이그레이션 실행

 

 

 

13)  배포용 압축파일 생성

- name: Zip Artifact For Deployment
  run: zip -r deploy.zip .

 

현재 프로젝트 전체를 deploy.zip으로 압축

 

 

14)  S3 업로드

- name: Upload To S3
  run: |
    aws configure set region $AWS_REGION
    aws s3 cp deploy.zip s3://nestjs-netflix-bucket/deploy.zip

deploy.zip을 S3 버킷에 업로드 (nestjs-netflix-bucket)

 

 

 

15)  Elastic Beanstalk 배포

- name: Deploy To AWS Elastic Beanstalk
  run: |
    aws elasticbeanstalk create-application-version ...
    aws elasticbeanstalk update-environment ...
  • 새 어플리케이션 버전 생성 (커밋 SHA를 버전 라벨로 사용)

  • 해당 버전으로 Elastic Beanstalk 환경 업데이트
    (환경명: Nestjs-netflix-env, 앱명: nestjs-netflix)

 

 

 

 

 

 

 

 

 

2.   우분트 22  SSH  배포

 

다음 참조

✅Spring Boot 3.4 애플리케이션을 우분투 22 서버에 GitHub Actions를 사용해 무중단 배포

 

 

1) SSH 키 기반 인증 준비

 SSH Key 생성 및 서버 등록

 

1. 로컬에서 SSH 키 생성 

여기서 github-actions@our-sample 는 임의 명이다.

github-deploy-key 또한 원하는 이름으로 변경하면된다.

중요한것은 깃허브에서  actions 에서 우분트 22 에 접속할수 있는  개인 키 등록과 우부트 22에 공개 키 설정이다.

 

PowerShell 사용 시 (경로를 명시적으로 써야 함)

ssh-keygen -t rsa -b 4096 -C "github-actions@our-sample" -f "$env:USERPROFILE\.ssh\github-deploy-key"

 

Git Bash 사용 시 (추천).

	
ssh-keygen -t rsa -b 4096 -C "github-actions@our-sample" -f ~/.ssh/github-deploy-key

 

 

2. GitHub에 개인 키 등록

github-deploy-key 내용을 복사

GitHub 저장소> 깃허브 해당 프로젝트에서 > Settings > Secrets and variables > Actions > New secret 이름은 예: DEPLOY_KEY  값을 복붙

 

 

3.서버에 공개 키 등록

권한설정 오류 방지하기 위해 root 디렉토리에 설정

서버에 .ssh 디렉토리 만들기

mkdir -p ~/.ssh
chmod 700 ~/.ssh

공개 키 붙여넣기:
로컬에서 github-deploy-key.pub 파일 내용을 복사한 뒤, 서버에서:

 

중요한 오해 방지 서버에 ~/.ssh/github-deploy-key 추가하는 게 아닙니다.

서버는 공개 키만 필요하며, 개인 키는 절대 서버에 두지 않습니다.

  • 개인 키: GitHub Actions에서만 사용

  • 공개 키: 서버의 ~/.ssh/authorized_keys에만

 

서버 측 ~/.ssh/authorized_keys 확인

우분투 서버에 다음 내용이 등록되어야 합니다:

  • ~/.ssh/authorized_keys 파일에 개인키에 대응되는 공개키가 포함되어야 합니다.

cat ~/.ssh/github-deploy-key.pub >> ~/.ssh/authorized_keys

 

 

루트에 설정해서 루트 권한을 가지게 됩니다

 

cat ~/.ssh/github-deploy-key.pub >> ~/.ssh/authorized_keys

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

 

 

 비밀번호 인증이 막혀 있음 (sshd_config)

원인: SSH 서버에서 PasswordAuthentication no로 설정되어 있으면, 비밀번호 로그인이 불가능합니다.

해결 방법:
서버에서 다음 명령어로 설정 파일 수정:

sudo vi /etc/ssh/sshd_config

 

다음 항목을 찾아서 아래처럼 수정:

PermitRootLogin yes

PasswordAuthentication yes

 

sudo systemctl restart ssh

 

 

 

설치

sudo apt install nodejs npm
npm install -g pm2

 

 

 

2) GitHub에  Secrets  등록

  1. GitHub > Settings > Secrets and variables > Actions > New repository secret

  2. 아래 항목 등록:

  3. 권한 설정 문제 :  

a) DEPLOY_KEY: 개인 키 (~/.ssh/github-deploy-key 내용)
b) HOST: sample.com
c) USER: nextjs
d) TARGET_DIR: /home/nextjs/app
e) SERVICE_NAME: nestjs.service
f) PORT:  1234
g) ENV :  .env 전체 내용을 그대로 붙여넣기

 

 

디렉토리 생성 : 샘플

mkdir -p /home/nextjs/app

 

.env  샘플

#dev = 개발  환경
#prod = 배포 환경
NESTJS_ENV="prod"

TARGET_DIR="/home/nextjs/app"

#DB
DB_TYPE = "postgres"
DB_HOST="192.168.0.19"
DB_PORT="5432"
DB_USERNAME="sample"
DB_PASSWORD="sample"
DB_DATABASE="sample"

# Hash
HASH_ROUNDS=10

# JWT  $ openssl rand -base64 64
ACCESS_TOKEN_SECRET="sample"
REFRESH_TOKEN_SECRET="sample"
JWT_SECRET="sample"

 

 

 

 

 

3) ssh-deploy.yml

GitHub에 등록한 self-hosted runner가 있다면, runs-on:에는 해당 runner를 구분할 수 있는 라벨(label) 을 지정해야 합니다

  runs-on: [self-hosted, nextjs-host]

 

라벨 지정 방법

1)

 

2)

 

서버 실행시 확인

3) sudo systemctl status github-runner

 

 

 

 

 

 

 

 

 

1. runs-on은 runner의 라벨 이름
GitHub Actions에서 runs-on:은 "어떤 runner에서 이 job을 실행할지"를 지정합니다.

GitHub에서 직접 제공하는 runner는 예: ubuntu-latest, windows-latest, macos-latest

Self-hosted runner는 등록할 때 **라벨(label)**을 하나 이상 설정하게 되어 있음

예시:

 

만약에 등록한 값이 없다면, 깃허브에서 기본적으로 제공하는  ubuntu-latest  를 적어 준다.

 

ssh-deploy.yml

name: CI/CD for NestJS

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: [self-hosted, nextjs-host]

    steps:
      - name: ✅ Checkout repository
        uses: actions/checkout@v3

      - name: ✅ Set up Node.js 18
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: ✅ List directory contents
        run: |
          pwd
          ls -alR

      - name: ✅ Create .env file from secrets
        run: |
          mkdir -p backend
          echo "${{ secrets.ENV }}" > backend/.env
          echo ".env created in backend/"

      - name: ✅ Install backend dependencies
        working-directory: ./backend
        run: npm install

      - name: ✅ Build backend project
        working-directory: ./backend
        run: npm run build

      - name: ✅ Setup SSH private key and known_hosts
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -p ${{ secrets.PORT }} -H ${{ secrets.HOST }} >> ~/.ssh/known_hosts

      - name: ✅ Compress and transfer build to remote server
        run: |
          tar -czf backend.tar.gz backend
          scp -F /dev/null -P ${{ secrets.PORT }} backend.tar.gz ${{ secrets.USER }}@${{ secrets.HOST }}:${{ secrets.TARGET_DIR }}/backend-latest.tar.gz

      - name: ✅ Restart service on remote server
        env:
          TARGET_DIR: ${{ secrets.TARGET_DIR }}
          HOST: ${{ secrets.HOST }}
          USER: ${{ secrets.USER }}
          PORT: ${{ secrets.PORT }}
        run: |
          ssh -F /dev/null -p "$PORT" "$USER@$HOST" << 'EOF'
            set -e
            echo "✅ Connected to remote server"

            echo "✅ Extracting build..."
            cd "$TARGET_DIR"
            rm -rf backend_new
            mkdir backend_new
            tar -xzf backend-latest.tar.gz -C backend_new --strip-components=1

            echo "✅ Fixing permissions (if needed)..."
            chown -R nextjs:nextjs "$TARGET_DIR/backend_new"

            echo "✅ Updating symlink..."
            ln -sfn "$TARGET_DIR/backend_new" "$TARGET_DIR/current"

            cd "$TARGET_DIR/current"

            echo "✅ Installing production dependencies..."
            npm install --omit=dev

            echo "✅ Restarting PM2 service..."
            pm2 restart app || pm2 start dist/main.js --name app

            echo "✅ 현재 실행 중인 모든 애플리케이션의 상태를 저장"
            pm2 save

            echo "✅ Deployment complete."
          EOF

 

 

※전송 시 scp로 권한 유지

cat ~/.ssh/github-deploy-key.pub >> ~/.ssh/authorized_keys

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

 

authorized_keys 를 루트에서 설정했기 때문에 루트 권한을 가집니다.

 따라서 scp 자체는 파일을 원격에서 어떤 유저로 실행하는지가 중요합니다.

만약 scp 전송 명령이 root 권한으로 실행되고 있다면, GitHub Action의 self-hosted runner 권한을 nextjs로 제한하거나,

파일 전송 후 아래처럼 권한을 반드시 조정하세요:

 

chown nextjs:nextjs backend-latest.tar.gz

 

authorized_keys 를 루트에서 설정 했기 때문에 github action 에 등록 한 USER 가 일반 접속 유저일경우

 항상 

일반 유저 파일 권한 변경 추가 다음처럼 권한 변경을 추가해야 합니다.

# inside your SSH script
sudo chown -R nextjs:nextjs /home/nextjs/app/backend-latest.tar.gz

 

 

 

 

 

4) 서버에 PM2 설치

서버에 SSH 접속해서 아래 명령어 실행:

# Node.js가 설치되어 있어야 합니다
npm install -g pm2

 

설치 확인:

 

pm2 -v

 

 

Restart service via SSH 설정 설명

- name: Restart service via SSH
  run: |
    ssh -p ${{ secrets.PORT }} ${{ secrets.USER }}@${{ secrets.HOST }} << 'EOF'
      set -e
      cd ${TARGET_DIR}
      tar -xzf backend-latest.tar.gz
      ln -sf ${TARGET_DIR}/backend ${TARGET_DIR}/current
      cd ${TARGET_DIR}/current
      npm install --omit=dev
      npm run build
      pm2 restart nestjs-app || pm2 start dist/main.js --name nestjs-app --env production
    EOF

 

위 명령은:

  • 앱이 이미 실행 중이면 restart

  • 앱이 없으면 새로 start

 

GitHub Actions에서 서버에 코드 배포

 

이미 설정하신 이 부분은 그대로 유지하시면 됩니다:

  • backend를 tar로 압축해서 서버로 전송

  • 서버에서 압축 해제

  • ln -sf로 /home/ubuntu/app/current 심볼릭 링크 생성

즉, current 디렉토리에 항상 최신 NestJS 앱이 배포되게 설정돼 있어야 합니다.

 

 PM2 프로세스 등록 (처음 1번만)

서버에서 다음 명령어로 PM2에 NestJS 앱을 등록합니다

 

cd /home/ubuntu/app/current

# .env가 있는 상태여야 함
npm install --omit=dev
npm run build

# PM2에 등록 (앱 이름은 nestjs-app으로 설정)
pm2 start dist/main.js --name nestjs-app --env production

 

.env는 GitHub Actions에서 이미 자동 생성되어 있으니 괜찮습니다.

 

 

 

 

5). PM2 로그 보기 (서버에서)

pm2 logs nestjs-app

 

 

 

 

 

 

✅ GitHub Actions에서 self-hosted 러너를 설정

 

기본 개념

  • GitHub Actions는 GitHub에서 제공하는 CI/CD(지속적 통합/배포) 도구입니다.

  • 기본적으로 GitHub에서는 무료로 제공되는 호스팅 러너(ubuntu-latest 등)를 사용하지만,

  • 필요에 따라 자체 서버(local, VM, 클라우드 등)를 러너로 등록하여 사용할 수 있습니다. 이것이 self-hosted runner입니다.

 

 

 

Self-Hosted 러너를 사용하는 이유

 

1)성능 제어    :     CPU , 메모리, 스토리지 등 자원을 내가 원하는 수준으로 구성 가능

2) 커스텀 환경  :  특정 라이브러리, 툴체인, DB 등을 미리 설치해 둘 수 있음

3) 보안  :  외부에 노출되지 않은 사내 네트워크나 내부 시스템 접근 가능

4)비용 절감  :   Actions 사용량이 많을 경우 GitHub의 무료 러너 한도를 초과함 → 자체 서버 사용 시 비용 절감

5) Windows/macOS 필요 시   :   GitHub이 기본적으로 Linux 러너만 제공하므로 Windows/macOS 환경이 필요할 경우 직접 구성해야 함

 

 

✅ 설정 요약

  1. GitHub 저장소 → Settings → Actions → Runners

  2. OS 선택 (Linux, Windows, macOS)

  3. 스크립트 복사

  4. 자신의 서버에서 실행 (ex. WSL2에서 실행 가능)

 

 

깃허브 액션 러너 설정

 

 

관리 권한으로 하면 안된다. 또한 접속자 권한으로 실행시에도 다음과 같은 오류가 난다.

 

 

actions-runner 디렉터리 내 파일의 소유권을 현재 사용자로 변경하세요

sudo chown -R $USER:$USER /actions-runner

 

다시 실행 전에 권한을 안전하게 설정해줍니다:

 

chmod -R u+rwX /actions-runner

 

 

위 권한 수정이 완료되면 다시 설정 명령어를 실행하세요:

 

작업은 sudo 없이 현재 사용자 계정으로 실행되어야 합니다. ./run.sh 역시 마찬가지입니다:

./run.sh

 

 

 

 

 

 

 

 

 WSL(Windows Subsystem for Linux)로 리눅스 사용하기

 

✅ WSL이란?

Windows에서 리눅스 커널을 직접 실행할 수 있게 해주는 기능입니다. 일반적으로 Ubuntu 배포판을 가장 많이 사용합니다.

 

✅ 설치 순서 (Windows 10/11 기준)

  1. PowerShell(관리자) 열기

wsl --install

자동으로 Ubuntu 설치됨 (Windows 11에서는 단순 명령어 하나로 끝)

  1. 설치 후 초기 설정

    • 사용자 이름 및 비밀번호 설정

  2. WSL2 설정 확인

wsl --set-default-version 2

 

실행

wsl

또는 시작 메뉴 → Ubuntu 검색

 

✅ GitHub Actions Self-Hosted Runner + WSL 사용 가능?

WSL2 환경에서도 self-hosted 러너를 등록할 수 있습니다.

# WSL2에서 러너 등록
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64-2.316.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.316.0/actions-runner-linux-x64-2.316.0.tar.gz
tar xzf actions-runner-linux-x64-2.316.0.tar.gz

# GitHub에서 발급받은 설정 명령어 붙여넣기 (token 포함)
./config.sh --url https://github.com/your-org/your-repo --token XXXXXX

# 실행
./run.sh

 

 

 

 

 

 

 

✅Ubuntu 시스템에서 부팅 시 /actions-runner/run.sh 자동 실행을 설정하는 방법 

 

1. run.sh 권한 확인

실행 가능 여부를 먼저 확인합니다:

chmod +x /actions-runner/run.sh

 

2. systemd 서비스 파일 생성

sudo nano /etc/systemd/system/github-runner.service

 

[Unit]
Description=GitHub Actions Runner
After=network.target

[Service]
ExecStart=/actions-runner/run.sh
WorkingDirectory=/actions-runner
User=사용자유저
Restart=always

[Install]
WantedBy=multi-user.target

 

 

3. systemd 서비스 등록 및 활성화

# 권한 다시 로딩
sudo systemctl daemon-reexec
sudo systemctl daemon-reload

# 서비스 등록
sudo systemctl enable github-runner.service

# 즉시 실행
sudo systemctl start github-runner.service

# 상태 확인
sudo systemctl status github-runner.service

 

 

확인

  • 시스템 재부팅 후에도 run.sh가 자동으로 실행됩니다.

  • journalctl -u github-runner.service 로 로그 확인 가능

 

✅ 부팅 시 정상 동작 확인 팁

  1. 시스템 재부팅

sudo reboot

 

2.재부팅 후 로그인 없이도 GitHub Runner가 자동 실행되는지 확인:

sudo systemctl status github-runner
 

 

 

 

 

 

 

Self-hosted Runner를 위한 네트워크 및 보안 체크리스트

 

✅ 1. GitHub 서버와의 통신 허용

  • GitHub에서 runner와 통신하기 위해 아웃바운드 포트가 열려 있어야 합니다.

  • 기본적으로 허용해야 할 포트:

    • HTTPS (443) → GitHub와의 통신 (최우선)

    • HTTP (80) → 초기 리디렉션에 사용되기도 함

  • 필수 도메인:

    • github.com, api.github.com, actions.githubusercontent.com 등

대부분의 경우 아웃바운드만 허용되면 충분합니다. 방화벽이 너무 제한적인 환경이라면 도메인 화이트리스트 등록도 필요할 수 있습니다.

 

✅ 2. 방화벽 설정

  • Runner는 GitHub 서버에서 직접 접속하지 않습니다. 즉, GitHub → runner로 인바운드 요청이 발생하지 않음.

  • 따라서 인바운드 포트를 열 필요는 없음, 단:

    • CI 환경 내에서 테스트 대상 애플리케이션이 서버처럼 동작하고 내부적으로 포트를 사용하는 경우, 예: Django 서버 실행 (python manage.py runserver), 해당 포트를 허용해야 함.

 

 

 

# 로컬에서 테스트 시 8000번 포트를 사용할 수 있게 허용
sudo ufw allow 8000

 

 

 

✅ 3. Runner 보안

  • self-hosted runner는 외부 요청을 받아 실행하므로 다음을 고려해야 합니다:

    • 별도의 사용자 계정으로 실행 (루트 권한 X)

    • 실행 환경을 주기적으로 초기화하거나 컨테이너화 (예: Docker)하여 안전하게 유지

    • 필요시 CI 서버를 내부망에서만 접근 가능하게 구성

 

 

예: Ubuntu + UFW 환경에서 최소 설정

# 아웃바운드 허용 (기본적으로 허용되어 있음)
sudo ufw default allow outgoing

# 인바운드는 필요할 때만 허용 (예: Django 서버 테스트용 8000)
sudo ufw allow 8000

# UFW 상태 확인
sudo ufw status

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

Children have the qualities of the parents. (자식은 양친의 성격을 이어 받는다.)

댓글 ( 0)

댓글 남기기

작성