전체 과정
다음과 같은 순서와 방법으로 진행.
1. SpringBoot프로젝트 내에 Dockerfile 생성 및 작성
2. github 레포지토리에 해당 프로젝트를 push, 이때 gradle에 필요한 파일들도 같이 push
3. ec2서버내에서 해당 레포지토리를 clone 받은 뒤 빌드시켜 jar파일 생성
4. docker compose를 통해 Nginx(리버스 프록시 서버)와 SpringBoot 컨테이너 생성
SpringBoot프로젝트 내에 Dockerfile 생성 및 작성
- 프로젝트 내부에 Dockerfile 생성
FROM openjdk:17-alpine
ARG JAR_FILE=build/libs/LibraryManagement-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} LibraryManagement.jar
ENTRYPOINT ["java", "-jar", "/LibraryManagement.jar"]
- Dockerfile는 최상위 루트 프로젝트 경로에 위치한다. 파일 이름은 Dokcerfile이라고 저장
- FROM 프로젝트에 사용된 java버전에 맞는 jdk 설정
- ARG 키워드는 Argument로 JAR_FILE 변수에 build/libs/LibraryManagement-0.0.1-SNAPSHOT.jar 경로설정
- COPY키워드를 이용해 위에서 할당한 변수명에 맞는 jar파일을 LibraryManagement.jar이름으로 복사 컨테이너 내부로 복사
- ENTRYPOINT는 java를 실행하는 parameter 담기
ec2서버내에서 해당 레포지토리를 clone 받아서 빌드시켜 jar파일 생성
1. ec2서버에 프로젝트 파일 넣기
ec2서버 내에서 github 레포지토리 클론 후 프로젝트 파일 내부로 이동
여기서 주의 할 점은 기본적으로 레포지토리에 gradle관련 파일이 올라가지 않기 때문에 다음 사진과 같이 필요한 파일들을 레포지토리에 푸쉬하거나 ec2에 직접 파일 업로드 프로그램을 사용해서 올려주세요
추가적으로 프로젝트 실행할 때 사용되는 프로젝트이름Application.java도 올려주셔야 합니다
문제 발생 -> 프리티어 AWS EC2서버로는 그래들 빌드를 기본 메모리가 감당하지 못해 인스턴스가 고장나 버림
내부에 실행중인 도커 컨테이너가 모두 종료된 상태에서 다시 빌드하니 성공적으로 빌드
2. jar 파일 생성을 위해 springboot 프로젝트 빌드하기
- 해당 명령어를 통해 gradle을 따로 설치 할 필요 없이 빌드할 수 있는 권한을 준다
chmod +x ./gradlew
- 빌드 명령어
# 테스트 파일 제외하고 빌드하기 위함
./gradlew build -x test
빌드가 성공하게 되면 build / lib 디렉토리에 jar 파일이 생성된 것을 볼 수 있음
docker compose를 통해 Nginx(리버스 프록시)와 SpringBoot 컨테이너 생성
먼저 제가 구성한 컨테이너 구조에 대해 알아보면 총 3개의 컨테이너를 생성할 예정입니다
Nginx(reverse proxy) / SpringBoot / DB
제가 가진 EC2서버에 요청을 보내면 Nginx로 요청을 받고 Nginx에서 SpringBoot로 요청을 전달하는 구조
1. Nginx를 리버스 프록시 서버로 사용하기 위한 설정 파일
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$request_uri" "$uri"'
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# springboot가 실행되는 컨테이너로 접속하는 연결통로를 만들어 준다
upstream spring-boot-api {
server springboot:8080;
}
# nginx에 요청이 들어왔을 때 url에 맞게 라우팅을 위한 목록
server {
# api가 붙으면 여기로
location /api/ {
rewrite ^/api(.*)$ $1 break; # springboot컨테이너로 api제외한 url로 요청을 위해 설정
# 요청을 보낼 업스트림 설정 위에서 설정한 이름으로
proxy_pass http://spring-boot-api;
proxy_redirect off;
# 기본 헤더설정
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
2. 3개의 컨테이너를 한번에 실행 / 관리하기 위한 docker-compose.yml
version: "3"
# services 하위 항목으로 만들 컨테이너 설정
services:
# nginx 컨테이너
nginxproxy:
# nginx컨테이너는 springboot와 db가 연결이 되어야 연결할 수 있는 구조인 것을 명시해준다
depends_on:
- springboot
- db
# 컨테이너를 만들때 사용할 이미지
image: nginx:latest
container_name: proxy
# ec2서버는 http요청시 80포트로 요청 ec2 80포트와 nginx 컨테이너 80포트를 연결
ports:
- "80:80"
restart: always
# 위에서 작성한 nginx.conf 파일을 컨테이너 Nginx 설정에 적용해야하기 때문에 volume을 통해
# ./nginx/nginx.conf 위치의 내가 작성한 conf파일을 nginx컨테이너 내부 /etc/nginx/nginx.conf와 연결해준다
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf"
# springboot 컨테이너
springboot:
depends_on:
- db
# 해당컨테이너를 만들때 사용할 사용자가 만든 도커파일을 사용할때 build 명령 사용
build:
# 도커파일이 존재하는 경로 (위에서 작성한 스프링부트 프로젝트 내부 Dockerfile)
context: ./LibraryManagement
# 파일이름
dockerfile: Dockerfile
expose:
- "8080"
container_name: springboot-api
restart: always
# 저는 springboot yml 파일 암호화를 위해 jasypt를 사용했기 때문에 컨테이너 환경변수 설정
environment:
JASYPT_ENCRYPTOR_PASSWORD: 설정한 암호
# db 컨테이너
db:
build:
dockerfile: Dockerfile_MYSQL
ports:
- "3306:3306"
container_name: mysqldb
volumes:
- "db:/var/lib/mysql"
restart: always
# db이름 계정 암호설정을 위해 environment를 설정해야 하지만 저는 dockerfile에 작성해 빌드했습니다.
# 사용하는 volumes를 명시
volumes:
db:
필요한 파일 작성이 끝나면 docker compose를 통해 컨테이너를 만들면 완료
docker-compose up -d
'Deploy' 카테고리의 다른 글
[Nginx] Nginx 리버스 프록시 (1) | 2023.12.06 |
---|---|
[Nginx] Nginx 기본 웹서버 (0) | 2023.12.02 |
[Docker] Docker Compose 사용법과 주요 명령 (1) | 2023.11.29 |