[인프라] 도전! 실전 깃허브 액션

2026. 5. 12. 15:04·CS/인프라

 

https://dev-dx2d2y-log.tistory.com/241

 

[인프라] CI/CD와 깃허브 액션

CI/CD수동배포에서의 업데이트https://dev-dx2d2y-log.tistory.com/240 [인프라] AWS란? (AWS 왕왕기초) + 수동배포AWS개발이 끝났다면 내가 만든 애플리케이션을 사용자들이 사용할 수 있도록 배포를 해야한다.

dev-dx2d2y-log.tistory.com

https://dev-dx2d2y-log.tistory.com/242

 

[인프라] CI/CD 깃허브 액션에 도커컴포즈 적용하기

https://dev-dx2d2y-log.tistory.com/241 [인프라] CI/CD와 깃허브 액션CI/CD수동배포에서의 업데이트https://dev-dx2d2y-log.tistory.com/240 [인프라] AWS란? (AWS 왕왕기초) + 수동배포AWS개발이 끝났다면 내가 만든 애플리

dev-dx2d2y-log.tistory.com

일전에 깃허브 액션과 도커컴포즈에 대해서 다뤘던 적이 있었다. 그런데 실제로 깃허브 액션을 적용시켜보니 저 위의 내용과 다르기도하고, 주의해야할 점도 있어서 수정해보려한다.

 

도커컴포즈를 제외한 토커내용은 기존과 동일하다


CI

CI는 딱히 수정할 게 없다. CI의 중요한 점은 gradlew를 빌드시키면서 테스트코드를 통과하도록 잘 짜기만하면 되는 것 같다.


CD

name: CONX server CD
on:
  workflow_run:
    workflows:
      - "CONX server CI"
    types:
      - completed

jobs:
  deploy:
    if: >
      github.event.workflow_run.conclusion == 'success' &&
      github.event.workflow_run.event == 'push' &&
      github.event.workflow_run.head_branch == 'main'
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.workflow_run.head_sha }}

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582

      - name: Build with Gradle Wrapper
        run: ./gradlew build

      - name: Setting Buildx Docker
        uses: docker/setup-buildx-action@v3

      - name: Login Docker
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          push: true
          platforms: linux/amd64, linux/arm64
          tags: |
            contactconx/conx-server:latest
            contactconx/conx-server:${{ github.event.workflow_run.head_sha }}
      
      - name: Deploy to EC2
        uses: appleboy/ssh-action@v1.0.3
        with:
            host: ${{ secrets.EC2_HOST }}
            username: ubuntu
            key: ${{ secrets.EC2_KEY }}
            script: |
              cd /home/ubuntu/CONX-server
              
              cat > .env << EOF
              IMAGE_TAG=${{ github.event.workflow_run.head_sha }}
              DB_URL=${{ secrets.DB_URL }}
              DB_USERNAME=admin
              DB_PASSWORD=${{ secrets.DB_PASSWORD }}
              SPRING_PROFILES_ACTIVE=prod
              EOF
              
              docker compose pull
              docker compose up -d --force-recreate            
              
              for i in {1..15}; do
                if curl -f http://localhost:80/health/ready; then
                  echo "Health Check passed"
                  break
                fi
                echo "Waiting for Service..."
                sleep 5
              done
  
              curl -f http://localhost:80/health/ready || exit 1
              
              sudo docker image prune -f

환경변수를 사용하는 경우 CD 과정에서 다소 신경써야할 게 있었다.

 

환경변수 다루기와 내가 겪었던 문제점

나는 도커를 사용하기 전 로컬에서 .env 파일에 환경변수를 저장하고, 스프링 애플리케이션이 이를 주입받고 있었다. 당연히 도커 및 AWS를 사용해서도 그 방식을 사용하려했고.

 

version: "3.8"

services:
  app:
    image: contactconx/conx-server:${IMAGE_TAG}
    ports:
      - "80:8080"
    restart: unless-stopped
    env_file:
      - .env

    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8080/health/ready" ]
      interval: 10s
      timeout: 3s
      retries: 5

