본문 바로가기
카테고리 없음

제로부터 DevOps까지 7편 - Docker, GitHub 실전

by 타임 플레그 2025. 5. 29.
반응형

CI/CD로 자동화된 배포 구축하기 - Docker, GitHub Actions 실전

“이제 코드를 Push 하면, 자동으로 서비스가 배포됩니다.”
이제는 배포도 코드처럼 다뤄야 하는 시대. 우리는 이번 편에서 CI/CD 파이프라인을 직접 구성하며, 진짜 개발자다운 자동화 흐름을 만들어 봅니다.


🛠️ 본격 실습 전, 준비할 것들

자동화 배포를 시작하기 전에 다음 준비 작업이 필요합니다:

  1. EC2 인스턴스 생성 및 접속 준비
    • Ubuntu 또는 Amazon Linux 2 인스턴스 실행
    • SSH 접속 가능 여부 확인 (chmod 400 키. pem, ssh -i 키. pem ec2-user@IP)
    • 보안 그룹 설정: 포트 22 (SSH), 80/443 (HTTP), 3000 (Node.js 앱)
  2. GitHub Repository 준비
    • main 브랜치 설정 및 기본 프로젝트 업로드
    • .gitignore, README.md, Dockerfile 포함 확인
  3. GitHub Secrets 설정
    • EC2_HOST: EC2 퍼블릭 IP
    • EC2_KEY:. pem 키 내용 전체 복붙 (비밀값)
    • EC2_USER: 일반적으로 ec2-user 또는 ubuntu
  4. Docker 설치 (EC2 내부)
    • 이후 exit 후 다시 접속하여 docker 명령어 사용 가능 확인
  5. sudo apt update sudo apt install docker.io -y sudo systemctl start docker sudo systemctl enable docker sudo usermod -aG docker $USER
  6. Node.js 및 프로젝트 디렉터리 구성
    • 프로젝트 폴더 /home/ec2-user/app에 clone 및 실행 권장

이 모든 준비가 끝났다면, 이제 자동화 배포의 여정을 본격 시작할 수 있습니다.


🧭 왜 자동화 배포가 필요할까?

지난 편에서는 AWS EC2에 수동으로 접속해 서버를 설정하고 배포를 진행했습니다. 하지만, 이런 방식은 다음과 같은 단점이 있습니다:

  • 수정사항이 생길 때마다 SSH 접속 → pull → restart 반복
  • 사람마다 설정이 달라 재현성 부족
  • 실수로 서버 설정 망가질 수 있음

그래서 등장한 것이 CI/CD입니다.

  • CI(지속적 통합): 코드를 자주 병합하고 자동 테스트/빌드를 수행
  • CD(지속적 배포): 코드를 병합하면 자동으로 배포까지 이어짐

이제 우리는 GitHub에 Push만 해도 배포가 완료되는 자동화 흐름을 만들어봅니다.


🐳 Docker란? 왜 써야 할까?

Docker는 앱과 그 실행 환경을 하나의 컨테이너로 묶어주는 도구입니다.

  • 가상머신: OS까지 통째로 복제 → 무거움
  • 도커 컨테이너: 앱과 라이브러리만 격리 → 가벼움

장점:

  • 어디서든 동일한 실행 환경 보장
  • 배포가 일관되고 빠름
  • 서버 설정 문제 발생률 감소

⚙️ Dockerize 실습: 내 Node.js 앱을 컨테이너에 담기

1. Dockerfile 작성

FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

2. 도커 빌드 & 실행

docker build -t my-node-app .
docker run -d -p 3000:3000 my-node-app

이제 브라우저에서 http://localhost:3000에 접속해 앱을 확인해 보세요.


⚡ GitHub Actions로 자동화 시작하기

.github/workflows/deploy.yml 생성:

name: Deploy to EC2
on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

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

    - name: Install dependencies
      run: npm install

    - name: SSH into EC2 & deploy
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USER }}
        key: ${{ secrets.EC2_KEY }}
        script: |
          cd /home/ec2-user/app
          git pull origin main
          docker build -t my-node-app .
          docker stop app || true && docker rm app || true
          docker run -d --name app -p 3000:3000 my-node-app

주의:

  • EC2_HOST, EC2_KEY 등은 GitHub Secrets에 등록해야 보안 유지
  • SSH 연결을 위해 EC2에 .pem 기반 SSH 접근 설정 필요

🧪 실전 트러블슈팅

문제 원인 해결 방법

SSH 연결 실패 키 문제 or IP 허용 안 됨 EC2 보안 그룹 22포트 확인
Docker pull 오류 Dockerfile 위치 이상 .dockerignore 체크 및 경로 확인
Workflow 작동 안 함 YAML 문법 오류 GitHub Actions 로그 확인

📌 실습 정리 & 배포 체크리스트

  • Node.js 앱에 Dockerfile 추가
  • GitHub Actions 설정 완료
  • Push 시 자동 배포 확인
  • EC2 로그 확인 (docker logs)
  • 실패 시 롤백 계획 세움

🧭 회고: 자동화, 진짜 개발자처럼

우리는 지금, 코드를 Push 하고 자동으로 서비스가 갱신되는 구조를 만들었습니다.
단순히 편리함을 넘어서, 이건 팀 개발과 실무의 기반이 되는 핵심 역량입니다.

자동화는 단순한 기술이 아니라 협업, 효율, 안정성을 위한 인프라입니다.


🔮 다음 예고: 도커 컴포즈와 멀티서비스

이제는 하나의 앱이 아니라, DB + API + 프론트 + Nginx를 함께 다루는 멀티 서비스 환경으로 나아갑니다.
이를 위해 우리는 Docker Compose를 배우게 됩니다.


⚙️ 배포는 끝이 아닌, 시작입니다.
다음은 복잡한 서비스를 통합적으로 다루는 도전이 기다립니다.

반응형