-
Notifications
You must be signed in to change notification settings - Fork 0
[EDMT-454] Docker 엔트리포인트 JAVA_OPTS 설정 개선 #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughENTRYPOINT를 직접 exec 형태의 Java 호출에서 셸 래퍼( Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Operator as Orchestrator/Compose
participant C as Container
participant SH as sh -c
participant J as java (app.jar)
Operator->>C: 컨테이너 시작
C->>SH: ENTRYPOINT ["sh","-c","java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=<env> -jar /app.jar"]
Note right of SH #f0f9ff: 런타임에서 `$JAVA_OPTS` 확장
SH->>J: java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=<env> -jar /app.jar
J-->>Operator: 프로세스 로그/상태
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (1)
Dockerfile-dev (1)
4-4: Dockerfile-dev·Dockerfile-prod: ENTRYPOINT에 exec 추가 또는 셸 래퍼 제거 권장
현상:
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"](prod 파일도
spring.profiles.active=prod로 동일)최소 변경(신호 전달·좀비 처리 개선, 쉘 인젝션 방어):
- ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"] + ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"]※ Dockerfile-prod 에도 동일하게 exec 추가 적용
권장 대안(쉘 제거 + JAVA_TOOL_OPTIONS 활용):
- ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"] + ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=dev", "-jar", "/app.jar"]환경변수 주입은 기존
JAVA_OPTS대신 JVM이 자동 인식하는JAVA_TOOL_OPTIONS사용추가 권장: 컨테이너 init 프로세스(
tini등) 도입으로 신호 전달·좀비 처리 보강검증:
- 컨테이너 실행 후
ps -o pid,ppid,comm -p 1로 PID 1 프로세스 확인docker stop시 애플리케이션이 그레이스풀 셧다운되는지 로그 점검
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
Dockerfile-dev(1 hunks)Dockerfile-prod(1 hunks)docker-compose.dev.yml(2 hunks)docker-compose.prod.yml(2 hunks)
| - ./jmx-config.yml:/app/jmx-config.yml | ||
| networks: | ||
| - app-network | ||
| entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
app-green도 동일 이슈 — 동일한 수정 적용 필요
아래와 같이 exec 추가 또는 JAVA_TOOL_OPTIONS 전환을 권장합니다.
- entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"]
+ entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"]app-green 서비스의 entrypoint 동일 여부 확인을 위해 아래 명령어 실행합니다.
🏁 Script executed:
#!/bin/bash
rg -n "entrypoint" -C3 docker-compose.dev.ymlLength of output: 520
app-green 서비스에도 exec 적용 필요
docker-compose.dev.yml의 44번째 줄 entrypoint를 아래와 같이 수정하세요:
- entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"]
+ entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -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.
| entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"] | |
| entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"] |
🤖 Prompt for AI Agents
In docker-compose.dev.yml around line 44, the app-green service entrypoint needs
to use exec so the Java process replaces the shell; update the entrypoint to run
the shell with exec before java (e.g., ["sh","-c","exec java $JAVA_OPTS
-Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"]) so
signals are forwarded correctly and the shell no longer becomes the main
process.
| - ./jmx-config.yml:/app/jmx-config.yml | ||
| networks: | ||
| - app-network | ||
| entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Verification inconclusive
prod app-green: 동일 수정 적용 필요
다음과 같이 exec 추가 또는 JAVA_TOOL_OPTIONS 전환을 적용해 주세요.
- entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]
+ entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]prod app-green: entrypoint에 exec 추가 필요
sh -c로 java를 실행하면 PID 1이 쉘이 되어 시그널 전달·종료 처리 문제가 발생할 수 있습니다. exec로 대체하세요.
파일: docker-compose.prod.yml (라인 44)
- entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]
+ entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -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.
| entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] | |
| entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] |
🤖 Prompt for AI Agents
In docker-compose.prod.yml around line 44, the entrypoint currently runs java
via sh -c which leaves the shell as PID 1 and prevents proper signal
propagation; update the entrypoint to invoke exec within the sh -c command so
the java process replaces the shell (e.g., use sh -c "exec java ..."),
preserving the existing JVM options and environment variable escaping.
| ARG JAR_FILE=build/libs/edukit-api.jar | ||
| COPY ${JAR_FILE} app.jar | ||
| ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=prod", "-jar", "/app.jar"] | ||
| ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Verification inconclusive
프로덕션 이미지에서의 sh -c는 보안/신호 전달 리스크 — exec 추가 또는 JAVA_TOOL_OPTIONS로 전환 필요
- 프로덕션에서는 쉘 인젝션과 PID 1 문제의 영향이 더 큼.
- 최소 변경:
-ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]
+ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]- 권장 대안:
-ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]
+ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=prod", "-jar", "/app.jar"]- 운영 환경에서는
JAVA_TOOL_OPTIONS로 옵션을 주입해 쉘을 제거하는 구성을 권장합니다.
프로덕션 Dockerfile: ENTRYPOINT에서 sh -c 제거 — 신호 전달·쉘 인젝션 위험 (긴급 수정 필요)
sh -c 사용 시 PID 1로서 SIGTERM/SIGINT 등이 자식 JVM으로 직접 전달되지 않으며, $JAVA_OPTS 같은 환경변수 확장으로 쉘 인젝션 위험이 있음.
최소 변경(신호 전달 보장):
-ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]
+ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]권장(쉘 제거 — 안전·명시적 인수 전달):
-ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]
+ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=prod", "-jar", "/app.jar"]운영 권장: 옵션은 JAVA_TOOL_OPTIONS로 주입하여 쉘을 제거한 exec 형식으로 실행. 파일: Dockerfile-prod (라인 4)
📝 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.
| ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] | |
| ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] |
| ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] | |
| ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=prod", "-jar", "/app.jar"] |
🤖 Prompt for AI Agents
Dockerfile-prod around line 4: the current ENTRYPOINT uses sh -c which breaks
signal forwarding and allows shell-injection via $JAVA_OPTS; change to an
exec-form ENTRYPOINT that invokes the JVM directly (no sh -c) and stop expanding
untrusted vars in the shell — pass JVM options via the standard
JAVA_TOOL_OPTIONS environment variable or as explicit JSON-array arguments so
signals (SIGTERM/SIGINT) are forwarded to the JVM and no shell interpolation
occurs; minimally replace the shell form with an exec-form ENTRYPOINT that calls
java with the timezone, profile and -jar arguments, and optionally set or
document use of JAVA_TOOL_OPTIONS for additional options.
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
docker-compose.dev.yml(2 hunks)docker-compose.prod.yml(2 hunks)jmx-config.yml(0 hunks)
💤 Files with no reviewable changes (1)
- jmx-config.yml
| - ./jmx-config.yml:/app/jmx-config.yml | ||
| networks: | ||
| - app-network | ||
| entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dev 환경도 동일하게 exec 적용 필요
dev compose 역시 sh -c로 인해 PID 1/signal 문제와 JAVA_OPTS 해석 문제가 동일하게 발생합니다. prod와 동일한 방식으로 exec를 추가해 주세요.
- entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"]
+ entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=dev -jar /app.jar"]Also applies to: 36-36
🤖 Prompt for AI Agents
In docker-compose.dev.yml around lines 18 and 36, the entrypoint currently uses
sh -c which causes PID 1/signal forwarding and JAVA_OPTS expansion issues;
update both entrypoint definitions to use exec so the JVM runs as PID 1 and
signals are forwarded and environment expansion works — change the command
string to include exec before java (e.g., keep the existing shell wrapper but
use "sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul
-Dspring.profiles.active=dev -jar /app.jar" or the equivalent for the other
occurrence) so the shell replaces itself with the java process.
| - ./jmx-config.yml:/app/jmx-config.yml | ||
| networks: | ||
| - app-network | ||
| entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
쉘 entrypoint로 인한 신호 전달 및 명령 인젝션 위험 수정 필요
현재 sh -c "java $$JAVA_OPTS …" 형태는 셸이 PID 1로 남아 SIGTERM 등이 JVM까지 전달되지 않을 수 있고, $$JAVA_OPTS가 셸에서 그대로 해석되어 명령 인젝션 위험도 존재합니다. 최소한 exec를 추가해 셸이 자신을 Java 프로세스로 교체하도록 해 주세요.
- entrypoint: ["sh", "-c", "java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]
+ entrypoint: ["sh", "-c", "exec java $$JAVA_OPTS -Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar"]Also applies to: 36-36
🤖 Prompt for AI Agents
In docker-compose.prod.yml around lines 18 and 36, the entrypoint uses a shell
form that leaves a shell as PID 1 and uses an unsafe variable expansion
(\"$$JAVA_OPTS\") which risks broken signal propagation and command injection;
update the entrypoints to run the Java process as PID 1 by prepending exec and
stop using the literal $$ expansion — use a shell invocation that calls exec and
a properly quoted environment variable (e.g., sh -c 'exec java "$JAVA_OPTS"
-Duser.timezone=Asia/Seoul -Dspring.profiles.active=prod -jar /app.jar') or,
preferably, move options into explicit args so the Java binary is launched
directly without an intermediate shell.
📣 Jira Ticket
EDMT-454
👩💻 작업 내용
Docker 컨테이너 실행 시 JAVA_OPTS 환경 변수가 올바르게 전달되도록 엔트리포인트 설정을 개선했습니다.
주요 변경사항
Dockerfile-dev,Dockerfile-prod에서 shell 실행을 통한 JAVA_OPTS 변수 확장 지원docker-compose.dev.yml,docker-compose.prod.yml에 명시적인 엔트리포인트 설정 추가$$JAVA_OPTS형태로 적절한 변수 이스케이프 적용기술적 개선사항
📝 리뷰 요청 & 논의하고 싶은 내용
Docker 엔트리포인트에서 shell 실행 방식 변경이 보안이나 성능에 미치는 영향이 있는지 검토 부탁드립니다.
Test Plan
✅ Manual Testing Checklist
🧪 Automated Tests
./gradlew test./gradlew build🔍 Code Quality
Deployment Notes
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores