๐Ÿš€ Spring Boot ํ”„๋กœ์ ํŠธ์˜์˜ Render ๋ฐฐํฌ ์‹คํŒจ ์‚ฌ๋ก€ ์ •๋ฆฌ: gradlew, JAVA_HOME, Dockerfile ๋ฌธ์ œ ํ•ด๊ฒฐ

@leekh8 ยท May 13, 2025 ยท 6 min read

Code N Solve ๐Ÿ“˜: Spring Boot ํ”„๋กœ์ ํŠธ์˜์˜ Render ๋ฐฐํฌ ์‹คํŒจ ์‚ฌ๋ก€ ์ •๋ฆฌ

์ง€๋‚œ๋ฒˆ Vite ๋ฐฐํฌ ์˜ค๋ฅ˜ ๊ธ€๊ณผ๋Š” ๋‹ฌ๋ฆฌ, Java + Spring Boot + Gradle1 ํ™˜๊ฒฝ์˜ ๋ฐฑ์—”๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ Render2์— Docker๋กœ ๋ฐฐํฌํ•  ๋•Œ ๊ฒช์€ ๋นŒ๋“œ ์‹คํŒจ ์‚ฌ๋ก€์™€ ํ•ด๊ฒฐ ๊ณผ์ •์„ ์ •๋ฆฌํ•˜์˜€๋‹ค.

๊ฐ๊ฐ์˜ ์˜ค๋ฅ˜๋ฅผ ๋ถ„์„ํ•˜๊ณ  ํ•ด๊ฒฐํ•œ ๊ณผ์ •์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

Vite๋‚˜ Node.js ํ™˜๊ฒฝ์ด ์•„๋‹Œ, Java ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๋ฅผ Docker ํ™˜๊ฒฝ์—์„œ Render๋กœ ๋ฐฐํฌํ•˜๋ ค๊ณ  ํ•˜๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ๋„์›€์ด ๋˜๋ฉด ์ข‹๊ฒ ๋‹ค.

๐Ÿšจ 1. ./gradlew ์‹คํ–‰ ์˜ค๋ฅ˜ - Permission denied

โŒ ๋ฌธ์ œ ์ƒํ™ฉ

  ./gradlew: Permission denied

๐Ÿง ์›์ธ ๋ถ„์„

  • Git์—์„œ ํŒŒ์ผ ๊ถŒํ•œ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ถ”์ ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๋กœ์ปฌ์—์„œ๋Š” ์‹คํ–‰๋˜๋˜ ./gradlew ํŒŒ์ผ์ด ๋ฆฌ๋ˆ…์Šค ๋ฐฐํฌ ํ™˜๊ฒฝ(Render ๋“ฑ)์—์„œ๋Š” ์‹คํ–‰ ๊ถŒํ•œ(x) ์—†์ด ๋ณต์ œ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ.

  • ํŠนํžˆ gradlew๋Š” .gitignore๋กœ ์ œ์™ธ๋˜์ง€ ์•Š๋”๋ผ๋„ chmod +x๋กœ ๋ถ€์—ฌ๋œ ์‹คํ–‰ ๊ถŒํ•œ ์ž์ฒด๊ฐ€ Git ์ปค๋ฐ‹์— ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์œผ๋ฉฐ, ์ด๋Š” Linux ํ™˜๊ฒฝ์—์„œ Permission denied ์˜ค๋ฅ˜๋ฅผ ์œ ๋ฐœํ•จ.

  • Windows๋‚˜ macOS ํ™˜๊ฒฝ์—์„œ๋Š” ์‹คํ–‰ ๊ถŒํ•œ์ด ๋ฌธ์ œ ์—†์ด ์ ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋‚˜, Render์˜ Docker ๋นŒ๋“œ๋Š” Linux ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ ์ด ๊ถŒํ•œ์ด ์—„๊ฒฉํžˆ ์š”๊ตฌ๋จ.

โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

1. ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ

  • chmod +x ./gradlew

๐Ÿšจ 2. Gradle Wrapper ์—†์Œ - GradleWrapperMain ์˜ค๋ฅ˜

โŒ ๋ฌธ์ œ ์ƒํ™ฉ

  Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain

