개발/Docker
# [Docker] Docker Compose 를 활용해 2개 이상의 컨테이너 관리 하기
ForrestPark
2024. 12. 13. 14:13
🌞 2024.12.12 Thu
1. SpringBoot 와 MySQL 동시 생성
<<gradle version >>
• start.spring.io 홈페이지에서 sb 생성 -> spring web, spring boot dev tools, spring data jpa, mysql driver 의존성 추가. -> 스프링 프로젝트가 생성(이클립스에서 실행)
2. build.gradle dependencies 변경
📝📝📝 << build.gradle file >> 📝📝📝
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
3. Eclipse 로 프로젝트 열어서 변경 할 것
3.1 Projeect refresh
- □ 프로젝트 오른쪽 클릭 -> gradle-> refresh gradle 을 실행 (refresh 안하면 안됨)
- 📌 프로젝트 파일 옆에 [boot], [devtools] 글씨가 나옴.
- maven 은 refresh 필요 없음.
3.2 JDBC 의존성 추가 Spring DB connecting (on application.yml)
- resource 폴더에서 properties 파일 삭제
- resource 클릭-> new -> file -> application.yml 생성⭐️ 컨테이너로 실행시킨 SpringBoot 가 MySQL 에 연결이 안되는 이유
# 📝📝📝<application.yml> 📝📝📝 spring: datasource: url: jdbc:mysql://my-db:3306/mydb username: root password: qwer1234 driver-class-name: com.mysql.cj.jdbc.Driver
- 각각의 컨테이너는 자신만의 네트워크망과 ip 주소를 가짐.
- 호스트 컴퓨터 입장에서는 localhost 는 호스트 컴퓨터를 가리키지만, spring boot 컨테이너 입장에서 localhost 는 spring boot 컨테이너를 가리킴.
- localhost:3306 라는 주소는 spring boot 컨테이너 내부에 있는 3306번 포트와 연결을 시도 하게 됨. 하지만 spring boot 가 실행되는 컨테이너 내부 3306 포트에는 아무것도 실행 되고있지 않음.
- spring 이 db 에 안붙는 이유는 localhost 를 쓰기 때문임. 포트 두개를 localhost 동시에 안에서 쓸수는 없음.
- 8080 에서 3306 으로 들어가야함.
- compose 의 service 이름으로 서로 통신할 수있다. service 의 이름이 각각의 미니컴퓨터의 주소로 사용된다.
=> local host 대신 my-db 가 들어가야한다.
application.yml 에서 localhost 를 my-db(compose 에쓰인 service 명 ) 로 바꾸고 빌드하면 동시에 된다.
[Maven 버전 application 에서도 바꾸어주어야한다. ]3.3 test/java/com/example/demo 폴더에서 java 파일 삭제# 📝📝📝 gradle use case <Dockerfile> FROM openjdk:17-jdk COPY build/libs/*SNAPSHOT.jar /app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]
# 📝📝📝 maven use case <Dockerfile> FROM maven:3.8.3-openjdk-17 as maven_builder WORKDIR /app COPY pom.xml . COPY /src ./src RUN mvn clean install RUN mv target/*.jar target/application.jar # <-- add RUN ls -l /app/target FROM openjdk:17-jdk as builder COPY --from=maven_builder /app/target/*.jar /target ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
# 📝📝📝< compose.yml>📝📝📝 services: my-server: build: . ports: - 8080:8080 depends_on: my-db: condition: service_healthy my-db: image: mysql environment: MYSQL_ROOT_PASSWORD: qwer1234 MYSQL_DATABASE: mydb volumes: - ./mysql_data:/var/lib/mysql ports: - 3306:3306 healthcheck: test: [ "CMD", "mysqladmin", "ping" ] interval: 5s retries: 10
- 3.4 Dockerfile , compose.yml 파일 생성 및 실행
# 📝📝📝<application.properties> 📝📝📝 spring.mvc.view.prefix=/WEB-INF/views/ spring.mvc.view.suffix =.jsp spring.mvc.static-path-pattern=/resources/** spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://my-db:3306/apple_store?serverTimezone=Asia/Seoul&autoReconnect=true&useSSL=false spring.datasource.username=root spring.datasource.password=qwer1234 productimage.upload.directory=src/main/resources/static/image
- dependency on: mysql 을 먼저 실행후 스프링을 실행
- service healthy 가 있으면 일단 정지 하고 mysql 을 실행하고 나중에 spring 실행.
- 5초 에 한번씩 check 10번 실행하고 그 다음에 함.
- spring 이 먼저 켜지면 그다음에 db 를 붙일 수가 없음.
- cd Docker/demo 로 들어가서 build 시작.
./gradlew clean build # mvn clean install -DskipTest # /Library/apache-maven-3.9.9/bin/mvn clean install -DskipTest # /Library/apache-maven-3.9.9/bin/mvn clean package docker compose up -d --build docker compose ps docker ps docker logs [container ID] docker compose down
- 3.5 Project clean build, Compose 실행