개발을 하다 보면 코드 변경 사항을 빠르게 반영하고 싶지만, docker compose up --build를 사용할 때마다 빌드 시간이 너~무 오래 걸려 불편함을 느낄 때가 있다.. 팀 프로젝트를 하는데 이와같은 문제를 겪다가 빌드 시간을 단축하면서도 코드 변경 사항이 실시간으로 반영되는 개발 환경을 구축해 보았다.
이번 포스팅에서는 그에 대한 내용을 다뤄보고자 한다.
해당 포스팅은 Java, springboot환경에서 실행됩니다.
문제점
- 느린 빌드 시간: docker compose up --build를 실행할 때마다 전체 이미지를 재빌드하느라 시간이 많이 소요 됨
- 비효율적인 개발 프로세스: 작은 코드 변경에도 빌드와 컨테이너 재시작을 반복해야 했음
목표
- 빌드 시간 단축: 전체 이미지를 재빌드하지 않고도 코드 변경 사항을 반영하고 싶음
- 실시간 코드 반영: 애플리케이션 코드 수정 시 즉시 변경 사항이 반영되도록 환경을 구성하고자 함.
해결 방법
1. 소스 코드 볼륨 마운트
Docker Compose에서 볼륨 마운트를 사용하여 호스트의 소스 코드를 컨테이너에 직접 연결함. 이를 통해 코드 변경 시 컨테이너 내부에도 즉시 반영되도록 설정
2. Gradle 설정 및 자동 컴파일
Gradle의 --continuous 옵션을 활용하여 소스 코드 변경 시 자동으로 재컴파일되도록 햇음. 이를 통해 애플리케이션이 최신 코드로 실행되도록 보장함
3. Spring Boot DevTools 활용
Spring Boot DevTools를 사용하여 애플리케이션이 클래스 변경 사항을 감지하고 자동으로 재시작되도록 설정
4. DevTools 폴링 모드 활성화
Docker 환경에서는 파일 시스템 이벤트가 컨테이너에 제대로 전달되지 않을 수 있으므로, DevTools의 폴링 모드를 활성화하여 변경 사항을 감지하도록 함
docker-compose.yml파일
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
volumes:
- ./src:/app/src
- ./build.gradle:/app/build.gradle
- ./settings.gradle:/app/settings.gradle
- ./gradle:/app/gradle
command: >
sh -c "./gradlew --no-daemon compileJava --continuous &
./gradlew --no-daemon bootRun"
environment:
SPRING_DEVTOOLS_RESTART_ENABLED: "true"
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-container:3306/playground
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 1234
depends_on:
- mysql-container
mysql-container:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_DATABASE: playground
ports:
- "3306:3306"
application.yml 파일
spring:
devtools:
restart:
enabled: true
additional-paths: /app/src
poll-interval: 1000
quiet-period: 500
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql-container:3306/playground?serverTimezone=Asia/Seoul
username: root
password: 1234
jpa:
open-in-view: false
database: mysql
show-sql: true
hibernate:
ddl-auto: update
server:
port: 8080
dockerfile
FROM openjdk:17-jdk-slim
WORKDIR /app
# Gradle 및 설정 파일 복사
COPY gradlew build.gradle settings.gradle ./
COPY gradle ./gradle
# Gradle 실행 권한 부여
RUN chmod +x gradlew
# 의존성 사전 다운로드
RUN ./gradlew clean assemble --no-daemon
# 애플리케이션 실행 포트 노출
EXPOSE 8080
# 컨테이너 실행 시 애플리케이션 구동
CMD ["./gradlew", "bootRun", "--no-daemon"]
그리고 build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.4'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.swyp'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'mysql:mysql-connector-java:8.0.33'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
tasks.register('watch') {
dependsOn 'classes'
doLast {
println 'Watching for changes...'
}
}
tasks.named('bootRun') {
dependsOn 'classes'
}
tasks.named('classes') {
mustRunAfter 'clean'
}
springBoot {
mainClass = 'com.swyp.playground.PlaygroundApplication'
}
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
완전 빠르다 헠
'Docker' 카테고리의 다른 글
| docker를 이용해서 나만의 서버를 배포해보자. (1) | 2024.12.14 |
|---|---|
| Docker volumes를 통해 안전하게 데이터를 지켜보자! (0) | 2024.11.21 |
| docker를 이용해서 팀 프로젝트 초기환경 세팅을 해보자! (0) | 2024.11.20 |