그래서 도커컴포즈에 env_file 속성을 통해서 어떤 파일에 환경변수를 저장할 지 명시해주었다. .env 파일에는 각종 환경변수들이 들어있었고.

 

      - name: Deploy to EC2
        uses: appleboy/ssh-action@v1.0.3
        with:
            host: ${{ secrets.EC2_HOST }}
            username: ubuntu
            key: ${{ secrets.EC2_KEY }}
            script: |
              
              cat > .env << EOF
              IMAGE_TAG=${{ github.event.workflow_run.head_sha }}
              DB_URL=${{ secrets.DB_URL }}
              DB_USERNAME=admin
              DB_PASSWORD=${{ secrets.DB_PASSWORD }}
              SPRING_PROFILES_ACTIVE=prod
              EOF
              
        ...

그런데 CD 과정에서 .env 파일에 cat 명령어를 사용했고, 이는 기존에 저장된 .env 파일과 겹치는 문제가 발생했다.

 

디버깅이 어렵다

우선 설정이 두 개다 보니까 가끔 두 값이 다른 경우가 있었다.

테스트용도로 yaml 파일을 application-prod.yaml 파일과 application-test.yaml 파일 두 개로 나눠놨는데, application.yaml 파일에서 spring-profiles-active 속성을 이용해 어느 yaml 파일을 사용할지 정해야했다.

 

server:
  address: 0.0.0.0

spring:
  application:
    name: conx-server

  profiles:
    active: ${SPRING_PROFILES_ACTIVE}

그리고 이 값을 외부에서 환경변수로 받아왔고.

하지만 이 환경변수가 깃허브 CD 과정에서 전해주는 값과, EC2 인스턴스 저장된 .env 파일의 값이 다른 경우가 있었다. 그러면 명령어를 찍어보지 않는 이상 어떤 환경변수가 사용되는지 알 길이 없다.

 

환경변수 관리가 어렵다

CD 과정에서 전해지는 환경변수의 값을 수정하려면 CD.yaml 파일을 수정한 뒤에 다시 깃허브로 push를 하거나 PR을 보내면 된다. 하지만 EC2 로컬에서 .env 파일을 저장해 사용하는 경우, 환경변수의 값을 수정하려면 직접 .env 파일에 접근해서 수정해야한다. 그리고 EC2 인스턴스와 컴퓨터의 환경이 달라서 터미널에서 우분투 명령어를 입력하며 하나하나 수정해야한다는 것이 단점. 이것 때문에 나는 분명 코드와 파일들을 수정했는데 원인 모를 에러가 끝도없이 나와서 고생 좀 했다.

 

 

 

단점이 꽤 많았던 것 같은데 적어보니 두 개 밖에 없네

그래도 저 두 개 때문에 무한디버깅지옥에 빠졌었다. .env 파일 속성이 꼬이면서 아예 환경변수를 읽어오지 못했던 적도 있었고. 로컬에서 수정했는데 EC2 인스턴스에는 반영이 되지 않아서 혼란스러웠던 적도 있었다.


환경변수를 EC2 로컬에 직접 저장하지 맙시다

        ...

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          push: true
          platforms: linux/amd64, linux/arm64
          tags: |
            contactconx/conx-server:latest
            contactconx/conx-server:${{ github.event.workflow_run.head_sha }}
      
      - name: Deploy to EC2
        uses: appleboy/ssh-action@v1.0.3
        with:
            host: ${{ secrets.EC2_HOST }}
            username: ubuntu
            key: ${{ secrets.EC2_KEY }}
            script: |
              cd /home/ubuntu/CONX-server
              
              cat > .env << EOF
              IMAGE_TAG=${{ github.event.workflow_run.head_sha }}
              DB_URL=${{ secrets.DB_URL }}
              DB_USERNAME=admin
              DB_PASSWORD=${{ secrets.DB_PASSWORD }}
              SPRING_PROFILES_ACTIVE=prod
              EOF
              
              docker compose pull
              docker compose up -d --force-recreate            
              
              for i in {1..15}; do
                if curl -f http://localhost:80/health/ready; then
                  echo "Health Check passed"
                  break
                fi
                echo "Waiting for Service..."
                sleep 5
              done
  
              curl -f http://localhost:80/health/ready || exit 1
              
              sudo docker image prune -f
version: "3.8"

services:
  app:
    image: contactconx/conx-server:${IMAGE_TAG}
    ports:
      - "80:8080"
    restart: unless-stopped
    env_file:
      - .env

    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8080/health/ready" ]
      interval: 10s
      timeout: 3s
      retries: 5

