토이 프로젝트를 생성했는데 AWS에 Docker로 띄우는 방법을 알고 싶어서 찾아보게 되었습니다.
SpringBoot + MySQL + Docker로 띄우는 방법을 처음부터 끝까지 작성된 내용을 찾지 못해서 제가 실행한 방법을 직접 글로 남기게 되었습니다.
여기저기 찾아보고 작성한 내용이기 때문에 부족한 내용이 있을 수 있습니다. 추가되어야 하거나 잘못된 내용이 있다면 알려주세요 :)
우선, Docker로 실행하려는 저의 프로젝트 상세 내용은 아래와 같습니다.
- SpringBoot
- Gradle
- MariaDB
- JPA
- Svelte
1. Docker Hub 가입 및 로그인
Docker Hub(https://app.docker.com/)에 회원가입을 합니다. Github처럼 사용자가 Docker 컨테이너 이미지를 저장, 공유, 관리할 수 있는 클라우드 기반 레지스트리입니다.
자세한 사용방법은 https://velog.io/@arnold_99/Docker-Docker-Hub를 참고하시면 됩니다.
참고로, 제가 만든 이미지를 Docker Hub에 push할 때 requested access to the resource is denied
라는 오류가 발생했습니다. 저는 이미지에 사용자를 추가해주지 않아서 발생한 문제였습니다. 해결방법은 https://velog.io/@eunsilson/Docker-Docker-Hub-push-%EC%8B%A4%ED%8C%A8-requested-access-to-the-resource-is-denied 블로그를 참고하시면 됩니다!
2. Dockerfile 작성
Docker 이미지 생성을 위해 Dockerfile을 추가합니다.
Dockerfile의 위치는 자신의 프로젝트의 최상단입니다. (저는 build.gradle과 같은 위치에 Dockerfile을 추가했습니다.)
Project
| ...
|----- src
|----- gradlew
|----- build.gradle
|----- Dockerfile
| ...
# Gradle 빌드 이미지를 사용해 애플리케이션을 빌드
FROM gradle:7.5.0-jdk17 AS build
WORKDIR /app
COPY . .
RUN gradle clean build --no-daemon
# OpenJDK 17 이미지로 전환하고 JAR 파일 실행
FROM openjdk:17
WORKDIR /app
COPY build/libs/*.jar app.jar
# 애플리케이션 실행
ENTRYPOINT ["java", "-jar", "app.jar"]
# 애플리케이션의 기본 포트(8080)를 노출
EXPOSE 8080
3. SpringBoot Docker 이미지 생성
터미널에서 Dockerfile 위치로 이동한 다음 docker image를 생성합니다.
# docker image 생성
# docker build -t {이미지 이름}:{태그} .
$ docker build -t test-proj:0.1 .
4. 같은 네트워크 사용을 위해 네트워크 생성
# 네트워크 생성
# docker network create {생성할 네트워크 이름}
$ docker network create testProj-net
MySQL과 SpringBoot 프로젝트 컨테이너를 모두 실행시킨 뒤, docker inspect testProj-net
으로 확인했을 때 MySQL과 SpringBoot 모두 같은 네트워크를 사용하고 있어야 합니다.
5. DB (MySQL) Docker 이미지 생성
자신의 프로젝트에서 DB를 사용하는 경우, Docker에 DB용 이미지를 추가해야 합니다.
저는 MariaDB를 사용하기 때문에 MySQL을 추가했습니다. Docker에 MySQL 추가하는 방법은 https://poiemaweb.com/docker-mysql를 참고했습니다.
# MySQL Docker 이미지 다운로드. 태그에 버전을 지정하지 않으면 최신 버전을 다운로드합니다.
$ docker pull mysql
# 생성된 이미지 목록 확인
$ docker images
# MySQL Docker 컨테이너 생성 및 실행
# docker run --name {생성할 컨테이너이름} --network {생성한 네트워크이름} -e MYSQL_ROOT_PASSWORD={DB비밀번호} -d -p 3306:3306 {DB 도커 이미지 이름}:{태그}
$ docker run --name testProj-DB --network testProj-net -e MYSQL_ROOT_PASSWORD=12345 -d -p 3306:3306 mysql:latest
만약 3306 포트를 이미 사용하고 있다면 3307:3306 등으로 수정하면 됩니다.
6. 같은 네트워크로 SpringBoot 이미지와 DB 이미지 띄우기 (Docker run)
DB 이미지로 컨테이너를 생성 및 실행할 때 allowPublicKeyRetrieval=true&useSSL=false
를 url에 추가하지 않았을 때 Public key retrieval is not allowed
오류가 발생했습니다. Mysql 8.0 버전부터는 보안적인 이슈로 useSSL 옵션에 대한 추가적인 설정이 필요해졌습니다. local에서 사용할 때 이런 오류가 발생한다면 아래와 같이 allowPublicKeyRetrieval=true&useSSL=false
옵션을 추가해주면 됩니다. (https://stackoverflow.com/questions/50379839/connection-java-mysql-public-key-retrieval-is-not-allowed)
실제로 서비스할 때는 어떻게 사용할지 추후 알아보겠습니다!
# docker container 생성 및 실행
# --name : 컨테이너 이름 설정
# --network : 네트워크 이름 설정
# -p : 포트 설정
# -e : 환경 변수 설정
# docker run --name {생성할 컨테이너 이름} --network {생성한 네트워크 이름} -p 8080:8080 -e SPRING_DATASOURCE_URL='jdbc:mariadb://{도커 DB 이미지 이름}:3306/{사용할 database 이름}?allowPublicKeyRetrieval=true&useSSL=false' -e SPRING_DATASOURCE_PASSWORD={DB비밀번호} -d {도커이미지이름}:{태그}
$ docker run --name testProj-container --network testProj-net -p 8080:8080 -e SPRING_DATASOURCE_URL='jdbc:mariadb://mysql:3306/projDB?allowPublicKeyRetrieval=true&useSSL=false' -e SPRING_DATASOURCE_PASSWORD=12345 -d test-proj:0.1
SPRING_DATASOURCE_URL에 jdbc:mariadb://localhost:3306/projDB
이 아니라 localhost에 위에서 생성한 DB용 도커 이미지 이름을 넣어주어야 합니다.
7. DB 컨테이너에 자신의 프로젝트에서 필요한 database 생성
새로 DB를 추가했기 때문에 자신의 프로젝트에 맞는 database를 추가합니다.
database를 추가할 때 한글 입력이 안되는 문제를 방지하기 위해서 아래와 같이 추가했습니다.
CREATE DATABASE 데이터베이스명 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
그리고 테이블들을 추가해야 합니다. 제 프로젝트는 필요한 테이블들을 자동으로 추가해주는 설정이 있지만 어떻게 사용하는지 몰라서 손으로 직접 create 해주었습니다...
지금까지 SpringBoot + MySQL + Docker 사용방법을 정리했습니다.
해보면서 아쉬웠던 점들은 찾아보고 다시 시도한 뒤 이 글에 추가할 예정입니다!! 😎
추가로 시도해 볼 내용
- application.yml을 외부로 분리해서 사용하는 방법
- docker-compose.yml 사용방법
'Study😜' 카테고리의 다른 글
CSRF(Cross-Site Request Forgery) (1) | 2025.01.24 |
---|---|
Spring Security에서 WebSecurityConfigurerAdapter가 Deprecated된 이유와 새로운 구성 방법 (0) | 2024.12.28 |
AWS lambda에 Springboot 프로젝트를 Docker로 배포하기 (0) | 2024.09.07 |
Blocking/Non-blocking, Sync/Async 차이 (0) | 2024.07.07 |
Redis (Remote Dictionary Server) (0) | 2024.05.19 |