[quantHelper] 서버 배포
11일차
✏️ 서버 배포 하는 법
- AWS EC2 인스턴스 생성
- 해당 인스턴스에 Elastic IP 할당
- 즉시 인스턴스와 연결 해야한다! 안하면 과금된다.
- Gabia에서 Domain 구매
- quant-Helper.online을 1년치 구매했다.
- 8080 포트로 접속해야 하기 때문에, quant-Helper.online:8080으로 들어가야 한다.
- 구매한 Domain을 Route 53에 등록
- 인스턴스에 SSH로 접속
- 인스턴스에 docker, docker-compose 인스톨
- git clone으로 프로젝트 땡겨온 다음, docker-compose up -d로 실행
- application-prod.yml 파일을 추가해주어야 한다!
✏️ Docker
■ Dockerfile
Docker 이미지를 빌드하기 위한 명령어들을 작성한 파일이다.
- 반드시 D는 대문자이어야 한다.
- 이미지 설정, 의존성 설치, 환경 변수 설정 등 애플리케이션 실행에 필요한 모든 단계를 명시해야 한다.
■ Docker 이미지
Docker 컨테이너를 실행하는 데 필요한 모든 파일과 설정을 포함한 패키지
- 【 Docker 이미지 - 컨테이너 】 를 【 클래스 - 객체 】 관계로 생각하면 이해하기 쉽다.
- 이미지는 생성 후 변경되지 않는다. 변경이 필요한 경우 새로운 이미지를 빌드해야 한다.
이미지를 빌드하기 위해서는, Dockerfile이 존재하는 디렉토리에서 다음 명령을 실행하면 된다.
1
docker build -t [이미지 이름]:[태그] .
빌드한 이미지로 컨테이너를 실행할 수 있다.
1
2
3
docker run -d -p 4000:80 --name mycontainer myimage:tag
// -p 4000:80: 호스트의 4000 포트와 컨테이너의 80 포트를 연결.
// 이는 외부에서 컨테이너의 80 포트에 접근할 때 사용한다.
■ docker-compose
Docker Compose는 여러 컨테이너를 동시에 구성하는데 사용되는 도구로, docker-compose.yml 파일을 통해 서비스, 네트워크, 볼륨 등을 정의한다.
- 이 파일에 서비스를 설정함으로써 여러 컨테이너를 함께 쉽게 시작하고 연동할 수 있다.
다음은 현재 개발중인 프로젝트의 docker-compose.yml 파일이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
services: # 실행할 모든 컨테이너 서비스를 정의한다.
postgres: # 첫번째 서비스의 이름
image: postgres:16 # 이 서비스가 사용할 도커 이미지, Docker Hub에서 제공한다.
container_name: postgres
environment: # 컨테이너 내에서 사용할 환경변수
POSTGRES_USER: cluster23
POSTGRES_PASSWORD: cluster23
POSTGRES_DB: quant-helper
ports: # 호스트 머신(이 컨테이너를 담고 있는 PC) - 컨테이너간의 포트 매핑
- "5432:5432"
volumes: # 데이터를 영구적으로 저장하기 위한 볼륨
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
api: # 두번째 서비스의 이름
build: # Docker 이미지를 빌드하기 위한 설정
context: .
dockerfile: ./docker/api/Dockerfile
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/quant-helper
SPRING_DATASOURCE_USERNAME: cluster23
SPRING_DATASOURCE_PASSWORD: cluster23
container_name: api
ports:
- "8080:8080"
depends_on: # api 서비스가 실행되기 이전에 postgres 서비스가 먼저 실행되어야 한다.
- postgres
networks: # backend 네트워크에 연결한다.
- backend
networks: # backend network는 driver로 bridge를 사용한다.
backend:
driver: bridge
volumes: # postgres_data 볼륨 정의
postgres_data:
volumes
docker는 가상화 환경인 컨테이너에서 작업을 진행한다. 따라서, 모든 데이터는 컨테이너 내부에만 존재하게 된다. ➜ 컨테이너를 삭제하면 작업한 모든 데이터가 날라간다.
컨테이너가 삭제되어도 데이터를 유지하고 싶은 경우에 사용하는 것이 volume이다. volume은 데이터를 외부로 링크하는 기능이다.
위의 경우, postgres 서비스의 데이터는/var/lib/postgresql/data에 저장된다.
network
도커의 네트워크란 Docker 컨테이너 간의 통신을 관리하고 격리하기 위한 기능이다.
✏️ DB - APP 컨테이너 연결
지금 Docker에는 2가지의 서비스가 존재한다.
- postgres
- api
이 두개의 컨테이너를 연결하기 위해서는 수정해줘야 할 사항들이 몇가지 존재한다.
application.yml에서url: jdbc:postgresql://postgres:5432/quant-helper로 수정- 원래는 localhost의 5432 포트에서 동작했다.
- postgres 컨테이너와 api 컨테이너의 통신을 할 때는 localhost를 쓰면 안된다.
- api service에서 db를 접속하기 위한 환경 변수 설정
-
1 2 3 4
environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/quant-helper SPRING_DATASOURCE_USERNAME: cluster23 SPRING_DATASOURCE_PASSWORD: cluster23
-
✏️ 오류
현재 Dockerfile이 존재하는 위치는 다음과 같다.
Dockerfile은 다음과 같이 작성했다.
FROM gradle:jdk17 AS build WORKDIR /app COPY –chown=gradle:gradle . /app RUN gradle build –no-daemon
FROM openjdk:21-slim WORKDIR /app COPY –from=build /app/build/libs/*.jar /app/spring-boot-application.jar ENTRYPOINT [“java”,”-jar”,”/app/spring-boot-application.jar”]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<br>
Stage 1
- Base Image: gradle:jdk17를 사용하여 Gradle과 JDK 17을 포함한 환경에서 시작
- Working Directory: /app 폴더를 작업 디렉토리로 설정 (없으면 자동 생성)
- Copy: 현재 디렉토리의 모든 파일을 작업 디렉토리 /app에 복사하고, 소유권을 gradle 사용자에게 부여
- Build Command: gradle build --no-daemon 명령으로 애플리케이션을 빌드
<br>
Stage2
- Working Directory: /app 폴더를 작업 디렉토리로 설정
- Copy: Stage 1에서 생성된 JAR 파일을 /app 폴더로 복사합니다.
- Entrypoint: JAR 파일을 실행하는 커맨드를 설정합니다.
<br>
### 1. Directory 위치 오류
>```Directory '/app' does not contain a Gradle build```
```Dockerfile```은 현재 api 폴더 내에 존재한다.
따라서, api 폴더 내에서 Docker를 빌드 했더니 위와 같은 오류가 발생했다.
Dockerfile이 위치한 디렉토리에서 빌드를 실행하면, <span style = "color:red">이 경로가 기본적으로 빌드 컨텍스트가 된다.</span>
➜ ```COPY --chown=gradle:gradle . /app``` 명령이 실행되지 않는다.
따라서, 위치를 루트로 바꾼뒤에 실행해야한다.
cd /Users/Ruffles/Downloads/quantHelper docker build -t api -f docker/api/Dockerfile .
1
2
3
4
<br>
### 2. Docker build 오류
22 StockTest > testSaveStock() FAILED 58.22 java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:180 58.22 Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1786 58.22 Caused by: liquibase.exception.DatabaseException at SpringLiquibase.java:288 58.22 Caused by: org.postgresql.util.PSQLException at ConnectionFactoryImpl.java:354 58.22 Caused by: java.net.UnknownHostException at NioSocketImpl.java:572 ```
docker-compose up -d를 사용했더니 계속해서 이런 오류가 발생했다.
처음에는 postgresql이랑 연결이 잘못된줄 알고 Dockerfile과 docker-compose 파일을 계속 수정했는데, 결론은 이거였다.
test 폴더 내부에는 application.yml이 존재하지 않는다.
따라서, test를 제외시켜줘야 빌드가 수행된다.
Dockerfile에 RUN gradle build --no-daemon -x test를 추가했더니 해결되었다.