Skip to content

[ON-96] EC2 환경 Docker 세팅#20

Open
Thedduro wants to merge 1 commit intodevelopfrom
Feat/ON-96_DockerSetUp
Open

[ON-96] EC2 환경 Docker 세팅#20
Thedduro wants to merge 1 commit intodevelopfrom
Feat/ON-96_DockerSetUp

Conversation

@Thedduro
Copy link
Member

@Thedduro Thedduro commented Feb 13, 2026

📌 개요

EC2 배포를 위한 Spring Boot Dockerfile 추가

✨ 주요 변경 사항

  • Gradle 멀티스테이지 빌드 기반 Dockerfile 추가 (빌드: gradle:8.5-jdk17, 런타임: eclipse-temurin:17-jre)

🔍 관련 이슈

🙏 To Reviewers

  • 멀티스테이지 빌드로 최종 이미지에는 JRE + JAR만 포함됩니다.
  • server/ 디렉토리 기준으로 소스를 복사하는 구조이니 프로젝트 경로 확인 부탁드립니다.

Summary by CodeRabbit

릴리스 노트

  • Chores
    • Spring Boot 애플리케이션의 Docker 컨테이너 지원 추가
    • 다단계 빌드 프로세스를 통한 자동 생성 및 실행 환경 구성
    • 포트 8080을 통한 애플리케이션 접근 지원

@Thedduro Thedduro requested a review from Byunjihun February 13, 2026 08:06
@Thedduro Thedduro self-assigned this Feb 13, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 13, 2026

Walkthrough

새로운 Dockerfile이 추가되어 Spring Boot 애플리케이션을 빌드하고 실행합니다. 빌더 단계에서 Gradle 이미지를 사용하여 Gradle 설정 및 소스 코드를 복사하고, 빌드한 JAR을 생성합니다. 런타임 단계에서는 JRE 이미지를 기반으로 빌더에서 생성된 JAR을 복사하고 포트 8080을 노출하며 실행 진입점을 정의합니다.

Changes

