ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • VULTR에 docker(nginx+next.js) CI/CD 설정
    Server/클라우드서버(AWS,VULTR) 2025. 12. 14. 22:21

    이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

    코드변경 → 자동으로 빌드 → 자동으로 서버 배포

     

    CI / CD란?

    CI (Continuous Integration)

    CI = GitHub Actions에서 Docker build 하는 단계

    코드가 합쳐질 때 자동으로 검증/빌드

    지금 우리가 하는 CI 요소:

    • GitHub에 코드 push / merge
    • GitHub Actions 실행
    • Docker 이미지 빌드
    • 이미지 정상 생성 확인

    CD (Continuous Deployment)

    CD = 서버에 자동 배포하는 단계

    검증된 결과물을 자동으로 서버에 반영

    지금 우리가 하는 CD 요소:

    • 빌드된 Docker 이미지를 GHCR(GitHub Container Registry, Docker 이미지를 저장하는 GitHub 공식 저장소)에 push
    • Vultr 서버에서 최신 이미지 pull
    • docker-compose로 컨테이너 재시작
    • nginx 통해 즉시 서비스 반영

    CI/CD 흐름

    git push / PR merge
       ↓
    [GitHub Actions]
    - Docker build (CI)
    - GHCR push
       ↓
    [Vultr 서버]
    - docker pull
    - docker compose up -d (CD)
       ↓
    [유저]
    새 버전 서비스 이용

     

    0. 전제 조건 (이미 된것)

    • Vultr 서버 생성됨
    • Docker / docker-compose 설치됨
    • nginx, next.js 모두 Docker로 올릴 예정
    • GitHub 저장소 있음

     

    1. 서버(Vultr)에서 "딱 한 번" 해야 할 것들

    이건 GitHub Actions가 서버에 접속해서 배포할 수 있게 만드는 준비

    1-1. 서버에 배포 디렉토리 생성

    $ mkdir -p /app
    $ cd /app

    1-2. 서버에 GitHub Actions용 SSH Key 생성

    # 전부 Enter
    $ ssh-keygen -t ed25519 -C "github-actions"
    
    # GitHub Actions 공개키
    $ cat ~/.ssh/id_ed25519.pub
    
    # GitHub Actions 비공개키(GitHub에 설정해야함)
    $ cat ~/.ssh/id_ed25519

    1-3. Vultr 서버에 "GitHub Actions 공개키" 추가

    # GitHub Actions 공개키 확인
    cat ~/.ssh/id_ed25519.pub
    
    # Vultr서버에서 생성한 GitHub Action 공개키 추가
    $ vi ~/.ssh/authorized_keys
    
    
    # authorized_keys에 추가하고 나면 아래처럼 2개의 공개키가 있어야함
    
    # Mac에서 Vultr에 접속하기 위한 공개키
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... your-mac-key
    
    # GitHub Actions가 Vultr에 접속하기 위한 공개키
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... github-actions-key

     

    2. GitHub 설정

    자동 배포의 80%는 여기

    2-1. GitHub Secrets 설정

    GitHub 저장소에서

    Settings → Secrets and variables → Actions → Repository secrets -> [New repository secret]

    아래 4개 추가 (필수 Repository secrets)

    • VULTR_HOST: 서버 IP
    • VULTR_USERNAME: root
    • VULTR_SSH_KEY: id_ed25519 개인키 전체 내용
    # 서버에서 cat ~/.ssh/id_ed25519
    
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----
    • GH_PAT: GitHub Personal Access Token (아래 과정에서 생성된 ghp 토큰)
    계정
    → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token (classic)
    
    # Note
      ghcr-deploy (아무 이름이나 OK)
      
    # Expiration
      30 days
      # 30 days (처음에 추천, 30일 이후에 새 토큰 생성하고 GH_PAT Secret값 교체해줘야함)
      # 또는
      # No expiration (운영용, 영구 수동으로 삭제해야함)
      
    # Scopes(이게 핵심)
      write:packages
      read:packages
    
    → Generate token

    ghp 생성

     

    2-2. GH_PAT 생성 참고

    Docker 이미지를 GitHub Container Registry(GHCR)에 push 하기 위함

    GitHub → Settings → Developer settings
    → Personal access tokens → Tokens (classic)
    • 권한
      1. read:packages
      2. (push까지 할 거면 write:packageseh 체크)

    생성 후 -> 토큰 값 복사 -> GH_PAT에 저장

     

    3. 레포 구조

    .
    ├─ docker-compose.yml
    ├─ nginx/
    │   └─ default.conf
    ├─ nextjs/
    │   ├─ Dockerfile
    │   └─ ...
    └─ .github/
        └─ workflows/
            └─ deploy.yml

     

    4. docker-compose.xml (서버에서 돌릴 최종 형태)

    version: "3.8"
    
    services:
      nginx:
        image: nginx:alpine
        ports:
          - "80:80"
        volumes:
          - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
        depends_on:
          - nextjs
        restart: always
    
      nextjs:
        image: ghcr.io/OWNER/REPO:latest
        restart: always

    OWNER/REPO는 GitHub레포명으로 변경

     

    5. GitHub Actions (자동 배포 핵심)

    • .github/workflows/deploy.yml
    name: Deploy Next.js
    
    on:
      push:
        branches:
          - master
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
    
        steps:
          - uses: actions/checkout@v4
    
          - name: Login to GHCR
            run: echo ${{ secrets.GH_PAT }} | docker login ghcr.io -u USERNAME --password-stdin
    
          - name: Build & Push Image
            run: |
              docker build -t ghcr.io/OWNER/REPO:latest ./nextjs
              docker push ghcr.io/OWNER/REPO:latest
    
          - name: Deploy to Vultr
            uses: appleboy/ssh-action@v1.0.0
            with:
              host: ${{ secrets.VULTR_HOST }}
              username: ${{ secrets.VULTR_USERNAME }}
              key: ${{ secrets.VULTR_SSH_KEY }}
              script: |
                cd /app
                docker pull ghcr.io/OWNER/REPO:latest
                docker compose down
                docker compose up -d

     

    6. 서버에 최초 1번만 할 작업

    6.1. Github에 SSH keys 등록

    • 서버 공개키 복사
    # 서버 접속 및 서버 공개키 복사
    $ cat ~/.ssh/id_ed25519.pub
      ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... vultr-server
    • GitHub에 공개키 등록
    GitHub (우측 상단 프로필)
    → Settings
    → SSH and GPG keys
    → New SSH key

    6.2. 서버에서 clone 및 서버 동

    $ cd /app
    $ git clone https://github.com/OWNER/REPO.git .
    $ docker compose up -d
    1. master 브랜치에 push / merge
    2. GitHub Actions 실행
    3. Docker 이미지 빌드 -> GHCR push
    4. Vultr 서버 접속
    5. docker compose up -d
    6. 배포 완료

     

    핵심 정리

    • 서버 설정 딱 1번
    • GitHub Secrets 딱 1번
    • 이후엔 merge = 배포

     

    참고)

    • docker compose up -d 안될때
    docker compose up -d
    unknown shorthand flag: 'd' in -d
    
    Usage:  docker [OPTIONS] COMMAND [ARG...]
    
    Run 'docker --help' for more information
    • docker compose로 통일하려면
    # STEP 1. 필수 패키지 설치
    $ sudo apt update
    $ sudo apt install -y ca-certificates curl gnupg
    
    # STEP 2. Docker 공식 GPG 키 등록
    $ sudo mkdir -p /etc/apt/keyrings
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
      | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    $ sudo chmod a+r /etc/apt/keyrings/docker.gpg
    
    # STEP 3. Docker 공식 APT 저장소 추가
    $ echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" \
      | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    # STEP 4. 패키지 목록 갱신
    $ sudo apt update
    
    # STEP 5. docker-compose-plugin 설치
    $ sudo apt install -y docker-compose-plugin
    
    
    # (선택) docker-compose(v1) 완전 제거
    $ sudo apt remove -y docker-compose
    $ sudo rm -f /usr/bin/docker-compose

     

    최종 확인

    • GitHub Actions

    푸시하면 Git Actions의 workflow가 실행된다.

    • Deploy 에러 확인

    deploy 과정을 확인 할 수 있다.

    • 필자는 authorized_keys에 GitHub Actions에서 Vultr에 접속하기 위한 공개키가 추가되어 있지 않아서 추가하고 빌드에 성공하였다.

    성공

     

    • 소스 정리하고 다시 테스트 (아래처럼 하고 push해서 배포되는지 확인)
    # 기존 컨테이너 중지
    $ docker compose down
    
    # 기존 git clone 파일들 삭제 (nginx 설정 등이 새로 복사됨)
    $ rm -rf /app/*

    이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

    댓글

Designed by Tistory.