로컬 .env 파일에 직접 접근하지 않고도 환경변수를 관리할 수 있게끔 CD 과정에서 모든 환경변수를 만들고, .env 파일에 덮어씌우고, 스프링에 넘겨야한다. 이를 통해서 오직 한 곳에서만 환경변수를 관리하므로 변수 설정이 꼬일 염려가 없으며, 환경변수를 수정하고 싶다면 깃허브 시크릿이나 CD 파일만 수정하면되므로 디버깅도 간편하다


기타

https://dev-dx2d2y-log.tistory.com/241

 

[인프라] CI/CD와 깃허브 액션

CI/CD수동배포에서의 업데이트https://dev-dx2d2y-log.tistory.com/240 [인프라] AWS란? (AWS 왕왕기초) + 수동배포AWS개발이 끝났다면 내가 만든 애플리케이션을 사용자들이 사용할 수 있도록 배포를 해야한다.

dev-dx2d2y-log.tistory.com

어.. Github Runner (CI/CD 시 CICD 코드가 임시로 실행되는 프로세서)가 CI와 CD에서 다르기 때문에 둘 다 gradlew와 JDK 역시 CD 과정에서 다시 깔아야한다고한다. 저 위의 내용은 잘못된 내용

 

이게 귀찮으면 젠킨스를 사용하면 된다. 깃허브는 Github Runner를 사용하지만 젠킨스는 내가 직접 서버를 띄워서 거기에 JDK고 깔고 도커 업로드도하고 EC2 배포도 하는 형식으로 동작한다. 한 번 배워보고싶단 말이지..

 

https://www.inflearn.com/community/questions/1317453/github-action?srsltid=AfmBOorTZAvs-m8nryZwk17JYJCb893mwJGK-x9V2Z67nJ0BolZ13Wo0

 

github action - 인프런 | 커뮤니티 질문&답변

누구나 함께하는 인프런 커뮤니티. 모르면 묻고, 해답을 찾아보세요.

www.inflearn.com

위 내용을 참고했다.

'CS > 인프라' 카테고리의 다른 글

[인프라] CI/CD 깃허브 액션에 도커컴포즈 적용하기  (0) 2026.05.07
[인프라] CI/CD와 깃허브 액션  (0) 2026.05.07
[인프라] AWS란? (AWS 왕왕기초) + 수동배포  (0) 2026.05.06
[인프라] 도커란? (도커왕왕기초)  (0) 2026.05.06
'CS/인프라' 카테고리의 다른 글
  • [인프라] CI/CD 깃허브 액션에 도커컴포즈 적용하기
  • [인프라] CI/CD와 깃허브 액션
  • [인프라] AWS란? (AWS 왕왕기초) + 수동배포
  • [인프라] 도커란? (도커왕왕기초)
컬러잇
컬러잇
탄천러너지망생
  • 컬러잇
    Color it
    컬러잇
  • 전체
    오늘
    어제
    • 분류 전체보기 (235) N
      • 신년사 (3)
        • 2025년 (2)
        • 2026년 (1)
      • CS (72) N
        • JVM (12)
        • 인프라 (5)
        • 백엔드 (22) N
        • 논리회로 (5)
        • 언어구현 (1)
        • 인공지능 (1)
        • 코드설계 (3)
        • 컴퓨터구조 (9)
        • 데이터베이스 (4)
        • 컴퓨터 네트워크 (10)
      • 언어공부 (65)
        • Java | Kotlin (49)
        • JavaScript | TypeScript (9)
        • C | C++ (6)
      • 개인 프로젝트 (11)
        • [2025] Happy2SendingMails (3)
        • [2026] 골든리포트! (8)
        • [2026] 순수자바로 개발하기 (0)
        • 기타 이것저것 (0)
      • 팀 프로젝트 (29)
        • [2025][GDG]홍대 맛집 아카이빙 프로젝트 (29)
      • 알고리즘 (13)
        • 백준풀이기록 (11)
      • 놀이터 (0)
      • 에러 수정일지 (4)
      • 고찰 (35)
        • CEOS 23기 회고록 (9)
  • 링크

    • 교양있는컬러잇
  • 최근 글

  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.5
컬러잇
[인프라] 도전! 실전 깃허브 액션
상단으로

티스토리툴바