From e9159e9aef96989a0c1d20fb2eb525e1f7fc6de9 Mon Sep 17 00:00:00 2001 From: hodoon Date: Fri, 9 Jan 2026 20:44:44 +0900 Subject: [PATCH 1/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 37 +++++++++++++++++ .github/workflows/cicd.yml | 82 ++++++++++++++++++++++++++++++++++++++ Dockerfile | 21 ++++++++++ 3 files changed, 140 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/cicd.yml create mode 100644 Dockerfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..66e6c60 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + pull_request: + branches: [ "develop" ] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4.2.2 + + - name: Set up JDK 17 + uses: actions/setup-java@v4.7.1 + with: + java-version: '17' + distribution: 'temurin' + + - name: Cache Gradle + uses: actions/cache@v4.2.3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew clean build \ No newline at end of file diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml new file mode 100644 index 0000000..257e1af --- /dev/null +++ b/.github/workflows/cicd.yml @@ -0,0 +1,82 @@ +name: CI/CD + +on: + push: + branches: [ "main" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4.2.2 + + - name: Set up JDK 17 + uses: actions/setup-java@v4.7.1 + with: + java-version: '17' + distribution: 'temurin' + + - name: Cache Gradle packages + uses: actions/cache@v4.2.3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.10.0 + + - name: Log in to Docker Hub + uses: docker/login-action@v3.4.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Cache Docker layers + uses: actions/cache@v4.2.3 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Build and Push Docker image + if: github.ref == 'refs/heads/main' + uses: docker/build-push-action@v6.16.0 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.PROD_IMAGE_NAME }}:latest + platforms: linux/amd64 + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max + + - name: Move cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache + + deploy: + runs-on: ubuntu-latest + needs: build + steps: + - name: SSH to Server and Deploy + if: github.ref == 'refs/heads/main' + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.PROD_SERVER_HOST }} + port: ${{ secrets.PROD_SERVER_PORT }} + username: ${{ secrets.PROD_SERVER_USERNAME }} + key: ${{ secrets.PROD_SERVER_KEY }} + script: | + cd /home/ec2-user/alter + echo "${{ secrets.PROD_ENV }}" > ./env/prodEnv + ./deploy.sh + docker image prune -f + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7ff161d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +# ---------- Build Stage ---------- +FROM gradle:8.13-jdk17-alpine AS build +WORKDIR /home/gradle/project + +COPY build.gradle settings.gradle ./ +COPY gradle gradle/ + +COPY src src + +# 3) 빌드 (테스트까지 포함하려면 build, 제외하려면 -x test) +RUN gradle clean build + +# ---------- Run Stage ---------- +FROM eclipse-temurin:17-jre-alpine +WORKDIR /app + +COPY --from=build /home/gradle/project/build/libs/*.jar api.jar + +EXPOSE 8080 + +ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-jar", "api.jar"] \ No newline at end of file From 4cadb496b46b6958b9029e71b4ddba15104ebf54 Mon Sep 17 00:00:00 2001 From: hodoon Date: Sun, 11 Jan 2026 21:11:50 +0900 Subject: [PATCH 2/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 26 +++----- .github/workflows/cicd.yml | 103 +++++++++++++++++------------ Dockerfile | 35 +++++++--- build.gradle | 1 + src/main/resources/application.yml | 10 ++- 5 files changed, 106 insertions(+), 69 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66e6c60..80f78c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: CI +name: CI (develop) on: pull_request: @@ -8,30 +8,22 @@ permissions: contents: read jobs: - build: + build-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.2.2 + - name: Checkout + uses: actions/checkout@v4.2.2 - name: Set up JDK 17 uses: actions/setup-java@v4.7.1 with: - java-version: '17' - distribution: 'temurin' - - - name: Cache Gradle - uses: actions/cache@v4.2.3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }} - restore-keys: | - ${{ runner.os }}-gradle- + distribution: temurin + java-version: "17" + cache: gradle - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew clean build \ No newline at end of file + - name: Build & Test (Gradle) + run: ./gradlew clean build diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 257e1af..8a3de40 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -1,33 +1,28 @@ -name: CI/CD +name: CI/CD (main) on: push: branches: [ "main" ] +permissions: + contents: read + +concurrency: + group: valuedi-prod-deploy + cancel-in-progress: true + jobs: - build: + build-and-push: runs-on: ubuntu-latest + outputs: + image_repo: ${{ steps.meta.outputs.image_repo }} + image_tag: ${{ steps.meta.outputs.image_tag }} + steps: - - name: Checkout code + - name: Checkout uses: actions/checkout@v4.2.2 - - name: Set up JDK 17 - uses: actions/setup-java@v4.7.1 - with: - java-version: '17' - distribution: 'temurin' - - - name: Cache Gradle packages - uses: actions/cache@v4.2.3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.10.0 @@ -37,46 +32,70 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Cache Docker layers - uses: actions/cache@v4.2.3 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- + - name: Set image meta + id: meta + run: | + echo "image_repo=${{ secrets.DOCKER_USERNAME }}/valuedi-backend" >> $GITHUB_OUTPUT + echo "image_tag=${{ github.sha }}" >> $GITHUB_OUTPUT - - name: Build and Push Docker image - if: github.ref == 'refs/heads/main' + - name: Build & Push (latest + sha) uses: docker/build-push-action@v6.16.0 with: context: . file: ./Dockerfile push: true - tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.PROD_IMAGE_NAME }}:latest platforms: linux/amd64 - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache + tags: | + ${{ steps.meta.outputs.image_repo }}:latest + ${{ steps.meta.outputs.image_repo }}:${{ steps.meta.outputs.image_tag }} + cache-from: type=gha + cache-to: type=gha,mode=max deploy: runs-on: ubuntu-latest - needs: build + needs: build-and-push + steps: - - name: SSH to Server and Deploy - if: github.ref == 'refs/heads/main' + - name: Deploy via SSH (Blue/Green) uses: appleboy/ssh-action@v1.2.2 with: host: ${{ secrets.PROD_SERVER_HOST }} port: ${{ secrets.PROD_SERVER_PORT }} username: ${{ secrets.PROD_SERVER_USERNAME }} key: ${{ secrets.PROD_SERVER_KEY }} + script_stop: true script: | - cd /home/ec2-user/alter - echo "${{ secrets.PROD_ENV }}" > ./env/prodEnv + set -euo pipefail + + APP_DIR="/home/ubuntu/valuedi/app" + cd "$APP_DIR" + + # 1) PROD_ENV를 .env로 반영 (멀티라인 안전) + cat > .env << 'EOF' + ${{ secrets.PROD_ENV }} + EOF + + # 2) IMAGE_REPO / IMAGE_TAG 강제 주입 (PROD_ENV에 없거나 달라도 덮어씀) + IMAGE_REPO="${{ needs.build-and-push.outputs.image_repo }}" + IMAGE_TAG="${{ needs.build-and-push.outputs.image_tag }}" + + # IMAGE_REPO 업데이트/추가 + if grep -q '^IMAGE_REPO=' .env; then + sed -i "s|^IMAGE_REPO=.*|IMAGE_REPO=${IMAGE_REPO}|" .env + else + echo "IMAGE_REPO=${IMAGE_REPO}" >> .env + fi + + # IMAGE_TAG 업데이트/추가 + if grep -q '^IMAGE_TAG=' .env; then + sed -i "s|^IMAGE_TAG=.*|IMAGE_TAG=${IMAGE_TAG}|" .env + else + echo "IMAGE_TAG=${IMAGE_TAG}" >> .env + fi + + # 3) 최신 이미지 pull 확인 + 배포 + chmod +x deploy.sh scripts/healthcheck.sh scripts/switch_upstream.sh ./deploy.sh + + # 4) 사용하지 않는 이미지 정리(선택) docker image prune -f - diff --git a/Dockerfile b/Dockerfile index 7ff161d..b52699c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,38 @@ +# syntax=docker/dockerfile:1.7 + # ---------- Build Stage ---------- -FROM gradle:8.13-jdk17-alpine AS build -WORKDIR /home/gradle/project +FROM eclipse-temurin:17-jdk-jammy AS build +WORKDIR /workspace + +# Gradle 캐시 최적화: 설정/래퍼를 먼저 복사 +COPY gradlew . +COPY gradle gradle +COPY settings.gradle* build.gradle* gradle.properties* ./ +# 멀티모듈/버전카탈로그 사용 시 +COPY gradle/libs.versions.toml gradle/libs.versions.toml -COPY build.gradle settings.gradle ./ -COPY gradle gradle/ +# 의존성 캐시 (소스 없이도 가능한 단계) +RUN chmod +x gradlew \ + && ./gradlew --no-daemon dependencies > /dev/null 2>&1 || true +# 소스 복사 COPY src src -# 3) 빌드 (테스트까지 포함하려면 build, 제외하려면 -x test) -RUN gradle clean build +# 빌드 (테스트는 CI에서 수행하므로 컨테이너 빌드에서는 제외 권장) +RUN ./gradlew --no-daemon clean bootJar -x test # ---------- Run Stage ---------- -FROM eclipse-temurin:17-jre-alpine +FROM eclipse-temurin:17-jre-jammy AS runtime WORKDIR /app -COPY --from=build /home/gradle/project/build/libs/*.jar api.jar +# 보안/권장: non-root 유저로 실행 +RUN useradd -ms /bin/bash appuser +USER appuser + +# bootJar 복사 +COPY --from=build /workspace/build/libs/*.jar app.jar EXPOSE 8080 -ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-jar", "api.jar"] \ No newline at end of file +# 기본 JVM 옵션(필요 시 docker-compose/.env에서 JAVA_TOOL_OPTIONS로 덮어쓰기 가능) +ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-jar", "app.jar"] diff --git a/build.gradle b/build.gradle index 0862edf..896fc8b 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,7 @@ dependencies { // Spring Boot Core implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-actuator' // Lombok compileOnly 'org.projectlombok:lombok' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b91d59e..e3531e3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,4 +19,12 @@ spring: ddl-auto: ${DDL_AUTO} properties: hibernate: - format_sql: true \ No newline at end of file + format_sql: true +management: + endpoints: + web: + exposure: + include: health + endpoint: + health: + show-details: never From 17fe007a3c1b2e0bf33b65f6621c0960d53a5f45 Mon Sep 17 00:00:00 2001 From: hodoon Date: Sun, 11 Jan 2026 21:28:33 +0900 Subject: [PATCH 3/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 9 ++++++-- build.gradle | 1 + src/test/resources/application-test.yml | 30 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/application-test.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80f78c6..95fd402 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,5 +25,10 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build & Test (Gradle) - run: ./gradlew clean build + # ✅ CI에서만 test 프로필로 실행 + - name: Test with Spring profile (test) + run: ./gradlew clean test -Dspring.profiles.active=test + + # (선택) 테스트 통과 후 빌드까지 하고 싶으면 + - name: Build (skip tests) + run: ./gradlew bootJar -x test diff --git a/build.gradle b/build.gradle index 896fc8b..3c41435 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,7 @@ dependencies { // Test testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testRuntimeOnly 'com.h2database:h2' // Swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.13' diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml new file mode 100644 index 0000000..77f1642 --- /dev/null +++ b/src/test/resources/application-test.yml @@ -0,0 +1,30 @@ +spring: + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:valuedi_test;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + username: sa + password: + + jpa: + database: h2 + database-platform: org.hibernate.dialect.H2Dialect + show-sql: false + hibernate: + ddl-auto: create-drop + properties: + hibernate: + format_sql: true + + data: + redis: + host: localhost + port: 6379 + +management: + endpoints: + web: + exposure: + include: health + endpoint: + health: + show-details: never From 0153e32763cc5f75b80a1d12bd0bbf02af89f083 Mon Sep 17 00:00:00 2001 From: hodoon Date: Sun, 11 Jan 2026 21:31:32 +0900 Subject: [PATCH 4/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95fd402..e4b6dcc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,3 @@ jobs: # ✅ CI에서만 test 프로필로 실행 - name: Test with Spring profile (test) run: ./gradlew clean test -Dspring.profiles.active=test - - # (선택) 테스트 통과 후 빌드까지 하고 싶으면 - - name: Build (skip tests) - run: ./gradlew bootJar -x test From c058d04ba73ffa9283f74120417bd67103684f1c Mon Sep 17 00:00:00 2001 From: hodoon Date: Sun, 11 Jan 2026 21:44:14 +0900 Subject: [PATCH 5/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradlew | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gradlew diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 From 493b31ca0d9b0c6266af9192f3cdd095d140abc7 Mon Sep 17 00:00:00 2001 From: hodoon Date: Sun, 11 Jan 2026 21:45:32 +0900 Subject: [PATCH 6/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4b6dcc..80f78c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,5 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - # ✅ CI에서만 test 프로필로 실행 - - name: Test with Spring profile (test) - run: ./gradlew clean test -Dspring.profiles.active=test + - name: Build & Test (Gradle) + run: ./gradlew clean build From 75fba74361805714b68158b47ab9d5f0ae33e307 Mon Sep 17 00:00:00 2001 From: hodoon Date: Sun, 11 Jan 2026 21:48:52 +0900 Subject: [PATCH 7/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e3531e3..c5ff1ef 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -14,9 +14,9 @@ spring: jpa: database: mysql database-platform: org.hibernate.dialect.MySQLDialect - show-sql: ${SHOW_SQL} + show-sql: ${SHOW_SQL:false} hibernate: - ddl-auto: ${DDL_AUTO} + ddl-auto: ${DDL_AUTO:none} properties: hibernate: format_sql: true From 2fcabcc3286dd4695bb3b421d53fcb09e57dbc77 Mon Sep 17 00:00:00 2001 From: hodoon Date: Sun, 11 Jan 2026 21:52:10 +0900 Subject: [PATCH 8/8] =?UTF-8?q?infra:=20GitHub=20Actions=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20AWS=20CI/CD=20=ED=8C=8C=EC=9D=B4=ED=94=84=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c5ff1ef..790477d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,13 +4,13 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: ${DB_URL} - username: ${DB_USERNAME} - password: ${DB_PASSWORD} + url: ${DB_URL:jdbc:mysql://localhost:3306/valuedi?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8} + username: ${DB_USERNAME:test} + password: ${DB_PASSWORD:test} data: redis: - host: ${REDIS_HOST} - port: ${REDIS_PORT} + host: ${REDIS_HOST:localhost} + port: ${REDIS_PORT:6379} jpa: database: mysql database-platform: org.hibernate.dialect.MySQLDialect