저번달에 정리해서 글을 써야 되겠다 다짐했건만... 늦게 올리게 됐네요.. ㅎㅎ
최근 스프링 블로그 를 보신분은 알겠지만. 3.1.0 RC1 부터 docker-compose를 지원하게 됐습니다!
기존엔 docker-compose를 cli를 통해 서비스 구동하고 그랬지만... 이런 작업을 스프링에서 관리해주는.. ㅠㅠ
어떻게 가능하게 됐는지는 spring-boot-docker-compose을 확인해 보면 신규로 생긴 인터페이스며 구현체들의 모듈을 확인해볼 수 있습니다.
- core
- lifecycle
- readiness
- connection
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.core;
import java.time.Duration;
import java.util.List;
import java.util.Set;
import org.springframework.boot.logging.LogLevel;
/**
* Provides a high-level API to work with Docker compose.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @since 3.1.0
*/
public interface DockerCompose {
/**
* Timeout duration used to request a forced stop.
*/
Duration FORCE_STOP = Duration.ZERO;
/**
* Run {@code docker compose up} to create and start services. Waits until all
* contains are started and healthy.
* @param logLevel the log level used to report progress
*/
void up(LogLevel logLevel);
/**
* Run {@code docker compose down} to stop and remove any running services.
* @param timeout the amount of time to wait or {@link #FORCE_STOP} to stop without
* waiting.
*/
void down(Duration timeout);
/**
* Run {@code docker compose start} to start services. Waits until all containers are
* started and healthy.
* @param logLevel the log level used to report progress
*/
void start(LogLevel logLevel);
/**
* Run {@code docker compose stop} to stop any running services.
* @param timeout the amount of time to wait or {@link #FORCE_STOP} to stop without
* waiting.
*/
void stop(Duration timeout);
/**
* Return if services have been defined in the {@link DockerComposeFile} for the
* active profiles.
* @return {@code true} if services have been defined
* @see #hasDefinedServices()
*/
boolean hasDefinedServices();
/**
* Return if services defined in the {@link DockerComposeFile} for the active profile
* are running.
* @return {@code true} if services are running
* @see #hasDefinedServices()
* @see #getRunningServices()
*/
boolean hasRunningServices();
/**
* Return the running services for the active profile, or an empty list if no services
* are running.
* @return the list of running services
*/
List<RunningService> getRunningServices();
/**
* Factory method used to create a {@link DockerCompose} instance.
* @param file the docker compose file
* @param hostname the hostname used for services or {@code null} if the hostname
* should be deduced
* @param activeProfiles a set of the profiles that should be activated
* @return a {@link DockerCompose} instance
*/
static DockerCompose get(DockerComposeFile file, String hostname, Set<String> activeProfiles) {
DockerCli cli = new DockerCli(null, file, activeProfiles);
return new DefaultDockerCompose(cli, hostname);
}
}
그럼 우리는 어떻게 spring-boot에서 docker-compose를 사용하는지 간단하게 정리를 해보고자 합니다.
시작하기
간단하게 3.1.0-RC2 버전의 스프링부트 앱을 만들고 시작해보겠습니다.
작성하기 귀찮으신 분은 소스코드 첨부합니다.
-> https://github.com/kgggh/java-spring-learning/tree/main/spring-docker-compose
수정사항
- build.gradle
- implementation 'org.springframework.boot:spring-boot-docker-compose'
- yaml
- spring docker-compose property
- docker-compose file
1. spring-boot-docker-compose 모듈을 추가해줍니다.
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.0-RC2'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-docker-compose'
implementation 'org.springframework.boot:spring-boot-starter-web'
}
tasks.named('test') {
useJUnitPlatform()
}
2. docker-compose 사용을 위한 propery를 추가해줍니다. 설명은 2.1의 이미지를 참고해주세요!!
applcation.yml
spring:
profiles:
active:
- test
---
spring:
config:
activate:
on-profile: test
docker:
compose:
lifecycle-management: start_and_stop # container life-cycle에 대한 옵션.
file: docker-compose-test-redis.yml file: docker-compose-test-redis.yml # 작성 파일이 애플리케이션과 동일한 디렉터리에 없거나 이름이 다른 경우 경로 지정
start:
log-level: info # docker-compose 출력 로그 레벨 설정
command: up # 서비스 컨테이너 구동 옵션. run | start 선택가능
stop:
command: down 서비스 컨테이너 구동 옵션. down | stop 선택가능
---
spring:
config:
activate:
on-profile: real
docker:
compose:
lifecycle-management: start_and_stop # container life-cycle에 대한 옵션.
file: docker-compose.yml # 작성 파일이 애플리케이션과 동일한 디렉터리에 없거나 이름이 다른 경우 경로 지정
start:
log-level: info # docker-compose 출력 로그 레벨 설정
command: start # 서비스 컨테이너 구동 옵션. run | start 선택가능
stop:
command: stop # 서비스 컨테이너 구동 옵션. down | stop 선택가능
2.1. docker-compose properies
3. docker-compose file을 2개를 작성합니다. profile별 test, real 구분을 짓는다는 가정하에,
-> 원활한 작업을 위해 파일의 위치는 src/resource 하위에 생성 후 작성합니다.
docker-compose.yml
services:
redis:
container_name: real-redis
image: 'redis:7.0'
ports:
- '6379:6379'
labels:
org.springframework.boot.service-connection: redis
org.springframework.boot.readiness-check.tcp.disable: true
-------------------------------
docker-compose-test-redis.yml
services:
redis:
container_name: test-redis
image: 'redis:7.0'
ports:
- '6300:6379'
labels:
org.springframework.boot.service-connection: redis
org.springframework.boot.readiness-check.tcp.disable: true
하단의 이미지와 같은 구조로 작성이 됐습니다.
그렇다면 진짜 스프링에서 docker container를 실행해주는지 확인해 봐야겠죠?
결과
profile은 test로 설정 후 application을 실행해보겠습니다. 그렇다면 로그가 출력되는걸 볼수 있을겁니다.
2023-05-14T01:37:21.409+09:00 INFO 41786 --- [ main] c.e.s.SpringDockerComposeApplication : Starting SpringDockerComposeApplication using Java 17.0.6 with PID 41786 (/Users/kimgeonhee/Desktop/java-spring/spring-docker-compose/build/classes/java/main started by kimgeonhee in /Users/kimgeonhee/Desktop/java-spring/spring-docker-compose)
2023-05-14T01:37:21.412+09:00 INFO 41786 --- [ main] c.e.s.SpringDockerComposeApplication : The following 1 profile is active: "test"
2023-05-14T01:37:21.486+09:00 INFO 41786 --- [ main] .s.b.d.c.l.DockerComposeLifecycleManager : Found Docker Compose file '/Users/kimgeonhee/Desktop/java-spring/spring-docker-compose/build/resources/main/docker-compose-test-redis.yml'
2023-05-14T01:37:22.282+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Network main_default Creating
2023-05-14T01:37:22.336+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Network main_default Created
2023-05-14T01:37:22.336+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container test-redis Creating
2023-05-14T01:37:22.446+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container test-redis Created
2023-05-14T01:37:22.456+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container test-redis Starting
2023-05-14T01:37:22.933+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container test-redis Started
2023-05-14T01:37:22.934+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container test-redis Waiting
2023-05-14T01:37:23.440+09:00 INFO 41786 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container test-redis Healthy
2023-05-14T01:37:24.440+09:00 INFO 41786 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2023-05-14T01:37:24.450+09:00 INFO 41786 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-05-14T01:37:24.450+09:00 INFO 41786 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.8]
2023-05-14T01:37:24.523+09:00 INFO 41786 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-05-14T01:37:24.523+09:00 INFO 41786 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 790 ms
2023-05-14T01:37:24.860+09:00 INFO 41786 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2023-05-14T01:37:24.869+09:00 INFO 41786 --- [ main] c.e.s.SpringDockerComposeApplication : Started SpringDockerComposeApplication in 3.807 seconds (process running for 4.321)
CommandLineRunner Args: []
진짜 실행이 됐는지 로그만으로 확인하기는 어려우니 docker-desktop 혹은 cli를 통해 확인을 해보겠습니다.
하단의 이미지와같이 test-redis로 작성한 6300 port로 mapping되서 실행되는 모습을 볼수 있습니다.
앱 구동을 중지하면 test-redis 컨테이너가 사라진걸 볼수 있죠?
이렇게 간단하게 spring-boot docker-compose 간단한 사용법에 대해 알아봤습니다.
자세한 내용은 spring 블로그나 spring-project github을 통해 어떤 부분이 추가 됐는지 확인해보시면 좋을듯 싶네요 ㅎㅎㅎ
참고 문서
https://www.danvega.dev/newsletter/spring-boot-3-1-first-look/
https://docs.spring.io/spring-boot/docs/3.1.0-RC2/reference/htmlsingle/#features.docker-compose
'spring' 카테고리의 다른 글
[spring] gradle build fail (0) | 2023.10.18 |
---|---|
[spring] OpenFeign 로그 사용자화 (0) | 2023.08.30 |
flyway를 이용한 db migration (0) | 2022.10.05 |
[Jackson] 추상클래스, 인터페이스를 파라미터로? (0) | 2022.06.27 |
@PathVariable로 인한 이슈 (1) | 2022.05.01 |