Skip to content

Comments

infra: prod cd pipeline 구축#7

Merged
dev-ant merged 6 commits intodevfrom
infra/prod-cd-pipeline
Jan 26, 2026
Merged

infra: prod cd pipeline 구축#7
dev-ant merged 6 commits intodevfrom
infra/prod-cd-pipeline

Conversation

@dev-ant
Copy link
Contributor

@dev-ant dev-ant commented Jan 24, 2026

📋 상세 설명

@dev-ant dev-ant requested a review from Copilot January 24, 2026 04:44
@dev-ant dev-ant self-assigned this Jan 24, 2026
@dev-ant dev-ant added the 🏗️infrastructure 인프라 구조 설정 label Jan 24, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

운영(prod) 환경 CD 파이프라인을 구축하고, 환경별(local/dev/prod) Docker Compose 및 환경변수 샘플을 정리하는 PR입니다.

Changes:

  • prod/dev/local 환경별 docker-compose 파일을 분리·정비하고 리소스/JVM/헬스체크 설정을 구체화
  • GitHub Actions 기반 배포 워크플로우(prod/dev) 추가·수정
  • .env.{local,dev,prod}.sample 추가 및 Dockerfile 단순화

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
docker-compose-prod.yml 운영 프로필용 compose 추가(이미지 pull, 리소스/헬스체크/autoheal 설정)
docker-compose-local.yml 로컬 compose 구조/변수/로그/헬스체크 설정 정리 및 네이밍 변경
docker-compose-dev.yml 개발 서버용 compose 신규 추가
docker-compose-dev.yaml 기존 dev compose 파일 삭제
Dockerfile 멀티스테이지 제거 후 “외부에서 빌드된 jar COPY” 방식으로 변경
.github/workflows/push-cd-prod.yml prod CI/CD 워크플로우 신규 추가(이미지 빌드/푸시, SSH 배포, 헬스체크)
.github/workflows/push-cd-dev.yml dev 배포 트리거를 PR→push로 변경
.env.prod.sample 운영 환경 샘플 env 추가
.env.local.sample 로컬 환경 샘플 env 추가
.env.dev.sample 개발 환경 샘플 env 추가

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to 13
# ========================================
# Stage 1: Build
# ========================================
FROM eclipse-temurin:21-jdk-alpine AS builder

# Stage 1: Build Stage
FROM gradle:8.5-jdk21 AS builder

# 작업 디렉토리 설정
WORKDIR /app

# Gradle 의존성 다운로드를 위한 파일만 먼저 복사 (레이어 캐싱 최적화)
COPY gradle gradle
# Gradle wrapper 및 설정 파일 먼저 복사 (의존성 캐싱)
COPY gradlew .
COPY gradle gradle
COPY build.gradle.kts .
COPY settings.gradle.kts .

Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

런타임 컨테이너가 기본 root 사용자로 동작합니다(기존 Dockerfile에서는 non-root로 전환). 운영 환경에서는 권한 상승/컨테이너 탈출 리스크를 줄이기 위해 non-root 사용자 생성 후 USER로 전환하고, 필요한 디렉터리 권한만 부여하는 방식으로 되돌리는 것이 좋습니다.

Copilot uses AI. Check for mistakes.
Comment on lines 3 to +5
on:
pull_request:
branches: [ dev, main ]
types: [ opened, synchronize, reopened ]
push:
branches: [ dev ] # Only main branch, 서비스 시작 후 dev 제거
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

트리거를 push로 변경하면서, 이 워크플로우가 실제로 서버에 배포까지 수행하게 됩니다. 그런데 워크플로우 본문에서는 여전히 docker-compose-dev.yaml을 서버로 복사/실행하도록 되어 있어(현재 PR에서 해당 파일이 삭제됨) 배포 단계가 실패합니다. docker-compose-dev.yml로 참조를 변경하거나 파일명을 원복해야 합니다.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +16
devnogi-gateway-dev:
build:
context: .
dockerfile: Dockerfile
image: ${DOCKER_USERNAME}/${DOCKER_REPO}:${DOCKER_IMAGE_TAG:-latest}
container_name: devnogi-gateway-app-dev
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dev compose에서만 서비스 키가 devnogi-gateway-dev로 되어 있고(local/prod는 spring-app) 동일한 애플리케이션임에도 이름이 달라 운영/스크립트/문서에서 혼동이 생길 수 있습니다. 특별한 이유가 없다면 세 환경에서 동일한 서비스 키로 통일하는 편이 유지보수에 유리합니다.

