내가 두고두고 쓰는 Docker 설정들 총 정리 (EC2 & NginX & SpringBoot & MySQL)
Kotlin SpringBoot 백엔드를 개발하고 있습니다.
이제 EC2에 배포하기 위해서 프리티어 계정을 생성하였고, EC2를 생성했습니다.
EC2 생성 시 Amazon Linux 2 를 사용했고, 프리티어는 30GB 볼륨까지 사용할 수 있으므로 그렇게 지정해줍니다.
Nginx가 80 포트로 다뤄질 것이므로, 인바운드 규칙으로 80포트도 열어줍니다.
원래는 Docker를 활용함에 있어서, SpringBoot 서버 jar 파일을 image 화 시킨 뒤에, Docker Hub에 올려주고
EC2에서 이 Docker Hub에 접속해야 하는데, Docker Hub는 Private 저장소를 사용하려면 유료 요금을 지불해야 합니다.
또한 git 역시 저는 private repository로 진행하고 있기 때문에, scp 를 이용해서 jar 파일 자체를 EC2로 업로드해줍니다.
scp -i 키.pem 옮길파일 EC2유저명@IP:/경로
EC2에 Docker와 Docker-compose를 설치하는 것도 잊지 말아야 합니다.
그리고 mysql 과 nginx 도 docker를 이용해서 이미지를 받아주세요.
이에 대한 자세한 내용은 이전에 작성했던 글을 참고하시면 됩니다.
그러면 이제 EC2에 jar이 올라와 있고, docker, mysql image, nginx image가 설치되어 있습니다.
jar 또한 image로 만들어줘야 하지만 이 또한 docker-compose로 세팅해줍니다.
docker-compose를 이용해서 mysql 컨테이너와 nginx 컨테이너 실행 시 환경설정 또한 진행시켜줄 수 있습니다.
Dockerfile
jar를 docker image로 만들어줄 Dockerfile입니다.
FROM openjdk:17-jdk-alpine
COPY mcbe-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
docker-compose.yml
docker container를 실행하기 위한 설정과, 각 docker container들의 소통 방식에 대한 정의입니다.
version: '3'
services:
mysql:
image: mysql
container_name: mysql-container
restart: always
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=설정할 비밀번호
- MYSQL_DATABASE=생성할 DB명
- MYSQL_CHARSET=utf8mb4
- MYSQL_COLLATION=utf8mb4_unicode_ci
volumes:
- /home/ec2-user/mysql:/var/lib/mysql
- /home/ec2-user/mysql-options/my.cnf:/etc/mysql/my.cnf
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
springboot:
build: .
container_name: my-api-container
ports:
- "8080:8080"
depends_on:
- mysql
restart: always
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/생성할 DB명?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&serverTimezone=Asia/Seoul
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=설정한 비밀번호
nginx:
image: nginx
container_name: nginx
restart: always
ports:
- "80:80"
volumes:
- /home/ec2-user/nginx-options/nginx.conf:/etc/nginx/conf.d/default.conf
주의 깊게 보면 좋은 곳은
mysql의 volumes입니다.
도커 컨테이너는 휘발성으로, 도커 자체가 언제든 실행하고 없애버릴 수 있는 간편함의 장점을 갖고 있습니다.
볼륨을 따로 설정해주면 컨테이너를 삭제해도 데이터를 유지할 수 있습니다.
아래 부분이 바로, container의 /var/lib/mysql 에 있는 db 저장소를
호스트의 /home/ec2-user/mysql 폴더 안과 동기화시키겠다는 것입니다.
- /home/ec2-user/mysql:/var/lib/mysql
그래서 저는 /home/ec2-user 디렉터리에 mysql 빈 폴더를 미리 만들어놨습니다. 앞으로 이곳에 DB 정보들이 저장되어, 컨테이너가 삭제되어도 데이터를 보존할 수 있습니다.
또한 아래와 같은 코드는, 제가 mysql-options/my.cnf 에 mysql 설정 파일을 작성해놨고, 이를 /etc/mysql.my.cnf 에 마운트하겠다는 말입니다.
- /home/ec2-user/mysql-options/my.cnf:/etc/mysql/my.cnf
한글이 깨지지 않도록 설정을 작성해놨습니다.
mysql-options/my.cnf
[mysql]
default-character-set=utf8mb4
[client]
default-character-set=utf8mb4
[mysqld]
init_connect='SET collation_connection = utf8mb4_unicode_ci'
init_connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
이와 비슷하게 nginx에도 설정 파일을 작성해놨고, 이를 컨테이너에서 쓰이는 파일에 마운트해놨습니다.
- /home/ec2-user/nginx-options/nginx.conf:/etc/nginx/conf.d/default.conf
nginx-options/nginx.conf
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://my-api-container:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
이렇게 설정을 모두 마친 뒤에
jar, Dockerfile, docker-compose.yml 파일이 있는 곳에서 아래 명령을 입력합니다.
docker-compose build
이렇게 되면 springboot의 이미지가 생성됩니다.
이제 모든 것을 실행하겠습니다.
docker-compose up
데몬으로(백그라운드) 실행하려면 -d 옵션을 붙여주면 됩니다.
종료할 때에는 (도커 컨테이너도 삭제) 아래와 같이 입력해주면 됩니다.
docker-compose down
디렉터리 구조는 최종적으로
.
├── 프로젝트명 폴더
│ ├── Dockerfile
│ ├── docker-compose.yml
│ └── 0.0.1-SNAPSHOT.jar
├── mysql
├── mysql-options
│ └── my.cnf
└── nginx-options
└── nginx.conf
이렇게 됩니다. mysql 폴더에는 알아서 mysql 데이터들이 향후 저장되게 됩니다.
도움이 되셨길 바랍니다.