[Springboot] DockerFile, docker-compose를 통한 도커 컨테이너 배포/외부 접근 허용 (with Gradle)

송진영·2023년 3월 12일
3

Springboot

목록 보기
6/9

개요

프론트와의 통신을 테스트 하기 위해서 테스트용 Spring Server, MySQL Database, redis를 도커를 통해서 손쉽게 관리하기 위해 DockerFile과 docker-compose를 설정하였다.

DockerFile 설정

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-compose.yml

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들을 손쉽게 관리할 수 있다.

Docker 외부 접근 이슈

발단

Intellij에서 실행한 Spring Server는 외부에서 접근이 가능했지만 Docker를 통해 실행한 Spring server는 외부에서 접근이 불가능한 이슈가 발생했다.

원인

검색 결과 방화벽에서 해당 포트를 열어주지 않아서 외부에서 접근이 불가능하다는 것이었다.

해결

인바인드 규칙을 새로 설정해주면 된다.
방화벽 - 고급 설정 - 인바인드 규칙 - 새규칙

회고

Intellij에서는 실행되는데 docker에서 실행되지 않는 것 때문에 docker 설정을 잘못 해줬다고 생각했지만 Intellij에서는 local profile로 실행해서 8080 포트에서 실행되는데 8080는 허용되어 있었는데 8081 포트는 허용되어 있지 않아서 발생한 문제였던 것 같다.

profile
못하는 건 없다. 단지 그만큼 노력을 안 할 뿐이다.

1개의 댓글

comment-user-thumbnail
2023년 11월 25일

해당 코드를 적용해본 결과, mysql 컨테이너를 실행할 때 permision 거부되어 컨테이너가 실행하지 않고 spring 컨테이너만 동작하게 됩니다 이 경우는 해결할 수 있는 방법이 없을까요?

답글 달기