Suggested change
devnogi-gateway-dev:
build:
context: .
dockerfile: Dockerfile
image: ${DOCKER_USERNAME}/${DOCKER_REPO}:${DOCKER_IMAGE_TAG:-latest}
container_name: devnogi-gateway-app-dev
spring-app:
build:
context: .
dockerfile: Dockerfile
image: ${DOCKER_USERNAME}/${DOCKER_REPO}:${DOCKER_IMAGE_TAG:-latest}
container_name: spring-app

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +79
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest
${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:prod
${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:prod-${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BUILDKIT_INLINE_CACHE=1
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 Dockerfile이 build/libs/*.jarCOPY하도록 변경되었는데, 이 워크플로우에서는 Gradle로 bootJar(또는 build)를 실행하는 단계가 없어 Docker 이미지 빌드가 실패합니다. Docker build 전에 JAR을 생성하는 step을 추가하거나, Dockerfile을 다시 멀티스테이지(Gradle 빌드 포함)로 되돌려 CI에서 소스만으로 빌드 가능하게 해주세요.

Copilot uses AI. Check for mistakes.
Comment on lines 3 to 6
on:
pull_request:
branches: [ dev, main ]
types: [ opened, synchronize, reopened ] # 테스트용
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프로덕션 배포 워크플로우가 pull_request 이벤트( dev/main 대상 )에서 실행되도록 되어 있어 PR이 열릴 때마다 프로덕션 서버에 배포를 시도하게 됩니다. 이는 운영 안정성/보안 측면에서 위험하고, fork PR에서는 secrets가 제공되지 않아 동작 자체도 실패할 가능성이 큽니다. push(예: main) 또는 workflow_dispatch + GitHub Environments 승인(필요 시)로 트리거를 제한하는 쪽으로 조정이 필요합니다.

Copilot uses AI. Check for mistakes.
ssh -i ~/.ssh/my-key.pem -p ${{ secrets.PROD_SERVER_PORT }} ${{ secrets.PROD_SERVER_USER }}@${{ secrets.PROD_SERVER_HOST }} << 'EOF'
cd /opt/devnogi-gateway

# Write .env.prod content to .env
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석이 실제 동작과 불일치합니다. 여기서는 .env가 아니라 .env.prod 파일을 쓰고 있으니(다음 줄), 주석을 .env.prod로 맞춰 혼동을 줄여주세요.

Suggested change
# Write .env.prod content to .env
# Write production env content to .env.prod

Copilot uses AI. Check for mistakes.
Comment on lines 9 to +10
COPY gradlew .
COPY gradle gradle
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 Dockerfile은 build/libs/*.jar가 빌드 컨텍스트에 이미 존재한다고 가정합니다. 하지만 docker compose up --build(local/dev)나 현재 prod 워크플로우처럼 Gradle 빌드를 선행하지 않으면 COPY build/libs/*.jar에서 실패합니다. (1) 멀티스테이지로 Gradle 빌드를 포함하거나, (2) compose/CI에서 ./gradlew bootJar를 반드시 실행하도록 사용법/워크플로우를 함께 맞춰주세요.

Copilot uses AI. Check for mistakes.
COPY gradle gradle
COPY build.gradle.kts .
COPY settings.gradle.kts .

Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using sh -c with java ${JAVA_OPTS} -jar /app/app.jar makes the container entrypoint vulnerable to shell injection via the JAVA_OPTS environment variable. If any value that ends up in JAVA_OPTS contains shell metacharacters (for example ;, &&, or backticks) and an attacker can influence those environment variables (such as via a .env file or orchestration config), they can execute arbitrary shell commands in the container before the JVM starts. Avoid routing this through a shell; instead invoke java directly with its arguments or strictly validate and whitelist the characters allowed in JAVA_OPTS so only safe JVM options are accepted.

Copilot uses AI. Check for mistakes.
@dev-ant dev-ant merged commit ba5575e into dev Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🏗️infrastructure 인프라 구조 설정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant