프론트와의 통신을 테스트 하기 위해서 테스트용 Spring Server, MySQL Database, redis를 도커를 통해서 손쉽게 관리하기 위해 DockerFile과 docker-compose를 설정하였다.
DockerFile은 gradlew를 통한 jar 파일 생성을 자동화 하는 역할을 한다.
그리고 copy를 통해 volume에 저장하여 재빌드시 cache 데이터를 이용해 속도를 단축시킬 수 있다.
FROM adoptopenjdk/openjdk11 AS builder #베이스 이미지 + 별칭
COPY gradlew . #gradlew 복사
COPY gradle gradle #gradle 복사
COPY build.gradle . #build.gradle 복사
COPY settings.gradle . #settings.gradle 복사
COPY src src #웹어플리케이션 소스 복사
RUN chmod +x ./gradlew #gradlew 실행 권한 부여
RUN ./gradlew bootJar #gradlew를 통해 실행 가능한 jar파일 생성
FROM adoptopenjdk/openjdk11 #베이스 이미지 생성
COPY --from=builder build/libs/*.jar app.jar #build이미지에서 build/libs/*.jar 파일을 app.jar로 복사
ENTRYPOINT ["java", "-jar", "/app.jar"] #jar 파일 실행
VOLUME /tmp #볼륨 지정
docker-compsoe.yml을 도커 이미지를 생성하고, 해당 이미지들의 컨테이너를 실행하는 역할을 한다.
version: "3" #docker version 3 사용
services: #service들 정의
database: #service 이름
image: mysql #불러올 image
container_name: starbucks_db_test #container 이름 지정
environment: # 환경 설정
- MYSQL_DATABASE=starbucks_db_test
- MYSQL_ROOT_HOST=%
- MYSQL_ROOT_PASSWORD=1234
ports: #port 지정
- 3306:3306
volumes: #볼륨 지정
- ./db/data:/var/lib/mysql
networks: #사용할 네트워크 지정
- starbucks_network_02
webapp:
build: #image를 DockerFile 기반으로 사용한다
context: . #DockerFile이 있는 디렉토리
dockerfile: Dockerfile #기존에 설정해둔 DockerFile을 지정히여 build 된 jar 파일을 container에 올린다.
restart: always #컨테이너 재실행
depends_on: #database service가 실행된 이후에 실행
- database
ports:
- 8081:8081
container_name: app_test01
environment: #환경 설정(database연결 및 profile 지정)
SPRING_DATASOURCE_URL: jdbc:mysql://database:3306/starbucks_db_test?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 1234
SPRING_PROFILES_ACTIVE: dev #사용할 profile 지정
networks:
- starbucks_network_02
redis:
image: redis:alpine
command: redis-server --port 6379
container_name: redis_boot
hostname: redis_boot
labels:
- "name=redis"
- "mode=standalone"
ports:
- 6379:6379
networks: #네트워크 설정
starbucks_network_02:
※ networks를 통해서 db와 server를 같은 network로 묶어줘야 한다.
$: docker-compose build
docker-compose.yml에서 설정한 image 파일들을 생성
volume에 저장된 데이터 cache를 통해서 build 시간을 단축시킬 수 있다.
$: docker-compose up
image 파일들을 container에 올리며 실행
다음과 같이 backend(프로젝트 폴더 이름)에 3개의 컨테이너가 묶여서 동작하는 것을 알 수 있다.
$: docker-compose stop #실행 중인 docker container 중단
$: docker-compose start #중단 된 docker container 실행
docker-compose up을 통해 container를 올려놓으면 위의 명령어들을 통해서 container들을 손쉽게 관리할 수 있다.
Intellij에서 실행한 Spring Server는 외부에서 접근이 가능했지만 Docker를 통해 실행한 Spring server는 외부에서 접근이 불가능한 이슈가 발생했다.
검색 결과 방화벽에서 해당 포트를 열어주지 않아서 외부에서 접근이 불가능하다는 것이었다.
인바인드 규칙을 새로 설정해주면 된다.
방화벽 - 고급 설정 - 인바인드 규칙 - 새규칙
Intellij에서는 실행되는데 docker에서 실행되지 않는 것 때문에 docker 설정을 잘못 해줬다고 생각했지만 Intellij에서는 local profile로 실행해서 8080 포트에서 실행되는데 8080는 허용되어 있었는데 8081 포트는 허용되어 있지 않아서 발생한 문제였던 것 같다.
해당 코드를 적용해본 결과, mysql 컨테이너를 실행할 때 permision 거부되어 컨테이너가 실행하지 않고 spring 컨테이너만 동작하게 됩니다 이 경우는 해결할 수 있는 방법이 없을까요?