๐Ÿง ์›์ธ ๋ถ„์„

  • Gradle ํ”„๋กœ์ ํŠธ๋ฅผ Git์œผ๋กœ ๊ด€๋ฆฌํ•  ๋•Œ, ์ข…์ข… .gitignore์— ์˜ํ•ด ๋ฌด์‹ฌ์ฝ” ์ œ์™ธ๋˜๊ฑฐ๋‚˜ ์ปค๋ฐ‹ ๋ˆ„๋ฝ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Œ.

  • ํŠนํžˆ ๋‹ค์Œ ํŒŒ์ผ๋“ค์€ Gradle์˜ Wrapper3 ๊ธฐ๋Šฅ์„ ๊ตฌ์„ฑํ•˜๋Š” ํ•ต์‹ฌ ํŒŒ์ผ๋กœ, Wrapper ๋ฐฉ์‹์˜ ๋นŒ๋“œ๋Š” Gradle์ด ์„ค์น˜๋˜์ง€ ์•Š์€ ํ™˜๊ฒฝ์—์„œ๋„ ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์คŒ.

    • gradlew
    • gradlew.bat
    • gradle/wrapper/gradle-wrapper.jar
    • gradle/wrapper/gradle-wrapper.properties
  • ๋”ฐ๋ผ์„œ ์œ„ ํŒŒ์ผ๋“ค์ด ๋ˆ„๋ฝ๋˜๋ฉด ./gradlew ์‹คํ–‰ ์‹œ ๋‚ด๋ถ€์ ์œผ๋กœ org.gradle.wrapper.GradleWrapperMain ํด๋ž˜์Šค๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์–ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•จ.

โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

1. .gitignore์— ์˜ํ•ด ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ ๋‹ค์Œ ํŒŒ์ผ๋“ค์„ ๋ฐ˜๋“œ์‹œ ์ปค๋ฐ‹

  • gradlew
    gradlew.bat
    gradle/wrapper/gradle-wrapper.jar
    gradle/wrapper/gradle-wrapper.properties
  • ์ด ํŒŒ์ผ๋“ค์€ Gradle ๋นŒ๋“œ ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ์š”์†Œ๋กœ, Gradle ์„ค์น˜ ์—†์ด๋„ ./gradlew ๋ช…๋ น์–ด๋กœ ๋นŒ๋“œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ.

๐Ÿšจ 3. JAVA_HOME ๊ด€๋ จ ์˜ค๋ฅ˜

โŒ ๋ฌธ์ œ ์ƒํ™ฉ

Docker ๋นŒ๋“œ ๊ณผ์ •์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜ ๋ฐœ์ƒ.

  ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

๐Ÿง ์›์ธ ๋ถ„์„

  • Render์˜ ๊ธฐ๋ณธ ๋ฐฐํฌ ํ™˜๊ฒฝ์€ Node.js๋‚˜ Python๊ณผ ๊ฐ™์€ ์–ธ์–ด์—๋Š” ์นœํ™”์ ์ด์ง€๋งŒ, Java๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜์ง€ ์•Š์Œ.

  • ํŠนํžˆ env: docker ์„ค์ •์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ๋ณ„๋„์˜ Docker ์ด๋ฏธ์ง€์—์„œ Java๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์œผ๋ฉด Gradle ๋นŒ๋“œ ๊ณผ์ •์—์„œ JAVA_HOME ์„ค์ •์ด ์—†๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋จ.

  • Java ๊ธฐ๋ฐ˜์˜ ๋นŒ๋“œ๋ฅผ ์œ„ํ•œ ํ™˜๊ฒฝ์€ ์ง์ ‘ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜๋ฉฐ, Gradle ๋นŒ๋“œ ์‹œ ๋‚ด๋ถ€์ ์œผ๋กœ Java compiler๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•จ.

โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

1. Dockerfile์„ ์‚ฌ์šฉํ•ด Java๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์น˜

  •   # Dockerfile
      FROM eclipse-temurin:21-jdk
    
      WORKDIR /app
      COPY . .
    
      RUN chmod +x ./gradlew
      RUN ./gradlew build
    
      CMD find ./build/libs -name "*.jar" | xargs java -jar
  • Render์—์„œ Java๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด Dockerfile์—์„œ Java๋ฅผ ๋ช…์‹œ์ฒ™์œผ๋กœ ์„ค์น˜ํ•จ.

    • eclipse-temurin4์€ OpenJDK๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ณต์‹ Docker ์ด๋ฏธ์ง€.

๐Ÿšจ 4. Gradle Toolchain ์—๋Ÿฌ (Java 17 ์š”๊ตฌ)

โŒ ๋ฌธ์ œ ์ƒํ™ฉ

  Failed to calculate the value of task ':compileJava' property 'javaCompiler'.
  Cannot find a Java installation matching: {languageVersion=17...}

