Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CI

on:
pull_request:
branches:
- main
- dev
push:
branches:
- main
- dev

jobs:
build-and-test:
runs-on: ubuntu-latest
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3

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

- name: Build & Test
run: ./gradlew build --no-daemon

- name: Upload test report (on failure)
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-report
path: build/reports/tests/
retention-days: 7
49 changes: 49 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# syntax=docker/dockerfile:1.7

# ===== Stage 1: Build =====
FROM eclipse-temurin:21-jdk-jammy AS builder

WORKDIR /app

# 빌드 설정 파일만 먼저 복사 (의존성 레이어 캐시 최적화)
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./

RUN chmod +x gradlew

# 의존성만 먼저 다운로드 (소스 변경 시에도 이 레이어는 캐시됨)
RUN ./gradlew bootJar -x test --no-daemon || true

# 소스 복사 후 빌드
COPY src src
RUN ./gradlew clean bootJar --no-daemon -x test

# 빌드된 jar에서 layer 추출
RUN java -Djarmode=layertools -jar build/libs/*.jar extract


# ===== Stage 2: Runtime =====
FROM eclipse-temurin:21-jre-jammy

# healthcheck 위해 curl 설치
RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*

# 비-root 유저 생성
RUN useradd -ms /bin/bash spring

WORKDIR /app

# layered jar 복사 (변경 빈도 낮은 순서대로)
COPY --from=builder --chown=spring:spring /app/dependencies/ ./
COPY --from=builder --chown=spring:spring /app/spring-boot-loader/ ./
COPY --from=builder --chown=spring:spring /app/snapshot-dependencies/ ./
COPY --from=builder --chown=spring:spring /app/application/ ./

USER spring

EXPOSE 8080

ENV JAVA_OPTS=""

ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS org.springframework.boot.loader.launch.JarLauncher"]
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ext {
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-config-server'
Expand Down
33 changes: 33 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
version: '3.9'

services:
config-server:
build:
context: .
dockerfile: Dockerfile
image: config-server:latest
container_name: config-server
ports:
- "8888:8080"
environment:
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
CONFIG_SERVER_USERNAME: ${CONFIG_SERVER_USERNAME}
CONFIG_SERVER_PASSWORD: ${CONFIG_SERVER_PASSWORD}
GIT_USERNAME: ${GIT_USERNAME}
GIT_PASSWORD: ${GIT_PASSWORD}
EUREKA_URL: ${EUREKA_URL:-http://eureka-server:8761/eureka/}
JAVA_OPTS: "-XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"
networks:
- first-ticket-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 5s
start_period: 60s
retries: 3
restart: unless-stopped

networks:
first-ticket-network:
external: true
name: first-ticket-network
188 changes: 94 additions & 94 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

@SpringBootTest(properties = {
"spring.cloud.config.server.git.clone-on-start=false",
"spring.cloud.config.server.git.uri=https://example.com/dummy.git",
"spring.cloud.config.server.git.username=dummy",
"spring.cloud.config.server.git.password=dummy",
"eureka.client.enabled=false"
})
@ActiveProfiles("test")
@SpringBootTest
class ConfigServerApplicationTests {

@Test
Expand Down
17 changes: 17 additions & 0 deletions src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
spring:
cloud:
config:
server:
git:
uri: https://example.com/dummy
username: dummy
password: dummy
clone-on-start: false
security:
user:
name: testuser
password: testpass

eureka:
client:
enabled: false
Loading