✅ 워크 플로우

  1. main 브랜치에 merge → Github Actions 실행
  2. CI 수행
  3. Code Deploy 번들 생성
  4. S3에 업로드

✅ CI / CD 워크플로우 예시

  .github/workflows/ci-build-push.yml

  name: ci-build-push

  on:
    push:
      branches: [ "main" ]

  env:
    REGISTRY: dockerhub
    IMAGE_NAME: myapp

  jobs:
    build_push:
      runs-on: ubuntu-latest
      steps:
        - uses: actions/checkout@v4

        - name: Build Docker image
          run: |
            docker build -t $IMAGE_NAME:${{ github.sha }} .

        - name: Login to Docker Hub
          run: |
            echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin

        - name: Tag & Push
          run: |
            docker tag $IMAGE_NAME:${{ github.sha }} ${{ secrets.DOCKERHUB_USERNAME }}/$IMAGE_NAME:${{ github.sha }}
            docker tag $IMAGE_NAME:${{ github.sha }} ${{ secrets.DOCKERHUB_USERNAME }}/$IMAGE_NAME:latest
            docker push ${{ secrets.DOCKERHUB_USERNAME }}/$IMAGE_NAME:${{ github.sha }}
            docker push ${{ secrets.DOCKERHUB_USERNAME }}/$IMAGE_NAME:latest

  ———

  .github/workflows/cd-deploy.yml

  name: cd-deploy

  on:
    workflow_run:
      workflows: [ "ci-build-push" ]
      types: [ completed ]

  env:
    APP_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/myapp:latest

  jobs:
    deploy_app:
      runs-on: ubuntu-latest
      steps:
        - name: Deploy Spring Boot
          uses: appleboy/ssh-action@v1.0.3
          with:
            host: ${{ secrets.EC2_APP_HOST }}
            username: ${{ secrets.EC2_SSH_USER }}
            key: ${{ secrets.EC2_SSH_KEY }}
            script: |
              echo "${{ secrets.APP_ENV_FILE }}" > /tmp/app.env
              docker pull $APP_IMAGE
              docker rm -f spring-app || true
              docker run -d --name spring-app \\
                --env-file /tmp/app.env \\
                -p 8080:8080 \\
                $APP_IMAGE

    deploy_mysql:
      runs-on: ubuntu-latest
      steps:
        - name: Deploy MySQL
          uses: appleboy/ssh-action@v1.0.3
          with:
            host: ${{ secrets.EC2_DB_HOST }}
            username: ${{ secrets.EC2_SSH_USER }}
            key: ${{ secrets.EC2_SSH_KEY }}
            script: |
              echo "${{ secrets.MYSQL_ENV_FILE }}" > /tmp/mysql.env
              docker pull mysql:8.0
              docker rm -f mysql || true
              docker run -d --name mysql \\
                --env-file /tmp/mysql.env \\
                -p 3306:3306 \\
                -v /data/mysql:/var/lib/mysql \\
                mysql:8.0

    deploy_redis:
      runs-on: ubuntu-latest
      steps:
        - name: Deploy Redis
          uses: appleboy/ssh-action@v1.0.3
          with:
            host: ${{ secrets.EC2_REDIS_HOST }}
            username: ${{ secrets.EC2_SSH_USER }}
            key: ${{ secrets.EC2_SSH_KEY }}
            script: |
              echo "${{ secrets.REDIS_ENV_FILE }}" > /tmp/redis.env
              docker pull redis:7
              docker rm -f redis || true
              docker run -d --name redis \\
                --env-file /tmp/redis.env \\
                -p 6379:6379 \\
                redis:7

  ———

  필수 GitHub Secrets

  - DOCKERHUB_USERNAME
  - DOCKERHUB_TOKEN
  - EC2_APP_HOST, EC2_DB_HOST, EC2_REDIS_HOST
  - EC2_SSH_USER, EC2_SSH_KEY
  - APP_ENV_FILE, MYSQL_ENV_FILE, REDIS_ENV_FILE