๐Ÿง ์›์ธ ๋ถ„์„

  • Gradle Toolchain5 ๊ธฐ๋Šฅ์€ ํŠน์ • Java ๋ฒ„์ „์œผ๋กœ์˜ ์ผ๊ด€๋œ ๋นŒ๋“œ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋จ.

    • ์˜ˆ: JavaLanguageVersion.of(17).
  • ๊ทธ๋Ÿฌ๋‚˜ Render์˜ Docker ๋นŒ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ์ž๋™์œผ๋กœ ํ•„์š”ํ•œ Java ๋ฒ„์ „์„ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š์Œ.

  • ๋”ฐ๋ผ์„œ toolchain์— ๋ช…์‹œ๋œ ๋ฒ„์ „๊ณผ Docker ์ด๋ฏธ์ง€์˜ JDK ๋ฒ„์ „์ด ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๋นŒ๋“œ ์‹œ Gradle์ด ํ•ด๋‹น ๋ฒ„์ „์„ ์ฐพ์ง€ ๋ชปํ•ด ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ด.

  • Java toolchain ์„ค์ •์ด ์ ์šฉ๋œ ์ƒํƒœ์—์„œ eclipse-temurin:21-jdk ๋“ฑ ์ƒ์œ„ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.

โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

1. build.gradle์—์„œ toolchain ์ œ๊ฑฐ

  • tasks.withType(JavaCompile) {
      options.encoding = 'UTF-8'
    }
  • build.gradle์—์„œ toolchain ์ œ๊ฑฐ ๋˜๋Š” Java ๋ฒ„์ „ ์ž๋™ ๋งค์นญ ์ œ๊ฑฐ.

๋˜๋Š” 2. Java ๋ฒ„์ „ Docker์™€ ๋งž์ถ”๊ธฐ

  • FROM eclipse-temurin:17-jdk
  • Dockerfile์˜ JDK ๋ฒ„์ „์„ Gradle toolchain๊ณผ ์ผ์น˜์‹œํ‚ด.

    • ๐Ÿ”Ž ์ถ”๊ฐ€๋กœ, Gradle์˜ toolchain ์„ค์ •์ด ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” Dockerfile์—์„œ ๋™์ผํ•œ JDK ๋ฒ„์ „์„ ๋ช…์‹œ์ ์œผ๋กœ ํฌํ•จ์‹œ์ผœ์•ผ ํ•จ.

    • java {
        toolchain {
          languageVersion = JavaLanguageVersion.of(17)
        }
      }
    • ์ด ๊ฒฝ์šฐ, ๋นŒ๋“œ ํ™˜๊ฒฝ์—์„œ๋„ ์ •ํ™•ํžˆ JDK 17์ด ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ์ •์ƒ ์ž‘๋™ํ•จ.

    • Failed to calculate the value of task ':compileJava' property 'javaCompiler'.
      Cannot find a Java installation matching: {languageVersion=17...}

๐Ÿšจ 5. Render ๋ฐฐํฌ ์„ค์ • - render.yaml

๐Ÿง ์›์ธ ๋ถ„์„

  • Github ์ €์žฅ์†Œ ๋ฃจํŠธ์— render.yaml์ด ์žˆ์–ด์•ผ ํ•จ.

  • Dockerfile ๊ธฐ์ค€์œผ๋กœ ๋นŒ๋“œ๋˜๋„๋ก ์„ค์ • ํ•„์š”ํ•จ.

  • Dockerfile์ด ์กด์žฌํ•˜๊ณ  CMD ๊ตฌ๋ฌธ์—์„œ .jar์‹คํ–‰ํ•ด์•ผ ํ•จ.

  • ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ healthCheckPath, buildCommand ๋“ฑ ์ถ”๊ฐ€ ์„ค์ • ๊ฐ€๋Šฅ.

โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

1. render.yaml ์ž‘์„ฑ

  services:
    - type: web
      name: testweave
      env: docker
      plan: free

๐Ÿšจ 6. DATABASE_URL ์ž๋™ ์ œ๊ณต vs H2

  • Render๋Š” PostgreSQL ์‚ฌ์šฉ ์‹œ ํ™˜๊ฒฝ๋ณ€์ˆ˜ DATABASE_URL์„ ์ž๋™ ์ œ๊ณตํ•จ.6

  • postgres://<user>:<password>@<host>:<port>/<dbname> ํ˜•์‹์˜ ์ ‘์† ๋ฌธ์ž์—ด๋กœ, Spring Boot์—์„œ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ •๋ณด๋ฅผ ํ•œ ์ค„๋กœ ์ œ๊ณตํ•จ.

  • ๊ธฐ์กด์— H2 (in-memory)๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด application.properties์— ๋‹ค์Œ์„ ๋ฐ˜์˜ํ•ด์•ผ ํ•จ.

