From 4a907b175c84d7016c1af4f8b0cfc0cce875c0ae Mon Sep 17 00:00:00 2001 From: meraki6512 Date: Thu, 28 Aug 2025 17:28:29 +0900 Subject: [PATCH] =?UTF-8?q?[#32]=20chore:=20CI=20-=20Docker=20=EB=B0=8F=20?= =?UTF-8?q?Docker=20Compose=20=ED=99=98=EA=B2=BD=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Spring Boot, MySQL 기반 서비스의 Dockerfile 작성 및 멀티 스테이지 빌드 적용 - docker-compose.yml 작성하여 MySQL과 앱 컨테이너 연동 구성 - .env 파일로 DB 접속 정보 분리 및 환경 변수 사용 적용 - Git 캐시에서 .env 제거 및 .gitignore에 등록하여 민감 정보 노출 방지 - 인메모리 DB 테스트 프로파일 적용으로 빌드 시 테스트 오류 방지 - CI 파이프라인과 로컬 개발 환경에서 동일한 도커 환경 구축 지원 --- .github/workflows/ci-docker.yml | 26 +++++++++++++++ .github/workflows/{ci.yml => ci-yml.txt} | 0 .gitignore | 4 +++ Dockerfile | 28 ++++++++++++++++ docker-compose.yml | 42 ++++++++++++++++++++++++ 5 files changed, 100 insertions(+) create mode 100644 .github/workflows/ci-docker.yml rename .github/workflows/{ci.yml => ci-yml.txt} (100%) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml new file mode 100644 index 0000000..028c965 --- /dev/null +++ b/.github/workflows/ci-docker.yml @@ -0,0 +1,26 @@ +name: CI Docker Build + +on: + push: + branches: [ "dev" ] + pull_request: + branches: [ "dev" ] + +jobs: + build-and-test-docker: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build Docker image + run: | + docker build -t issue-dive-app . + + - name: Run tests inside Docker container + run: | + docker run --rm issue-dive-app ./gradlew test diff --git a/.github/workflows/ci.yml b/.github/workflows/ci-yml.txt similarity index 100% rename from .github/workflows/ci.yml rename to .github/workflows/ci-yml.txt diff --git a/.gitignore b/.gitignore index 5f96120..1f30306 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,7 @@ out/ # Application Properties application.properties application-test.properties + +.env +.java-version +logs/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f4069d5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +# 1. 빌드 스테이지 +FROM gradle:8.14.3-jdk17 AS builder + +WORKDIR /app + +# Gradle 캐시 최적화를 위해 build.gradle과 settings.gradle 먼저 복사 +COPY build.gradle settings.gradle gradlew ./ +COPY gradle ./gradle + +# 의존성 다운로드 +RUN ./gradlew --no-daemon dependencies + +# 나머지 소스 복사 및 빌드 +COPY src ./src +# RUN ./gradlew build --no-daemon -Dspring.profiles.active=test +RUN ./gradlew assemble --no-daemon -Dspring.profiles.active=test + + +# 2. 실행 스테이지 +FROM openjdk:17-jdk-slim + +WORKDIR /app + +# 빌드 산출물을 복사 +COPY --from=builder /app/build/libs/*.jar app.jar + +# 컨테이너 실행 시 +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1b44657 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,42 @@ +version: '3.8' + +services: + mysql: + image: mysql:8 + container_name: issueDive-mysql + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: issue_dive + # 일반 사용자 추가하지 않거나 별도의 사용자명으로 변경 + # 예를 들어 USER는 issueuser 등으로 변경 가능 + # MYSQL_USER: issueuser + # MYSQL_PASSWORD: user_password + ports: + - "3306:3306" + volumes: + - mysql-data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + + app: + build: . + container_name: issueDive-app + depends_on: + mysql: + condition: service_healthy + environment: + SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL} + SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME} + SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD} + ports: + - "8080:8080" + command: ./gradlew bootRun +# volumes: +# - ./:/app + tty: true + +volumes: + mysql-data: