프론트/React

[React] 최종: Docker 컨테이너화 및 CI/CD 파이프라인 구축

초코chip 2024. 11. 11. 23:30

최종적으로 작성할 파읻들

 

운영 환경을 위한 도커 파일 작성(Dockerfile)

  1. 빌드 단계(builder)
  2. 배포 단계(Nginx 서버)

./Dockerfile

# 빌드 단계
FROM node:16 AS builder
# 작업 디렉토리 설정
WORKDIR /usr/src/app

# package.json 복사
COPY package.json ./

# 의존성 설치
RUN npm install

# 모든 소스 코드 복사
COPY . .

# production 모드로 빌드
RUN npm run build

# Nginx 서버 단계
FROM nginx:alpine

# 빌드된 정적 파일을 Nginx의 기본 제공 HTML 디렉토리에 복사
COPY --from=builder /usr/src/app/dist /usr/share/nginx/html

# 필요에 따라 Nginx 설정 파일 커스터마이징 적용
COPY nginx.conf /etc/nginx/nginx.conf

 

 

nginx 설정 파일 작성(nginx.conf)

이 Nginx 설정 파일은 정적 파일 제공과 API 프록시 처리를 위한 구성을 포함:

  • 서버 블록
    • listen 80;: Nginx가 80번 포트에서 요청을 수신.
    • root /usr/share/nginx/html;: 정적 파일의 기본 경로 설정.
  • 라우팅 설정
    • location / { try_files $uri /index.html; }: SPA(Single Page Application)를 위한 설정으로, 요청된 파일이 없으면 index.html 반환.
  • API 프록시 설정
    • location /api/ {}: /api/ 경로로 들어오는 요청을 백엔드 서버로 프록시.
    • proxy_pass http://app:8080;: 백엔드 서버 http://app:8080로 요청 전달.

 

./nginx.conf

# 필수 이벤트 블록
events {}

# HTTP 블록
http {
    # MIME 타입 설정 파일 포함
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    server {
        listen 80;

        # 서버 이름 설정
        server_name localhost;

        # 정적 파일의 기본 경로 설정
        root /usr/share/nginx/html;

        # SPA를 위한 기본 라우팅 설정
        location / {
            try_files $uri /index.html;
        }

        # API 요청을 백엔드 서버로 프록시
        location /api/ {
            proxy_pass http://app:8080;
            proxy_http_version 1.1;  # HTTP/1.1 사용
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Connection "keep-alive";  # 연결 유지
            proxy_read_timeout 300;  # 타임아웃을 5분으로 설정
        }
    }
}

 

깃헙 액션 파일 작성(deploy.yml)

.github/workflows/deploy.yml

name: Deploy to EC2

on:
  push:
    branches:
      - main  # main 브랜치에 push될 때 트리거

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2  # 레포지토리 코드를 체크아웃
      
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v1
      
    - name: Log in to Docker Hub
      env:
        DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
        DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
      run: echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin

    - name: Build and push Docker image
      run: |
        docker build -t ${{ secrets.DOCKER_IMAGE_NAME }} .
        docker push ${{ secrets.DOCKER_IMAGE_NAME }}
    
    - name: SSH into EC2 and deploy
      uses: appleboy/ssh-action@v0.1.7
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USER }}
        key: ${{ secrets.EC2_KEY }}
        port: 22
        script: |
          # backend_network가 없으면 생성
          docker network ls | grep backend_network || docker network create backend_network
          
          # 최신 이미지를 pull하고 기존 컨테이너를 중단 및 삭제 후 새로 시작
          docker pull ${{ secrets.DOCKER_IMAGE_NAME }}
          docker stop my-app || true
          docker rm my-app || true
          
          # 프론트엔드 컨테이너를 backend_network에 연결하여 실행
          docker run -d --name my-app --network backend_network -p 80:80 ${{ secrets.DOCKER_IMAGE_NAME }}

 

Github Secrects 설정

GitHub Actions에서 사용하는 민감한 정보나 환경 변수를 저장

 

도커 관련 설정

  • 도커 아이디
  • 도커 패스워드 or 토큰(권장)

AWS EC2 관련 설정

  • {EC2유저}@{EC2주소}
  • EC2 접속 .pem 키