โŒ ๋ฌธ์ œ ์ƒํ™ฉ

๐Ÿง ์›์ธ ๋ถ„์„

  • ๋กœ์ปฌ ๊ฐœ๋ฐœ์—์„œ H2 ์ธ๋ฉ”๋ชจ๋ฆฌ DB๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค๊ฐ€, Render์™€ ๊ฐ™์€ ์šด์˜ ๋ฐฐํฌ ํ™˜๊ฒฝ์„ธ์„œ๋Š” PostgreSQL ๊ฐ™์€ ์˜์†์ ์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ํ•„์š”ํ•จ

  • Render๋Š” PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ž๋™์œผ๋กœ DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์ง€๋งŒ, Spring Boot์˜ application.properties์—์„œ ์ด ๊ฐ’์„ ์ฝ๋„๋ก ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ H2๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์—ฐ๊ฒฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•จ.

  • ๋˜ํ•œ PostgreSQL์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด JDBC ๋“œ๋ผ์ด๋ฒ„ ์˜์กด์„ฑ์„ ๋ณ„๋„๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋ฉฐ, ๋กœ์ปฌ์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๋˜ ์„ค์ •์ด Render์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ.

โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

1. PostgreSQL ์‚ฌ์šฉ ์‹œ ์„ค์ •

  • # application.properties
    spring.datasource.url=${DATABASE_URL}
    spring.datasource.driver-class-name=org.postgresql.Driver
    spring.jpa.hibernate.ddl-auto=update
  • # build.gradle
    dependencies {
      implementation 'org.postgresql:postgresql:42.7.3'
    }
  • PostgreSQL ๋“œ๋ผ์ด๋ฒ„ ์˜์กด์„ฑ๋„ build.gradle์— ์ถ”๊ฐ€ ํ•„์š”ํ•จ.

โ›” H2์—์„œ ์ „ํ™˜ ์‹œ ์ฃผ์˜

  • ๋กœ์ปฌ ๊ฐœ๋ฐœ๊ณผ ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ DB๊ฐ€ ๋‹ค๋ฅผ ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ Flyway ๋˜๋Š” Liquibase ๋“ฑ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํˆด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ.

  • Render์—์„œ ์ œ๊ณตํ•˜๋Š” DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•์‹.

    • postgres://username:password@hostname:port/dbname
  • ํ•ด๋‹น URL์€ spring.datasource.url์— ๊ทธ๋Œ€๋กœ ๋„ฃ์œผ๋ฉด Spring Boot์—์„œ ์ž๋™์œผ๋กœ ๋ถ„๋ฆฌ ํŒŒ์‹ฑํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ.

๊ฒฐ๋ก 

  1. ./gradlew์— ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ (chmod +x ./gradlew)

  2. gradlew, gradle-wrapper.jar, .properties ๋“ฑ Wrapper ๊ด€๋ จ ํŒŒ์ผ์„ Git์— ๋ฐ˜๋“œ์‹œ ์ปค๋ฐ‹

  3. Dockerfile์—์„œ eclipse-temurin ์ด๋ฏธ์ง€๋กœ Java ํ™˜๊ฒฝ ๋ช…์‹œ

  4. Gradle toolchain์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ Docker JDK ๋ฒ„์ „๊ณผ ์ผ์น˜์‹œํ‚ฌ ๊ฒƒ

  5. Render ๋ฃจํŠธ์— render.yaml ์กด์žฌ ํ™•์ธ

  6. PostgreSQL ์‚ฌ์šฉ ์‹œ DATABASE_URL๊ณผ JDBC ์„ค์ • ์ถ”๊ฐ€

  7. ๋กœ์ปฌ์—์„œ๋Š” H2, ์šด์˜์—์„œ๋Š” PostgreSQL์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋„๊ตฌ(Flyway ๋“ฑ) ๋„์ž… ๊ณ ๋ ค

Render๋Š” ํŽธ๋ฆฌํ•˜๊ณ  ๋ฌด๋ฃŒ๋กœ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ์ด์ง€๋งŒ Java ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๋ณ„๋„ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ์„ ๊ผญ ๊ธฐ์–ตํ•ด์•ผ๊ฒ ๋‹ค!

@leekh8
Hello :)