Cohort / File(s) Summary
멀티 스테이지 빌드 설정
Dockerfile
Gradle을 사용한 빌드 단계와 JRE 기반 런타임 단계를 포함하는 Spring Boot 애플리케이션 컨테이너 이미지 빌드 구성

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 도커 파일이 추가되니,
이제 애플리케이션 타운으로 우르르르르르~
빌더와 런타임이 손잡고,
포트 8080을 활짝 열고,
한번의 명령으로 쌩하고 날아간다! ✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목 'ON-96 EC2 환경 Docker 세팅'은 변경사항의 주요 내용과 일치합니다. Dockerfile 추가를 통한 Docker 환경 설정이 핵심 변경사항이며, 제목에서 이를 명확하게 반영하고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into develop

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch Feat/ON-96_DockerSetUp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@Dockerfile`:
- Around line 20-29: 런타임 Dockerfile이 현재 root로 컨테이너를 실행하므로 권한 상승 위험이 있으니 non-root
사용자로 실행되도록 수정하세요: 런타임 stage에 그룹/사용자(예: appuser, uid 1000)를 생성하고 WORKDIR /app 및
복사된 app.jar에 대해 소유권을 해당 사용자로 chown 한 뒤 ENTRYPOINT 실행 전에 USER appuser를 설정해 컨테이너가
root가 아닌 appuser로 시작되도록 하십시오 (참고 대상 토큰: WORKDIR, COPY --from=builder ...,
app.jar, ENTRYPOINT, USER).
- Line 25: The Dockerfile COPY uses a wildcard that matches multiple JARs (COPY
--from=builder /app/build/libs/*.jar app.jar) causing the build to fail; fix by
either disabling the plain jar in the Gradle build (add tasks.named('jar') {
enabled = false } to server/build.gradle so only the bootJar remains) or by
making the Dockerfile copy a single, explicit artifact (replace the wildcard
with the exact boot JAR filename or a pattern that matches only the boot JAR).
Ensure the Docker COPY references the single artifact produced by bootJar to
avoid multiple-match errors.
🧹 Nitpick comments (1)
Dockerfile (1)

7-17: Gradle 의존성 캐싱 레이어 누락

현재 구조에서는 소스 코드가 변경될 때마다 의존성을 매번 다시 다운로드합니다. Gradle 설정 파일 복사 후 의존성을 먼저 다운로드하는 레이어를 추가하면 빌드 속도를 크게 개선할 수 있습니다.

♻️ 의존성 캐싱 레이어 추가 제안
 # Copy gradle files
 COPY server/build.gradle server/settings.gradle server/gradlew ./
 COPY server/gradle ./gradle
 
+# Make gradlew executable
+RUN chmod +x ./gradlew
+
+# Pre-download dependencies (cached unless build.gradle changes)
+RUN ./gradlew dependencies --no-daemon
+
 # Copy source code
 COPY server/src ./src
 
-# Make gradlew executable
-RUN chmod +x ./gradlew
-
 # Build the application
 RUN ./gradlew bootJar --no-daemon

Comment on lines +20 to +29
FROM eclipse-temurin:17-jre

WORKDIR /app

# Copy the built jar from builder stage
COPY --from=builder /app/build/libs/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

컨테이너가 root 사용자로 실행됩니다

런타임 스테이지에서 non-root 사용자를 지정하지 않아 컨테이너가 root로 실행됩니다. 컨테이너 탈출 취약점 발생 시 호스트에 대한 권한 상승 위험이 있습니다.

🔒 non-root 사용자 추가 제안
 FROM eclipse-temurin:17-jre
 
 WORKDIR /app
 
+RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
+
 # Copy the built jar from builder stage
 COPY --from=builder /app/build/libs/*.jar app.jar
 
+USER appuser
+
 EXPOSE 8080
 
 ENTRYPOINT ["java", "-jar", "app.jar"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM eclipse-temurin:17-jre
WORKDIR /app
# Copy the built jar from builder stage
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
FROM eclipse-temurin:17-jre
WORKDIR /app
RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
# Copy the built jar from builder stage
COPY --from=builder /app/build/libs/*.jar app.jar
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
🤖 Prompt for AI Agents
In `@Dockerfile` around lines 20 - 29, 런타임 Dockerfile이 현재 root로 컨테이너를 실행하므로 권한 상승
위험이 있으니 non-root 사용자로 실행되도록 수정하세요: 런타임 stage에 그룹/사용자(예: appuser, uid 1000)를 생성하고
WORKDIR /app 및 복사된 app.jar에 대해 소유권을 해당 사용자로 chown 한 뒤 ENTRYPOINT 실행 전에 USER
appuser를 설정해 컨테이너가 root가 아닌 appuser로 시작되도록 하십시오 (참고 대상 토큰: WORKDIR, COPY
--from=builder ..., app.jar, ENTRYPOINT, USER).

WORKDIR /app

# Copy the built jar from builder stage
COPY --from=builder /app/build/libs/*.jar app.jar
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and display build.gradle to check for plain JAR configuration
fd build.gradle -type f --exec cat {}

Repository: OneBiteArticle/oba_backend

Length of output: 240


🏁 Script executed:

#!/bin/bash
# Find and display Dockerfile to verify the COPY command on line 25
fd Dockerfile -type f --exec cat -n {}

Repository: OneBiteArticle/oba_backend

Length of output: 240


🏁 Script executed:

#!/bin/bash
# Check for Spring Boot gradle plugin configuration and JAR settings
fd -e gradle -type f --exec grep -l "bootJar\|plain.*jar\|jar.*enabled" {} \;

Repository: OneBiteArticle/oba_backend

Length of output: 240


🏁 Script executed:

#!/bin/bash
# Find build.gradle files
fd build.gradle

Repository: OneBiteArticle/oba_backend

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Find Dockerfile
fd Dockerfile

Repository: OneBiteArticle/oba_backend

Length of output: 80


🏁 Script executed:

#!/bin/bash
# Display Dockerfile with line numbers
cat -n Dockerfile

Repository: OneBiteArticle/oba_backend

Length of output: 802


🏁 Script executed:

#!/bin/bash
# Display server/build.gradle to check jar configuration
cat -n server/build.gradle

Repository: OneBiteArticle/oba_backend

Length of output: 2037


🌐 Web query:

Spring Boot gradle plugin plain jar generation default behavior

💡 Result:

  • Spring Boot Gradle plugin (Spring Boot ≤ 2.4.x): when bootJar is configured, the plugin disables the standard jar task by default, so a “plain” jar is not produced unless you re-enable jar. [1]
  • Spring Boot Gradle plugin (Spring Boot ≥ 2.5.0 and still in Spring Boot 3.x): the plugin leaves jar enabled, but configures it as a separate “plain” artifact by giving it the default classifier plain (so you typically get app-plain.jar alongside the executable bootJar). You can disable the plain jar by disabling jar, or change classifiers if you don’t want the plain suffix. [2][3]

Common knobs

  • Don’t build the plain jar: tasks.named("jar") { enabled = false } [3]
  • Don’t use the plain classifier (so the plain jar is just app.jar): set archiveClassifier = "" on jar (and optionally move a classifier to bootJar). [2][3]

Sources: Spring Boot Gradle Plugin reference (2.4) for “jar disabled by default”; Spring Boot Gradle Plugin reference (2.5 / 3.x) for “plain archive” behavior and how to disable or reclassify. [1][2][3]


🌐 Web query:

Docker COPY command multiple files wildcard pattern behavior

💡 Result:

  • Wildcards are expanded by the Docker builder (not your shell), and each <src> in COPY <src>... <dest> may include wildcards matched using Go’s filepath.Match rules (e.g. *, ?, []). This is relative to the build context. [1]
  • If a wildcard (or multiple explicit sources) resolves to more than one source, then <dest> must be a directory and must end with / (e.g. COPY *.png /dest/). [1]
  • For a single file source, if <dest> ends with /, Docker treats it as a directory and writes the file as <dest>/<basename(src)> (i.e., it uses the source file’s basename). [1]
  • For a directory source, Docker copies the directory contents (not the directory entry itself). Subdirectories are copied/merged into the destination. [1]
  • Builder implementations can differ (e.g., Docker vs Buildah/other tools) in edge cases like enforcing the “dest must end with /” rule, so the same Dockerfile can behave differently across builders. [2]
  • If you need to preserve parent directories when copying matched files, BuildKit’s newer Dockerfile features support COPY --parents ..., including examples using wildcards (and even ** in that mode). [3]

Sources:
[1] Dockerfile reference (COPY / pattern matching / multi-source dest rules) — Docker Docs (docs.docker.com)
[2] Buildah issue discussing divergence from Docker’s trailing-slash rule for multi-source COPY (github.com)
[3] Docker blog: Dockerfile v1.7.0 capabilities (COPY --parents, wildcards, **) (docker.com)

Citations:


Docker 빌드 실패: 와일드카드로 인한 다중 JAR 매칭 문제

Spring Boot 3.5.4에서는 기본적으로 bootJar 외에도 *-plain.jar 파일을 생성합니다. COPY --from=builder /app/build/libs/*.jar app.jar 명령은 두 개의 JAR 파일과 매칭되는데, 목적지(app.jar)가 디렉토리가 아니므로 Docker 빌드가 실패합니다.

server/build.gradle에 다음을 추가하여 plain JAR 생성을 비활성화하거나, Dockerfile의 경로를 더 구체적으로 지정하세요:

♻️ build.gradle에 plain JAR 비활성화 추가
tasks.named('jar') {
    enabled = false
}
🤖 Prompt for AI Agents
In `@Dockerfile` at line 25, The Dockerfile COPY uses a wildcard that matches
multiple JARs (COPY --from=builder /app/build/libs/*.jar app.jar) causing the
build to fail; fix by either disabling the plain jar in the Gradle build (add
tasks.named('jar') { enabled = false } to server/build.gradle so only the
bootJar remains) or by making the Dockerfile copy a single, explicit artifact
(replace the wildcard with the exact boot JAR filename or a pattern that matches
only the boot JAR). Ensure the Docker COPY references the single artifact
produced by bootJar to avoid multiple-match errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant