저번 포스팅에서 Docker에 MariaDB를 설치하고 Dump 파일 실행하기까지 했음
https://dev2som.tistory.com/146
오늘 할 내용의 대략적인 구조도이다^^!
휴 진짜 어려웠다... 도커가 첨이라 개념이 생소하기도 했고ㅠ
담엔 쿠버네티스도 해봐야지
Local에서 작업한 Spring Boot 프로젝트 Docker에 배포하기
= Backend 프로젝트 배포하기
과정 1. Dockerfile을 이용해 Docker Image 생성
1-1. Dockerfile 생성
도커 파일은 도커 이미지를 만들기 위한 여러가지 명령어의 집합이다.
Spring Boot 프로젝트의 루트 > New File > Dockerfile 이라는 이름으로 파일 생성
이런 식으로!
안의 내용은
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
이다.
line 1) openjdk java 8버전의 환경의 이미지를 받는다.
line 2) 빌드 될 때 활용된다. JAR_FILE 변수에 target/*.jar를 담음.
line 3) app.jar에 JAR_FILE을 복사한다.
line 4) 기존 jar 파일을 단순 실행하듯이 "java -jar /app.jar"(jar 파일을 실행하는 명령어)를 실행하면서 스프링부트가 올라간다.
1-2. application.properties 에서 jdbc 관련 부분만 jdbc.properties 파일을 통해 분리한다
AWS EC2 인스턴스는 사용량에 빌링이 되기 때문에, 보안상 jdbc 관련 부분은 따로 관리한다.
(.gitignore에 jdbc.properties를 추가해주면 깃에 올라가지 않는다.)
Spring Boot 메인 클래스
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication
@PropertySource(value = {"classpath:jdbc.properties"})
public class XXXXXX {
public static void main(String[] args) {
SpringApplication.run(XXXXXX.class, args);
}
}
jdbc.properties
spring.datasource.driver-class-name=
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
여기에서 url 부분은 https://anomie7.tistory.com/46 페이지를 참고했다.
1-3. Maven Skip Test
(다음단계인) Maven 패키징 작업(jar 파일 생성)을 할 때, test 소스 때문에 에러가 발생한다.
정확하게는 jdbc.properties에서 AWS EC2의 mariadb-container Docker 컨테이너 안에 있는 DB에 접근하려 하는데, 현재 프로젝트가 Docker에 배포되지도, 컨테이너끼리 연결되어있지도 않으니 나타나는 문제이다.
이 경우 pom.xml에서의 간단한 설정을 통해 Maven 패키징 작업 시 test를 생략해준다.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
1-4. 배포용 jar 파일 생성하기
위의 스크립트에서 target 폴더의 jar 파일을 찾을 것이기 때문에(target/*.jar)
target에 Spring Boot의 jar 파일을 위치시킨다.
내 프로젝트는 Maven이라 mvn package 명령어를 실행해도 되지만 아래와 같은 방법으로 해결했다.
Run as > Maven build
Goals에 package를 입력하고 Run
안될 경우 Workspace...에서 해당 project를 선택하고 다시 Run
잘 생성되었다^^!
과정 2. DockerHub를 이용해 로컬에서 remote Repository로 push
2-1. 프로젝트(내 경우 backend)의 경로에서 cmd창 오픈
2-2. Dockerfile 빌드
프로젝트가 Gradle이냐, Maven이냐에 따라 달라진다. (내 프로젝트는 Maven)
-t 옵션으로 tag를 설정한다.
docker build -t [Docker Hub ID]/[Docker Hub Repository 명] .
도커파일을 빌드하면 이미지가 생성된다.
docker images 명령어를 통해 Local에 이미지가 생성됐는지 확인해볼 수 있다.
2-3. 생성된 이미지를 도커허브 Repository에 push
Docker Hub는 GitHub처럼 remote 저장소를 활용할 수 있다. 미리 가입을 해둔다.
docker push [Docker_Hub_ID]/[Docker_Hub_Repository]
도커 허브에서 확인해보면 아래와 같이 잘 올라와 있는 것이 보인다.
과정 3. AWS EC2 인스턴스에 Spring Boot Docker 컨테이너 만들기
3-1. mariadb-container에서 나온다.
exit
3-2. Docker Hub에 push했던 repository를 AWS EC2 인스턴스에서 pull 받는다.
docker pull [Docker_Hub_ID]/[Docker_Hub_Repository명]
3-3. 잘 도착했는지 확인 (다운로드 받은 이미지 확인)
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
XXXX/backend latest XXXX 6 hours ago 147MB
mariadb latest XXXX 6 days ago 409MB
3-4. Spring Boot Docker 컨테이너 생성 및 실행
docker run --name XXXX-backend-container -d -p 8080:8080 XXXX/backend
아직 도커끼리 연결되어 있지 않기 때문에 오류가 난다.
과정 4. DB 도커 컨테이너와 BE 도커 컨테이너 연결하기
네트워크를 생성하고, 컨테이너끼리 연결시켜 네트워크 안에 속한 컨테이너끼리는 서로 접속할 수 있다.
4-1. 새로운 네트워크 생성
docker network create [네트워크_이름]
4-2. 네트워크 조회
docker network ls
bridge, host, none은 Docker 데몬이 실행되며 기본적으로 실행되는 네트워크다.
대부분의 경우 사용자가 직접 네트워크를 생성해서 사용하는 것이 권장된다.
4-3. 생성한 네트워크에 mariadb-container 컨테이너 연결
docker network connect [네트워크명] mariadb-container
컨테이너 생성 시 --network 옵션으로 명시해주지 않으면 기본적으로 bridge라는 디폴트 네트워크에 붙게 된다.
(참고 : 연결을 해제하고 싶을 떄는 docker network disconnect를 사용하면 된다.)
docker network disconnect [해제하려는_네트워크명] [해제하려는_컨테이너명]
4-4. 네트워크 상세 정보로 연결되었는지 확인
docker network inspect [네트워크명]
잘 추가되어 있다.
4-5. Spring Boot 컨테이너 생성 및 실행
docker run --name XXXX-backend-container -d -p 8080:8080 XXXX/backend
--name : 컨테이너 이름 지정
-d : 백그라운드에서 실행
4-6. Spring Boot 컨테이너도 연결
docker network connect XXXX-network XXXX-backend-container
백엔드 프로젝트까지 연결 완료!
+ 추가
0. backend 코드 상에서 Swagger 설정 해줘야 한다.
외부에서 backend 서버에 접속하여 요청을 날리려면 AWS EC2 상에서 인바운드 규칙을 추가해주어야 한다.
1. AWS 콘솔의 인스턴스 확인 페이지에서 해당 EC2 인스턴스를 선택하고 아래의 보안 탭을 클릭
2. 보안 그룹 클릭!
3. 인바운드 규칙 > Edit inbound rules
외부에서 서버로 인바운드 가능한 ip와 포트번호, 프로토콜을 지정해줄 수 있다.
4. 규칙추가해서 아래처럼 만들어주고 저장하면 된다.
나는 backend(HTTP 프로토콜에, 8080포트)로 들어오는 접근을 허용해주었다.
5. 접속 잘 된다^__^