728x90
https://bestdevelop-lab.tistory.com/154
Docker compose 설정 및 각종 테스트
Docker compose란?여러 개의 Docker Container를 정의하고 이들을 하나의 애플리케이션으로 관리할 수 있게 해주는 것 여기서는 두 개의 컨테이너를 동일 네트워크에 포함시킬 예정네트워크는 별도로
bestdevelop-lab.tistory.com
이전 Docker compose 글에서 추가, 변경이 된 내용
1. Redis (application.yml)
- 이메일 인증 코드를 저장하기 위해 Redis가 추가
- 추후 JWT 토큰의 Refresh Token을 저장할 때도 Redis가 필요
spring:
# 레디스
data:
redis:
host: localhost
port: 6379
2. docker-compose.yml
- 이전 글의 Docker compose 방식
- docker build -t test-image(이미지명) . → 명령어를 사용하여 이미지 생성
- docker-compose.yml에서 services.myapp.image : test-image(이미지명) 으로 Spring에 사용할 image 지정
services:
myapp:
image: 이미지명
container_name: playheaven-container
build:
context: .
dockerfile: Dockerfile
depends_on:
db :
condition: service_healthy
ports:
- "8080:8080"
하지만, 생각해보니 아래 두 줄의 명령어에 의해서 '현재 디렉토리에 있는 Dockerfile을 실행시켜서 image를 build 하겠다'라는 의미로 작동 됨
services.myapp.build.context : .
services.myapp.build.dockerfile : Dockfile
따라서, 'docker build -t 이미지명 .' 명령어를 할 필요 없이 아래 처럼 docker-compose.yml 파일 하나로 가능함
services:
myapp:
container_name: playheaven-container
build:
context: .
dockerfile: Dockerfile
depends_on:
db :
condition: service_healthy
ports:
- "8080:8080"
3. docker-compose.yml만 실행 vs build 기준
- docker-compose.yml 파일만 변경이 되었다면 새로 빌드할 필요 없이 컨테이너 삭제 후 docker-compose.yml만 실행하면 됨
- 하지만 그 외에 자바 코드 추가, 삭제 변경 / application.yml / Dockerfile 변경 시에는 컨테이너 뿐만 아니라 Spring image(myapp)까지 삭제한 뒤 build → docker-compose.yml 실행 순서로 해야 함
docker-compose.yml 설정 추가
services:
redis:
image: redis:latest
container_name: redis_test
ports:
- 6379:6379
volumes:
- ./redis/data:/data
- ./redis/conf/redis.conf:/usr/local/conf/redis.conf
labels:
- "name=redis"
- "mode=standalone"
restart: always
command: redis-server /usr/local/conf/redis.conf
- service.redis.image
- 가장 최신 버전 redis 사용
- service.redis.container_name
- 컨테이너로 사용할 이름
- 설정하지 않을 경우 Docker가 자동 할당
- service.redis.ports
- 접근 포트 설정 (호스트포트:컨테이너포트)
- service.redis.volumes
- 로컬 디렉토리와 컨테이너 내부 디렉토리를 마운트
- ./redis/data:/data는 컨테이너의 /data 디렉토리에 데이터를 저장하면서, 로컬 디렉토리(./redis/data)에도 이를 유지
⇒ 컨테이너가 삭제되더라도 데이터는 로컬에 남아있어, 컨테이너 재시작 시 데이터 복구 가능 - ./redis/conf/redis.conf:/usr/local/conf/redis.conf는 Redis 설정 파일을 외부에서 관리할 수 있도록 마운트
- service.redis.labels
- 컨테이너에 메타 데이터 추가
- name=redis, mode=standalone이라는 라벨을 부여해 컨테이너를 식별하거나 필터링 가능
- Docker 명령어나 UI 도구에서 컨테이너를 관리할 때 유용
- service.redis.restart
- 컨테이너 종료 시 재시작 여부 설정
- always : 컨테이너가 중지되거나 충돌 시 무조건 재시작
- service.redis.command
- 컨테이너가 시작될 때 실행할 명령어 설정
- 특정 설정 파일(/usr/local/conf/redis.conf)을 사용해 실행
docker-compose.yml 실행 → Docker Container 확인
- 3개 Container 모두 정상 실행 확인
- Postman을 이용하여 이메일 인증 코드 발송 → 에러 발생
- Docker의 Spring Boot 확인 → ConnectionException : Connection refused
원인
- 이전 Docker compose 글에서 DB Connection을 docker 설정에 맞춰야하는 문제와 동일
- Local에서는 localhost이지만, Docker에서는 host.docker.internal로 설정을 해야한다고 함
- host.docker.internal 설정은 docker-compose.yml 파일의 services 이름을 넣으면 됨
application.yml 파일이 변경 되었기 때문에 아래 순서로 진행
1. Container 삭제
2. Image 삭제
3. Build
4. docker-compose.yml 실행(터미널 명령 : docker compose up)
5. 3개 컨테이너 정상 작동 확인
6. Postman 정상 작동 확인
7. Docker의 Redis에 저장 되었는 지 확인
- Docker Redis 접근 명령
- docker exec -it 레디스컨테이너명 redis-cli
docker exec -it redis_test redis-cli
최종 설정
application.yml
spring:
# 레디스
data:
redis:
host: redis
port: 6379
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://db:3306/playheaven
username: root
password: 1234
#Email 인증
mail:
host: smtp.gmail.com
port: 587
username: 아이디
password: 비밀번호
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
connectiontimeout: 5000
timeout: 5000
writetimeout: 5000
auth-code-expiration-millis: 300000 # 5 * 60 * 1000(밀리초) == 5분
jpa:
open-in-view: true
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate.format_sql: true
dialect: org.hibernate.dialect.MySQL8InnoDBDialect
logging:
level:
org.hibernate.SQL: debug
docker-compose.yml
version: '3.8'
services:
redis:
image: redis:latest
container_name: redis_test
ports:
- 6379:6379
volumes:
- ./redis/data:/data
- ./redis/conf/redis.conf:/usr/local/conf/redis.conf
labels:
- "name=redis"
- "mode=standalone"
restart: always
command: redis-server /usr/local/conf/redis.conf
db:
image: mysql:8.0
container_name: mysql-container
environment:
MYSQL_ROOT_PASSWORD : 1234
MYSQL_DATABASE: playheaven
ports:
- "3307:3306"
restart: always
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u root -p1234 && sleep 5"]
interval: 5s
retries: 10
myapp:
container_name: playheaven-container
build:
context: .
dockerfile: Dockerfile
depends_on:
db :
condition: service_healthy
ports:
- "8080:8080"
Health Check
설정 도중 myapp의 depends_on에 redis를 추가하려 하니 아래의 두 설정 파일처럼 db와 redis 둘 다 health_check를 하거나 둘 다 하지 않아야했음
- 아래 설정 파일을 사용하기 위해서는 redis에도 health check를 하는 설정을 해주어야 함
services:
myapp:
container_name: playheaven-container
build:
context: .
dockerfile: Dockerfile
depends_on:
db :
condition: service_healthy
redis:
condition: service_healthy
ports:
- "8080:8080"
- 아래 설정 파일은 MySQL이 실행되는 동안 Spring에서 DB Connection에 실패하여 Spring Container가 종료 되기 때문에 MySQL이 켜진 뒤 수동으로 시작해줘야하는 번거로움이 있었음
services:
myapp:
container_name: playheaven-container
build:
context: .
dockerfile: Dockerfile
depends_on:
- db
- redis
ports:
- "8080:8080"
- ChatGPT에 의하면 depends_on의 condition : service_health 옵션은 더 이상 Docker compose에서 권장하지 않으며, 최신 버전에서는 지원하지 않는다고 함
- 따라서, healcheck 대신 restart : on-failure 설정을 통해, 실패할 때마다 자동으로 재시작 되도록 하는 것이 일반적인 접근이라고 함
services:
myapp:
container_name: playheaven-container
restart: on-failure
build:
context: .
dockerfile: Dockerfile
depends_on:
- db
- redis
ports:
- "8080:8080"
- 또는 헬스 체크 대신 대기 스크립트를 사용한다고 함
- 예를 들어, wait-for-it.sh 같은 도구를 사용하여 MySQL과 Redis가 준비될 때까지 대기한 후 애플리케이션 기동 가능
728x90
'Docker' 카테고리의 다른 글
Docker compose 설정 및 각종 테스트 (0) | 2024.08.09 |
---|---|
Docker 설치 및 환경 설정 (0) | 2024.08.09 |
Docker란? (0) | 2024.08.08 |
컨테이너 vs 가상머신(VM) (0) | 2024.08.08 |