지난글:
https://cooookieeee.tistory.com/46
서버는 AWS 인스턴스를 할당받아 SSH를 통해 서버에 접속에 성공했다.
다음은 서버를 웹 서버,웹어플리케이션 서버,DB 서버로 나누어 분리 배포하기 위해 Docker를 사용했다.
Docker를 사용한 이유:
- 추후 Docker Swarm을 통해 인스턴스(Worker Node) 추가 간편화
- 빠른 배포
- 서비스 연속성 보장( One Service - Many Container )
- 컴퓨터 자원 효율적 사용
[Docker 환경 구축]
목적: 상기와 같음
-1. Docker install
sudo apt update
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
-2. Docker compose install
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version
[Docker Compose.yml, nginx.conf, Dockerfile 작성]
목적: nginx - springboot -db 서버 형식으로 배포하기 위함
방법:
- 1. Docker Compose.yml (컨테이너 서비스와 볼륨,네트워크에 대한 총괄 설정 )
version: '3.8'
services:
nginx: #nginx 관련하여 컨테이너 설정
image: nginx:latest #nginx 이미지
container_name: nginx_container # 비필수
ports:
- "80:80" # 호스트의 포트와 컨테이너의 포트포워딩
volumes:
- /home/ubuntu/my_project/nginx/nginx.conf:/etc/nginx/nginx.conf:ro # Bind volume 형식으로 호스트의 nginx.conf와 컨테이너 nginx.conf를 mount
depends_on:
- springboot # springboot 컨테이너 서비스가 먼저 만들어지고 생성
networks: #사용할 네트워크 지정
- starbucks_network_02 # 네트워크를 통해 컨테이너끼리 소통
springboot:
image: my-springboot_v2:latest # Dockerfile를 기반으로 이미지 생성
container_name: springboot_container
stdin_open: true # -i 옵션 활성화
tty: true # -t 옵션 활성화
command: /bin/bash # 기본 명령어
ports:
- "8080:8080" # 포트 개방
volumes:
- /home/ubuntu/my_project/env.properties:/app/be/env.properties # Bind volume (계정 정보 파일)
- /home/ubuntu/my_project/shell2:/app/be/shell2 # Bind volume (CI/CD를 위해 테스트용)
environment:
- SPRING_PROFILES_ACTIVE=prod # Spring Boot 프로파일 설정
depends_on:
- db # 생성 순서 지정
networks:
- starbucks_network_02
db:
image: mysql:8.0 #DB 이미지(Mysql)
container_name: mysql_container
restart: always: 컨테이너에 문제가 생겼을 시 재시작
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/ROOT_PASSWORD #도커 시크릿 경로
MYSQL_DATABASE_FILE: /run/secrets/DATABASE
MYSQL_USER_FILE: /run/secrets/USERNAME
MYSQL_PASSWORD_FILE: /run/secrets/PASSWORD
secrets:
- ROOT_PASSWORD # 사용할 도커 시크릿
- DATABASE
- USERNAME
- PASSWORD
ports:
- "3306:3306" # 포트 개방
volumes:
- db_data:/var/lib/mysql # db_data라는 도커 볼륨을 통해 컨테이너가 삭제되도 DB 정보가 남아있게 설정
networks:
- starbucks_network_02
volumes: #볼륨 설정
db_data:
secrets: #도커 시크릿 설정
ROOT_PASSWORD:
external: true #외부
DATABASE:
external: true
USERNAME:
external: true
PASSWORD:
external: true
networks:
starbucks_network_02:
driver: overlay #오버레이 형식으로 네트워크 구성
-2.nginx.conf (nginx 웹 서버 설정)
events {
worker_connections 1024;
}
http {
server {
listen 80; # 80 포트로 들어오는 inbound 처리
location / {
proxy_pass http://springboot:8080; # inbound를 프록시 형태로 전달 이때 DNS는 도커 DNS로 서비스이름
proxy_set_header Host $host; #헤더 설정
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
-3. Dockerfile( 스프링부트 이미지 생성)
-호스트에서 미리 빌드 시 (빠른 container 생성)
# 호스트에 빌드 후 도커에 jar 파일만 전달 시#
FROM eclipse-temurin:17-jre # jar 파일을 실행시킬 환경 image 사용
WORKDIR /app/be # 디렉토리 변경
COPY app/be/build/libs/be-0.0.1-SNAPSHOT.jar . #호스트에 있는 jar 파일 현재 workdir에 전달
#CMD ["bash", "-c", "tail -f /dev/null"] # 잘 전달됐는지 확인하기 위해 컨테이너 유지용 명령
ENV SPRING_PROFILES_ACTIVE=prod # 운영 환경으로 전환
EXPOSE 8080 # 8080 포트로 들어올 시 서비스를 제공할 수 있도록 설정
ENTRYPOINT ["java", "-jar", "be-0.0.1-SNAPSHOT.jar"] # jar파일 실행 (서비스 실행)
-컨테이너에서 직접 빌드 시
# 베이스 이미지 (빌드 단계)
FROM eclipse-temurin:17-jdk AS builder # build하기 위한 환경 구축
WORKDIR /app #workdirectory 변경
RUN apt-get update && apt-get install -y git && apt-get clean #git 설치
RUN git clone https://github.com/dopamingu/be.git # 프로젝트 클론
WORKDIR /app/be #workdirectory 변경
RUN chmod +x ./gradlew #build 파일에 접근할 수 있도록 허용
RUN ./gradlew build -x test #build 진행
# 런타임 이미지
FROM eclipse-temurin:17-jre #런타임용 가벼운 환경으로 전환(jar파일 실행용)
WORKDIR /app #workdirectory 변경
COPY --from=build /app/build/libs/*.jar app.jar #build한 jar파일을 컨테이너의 app.jar로 옮김
ENV SPRING_PROFILES_ACTIVE=prod # 운영 환경으로 전환
EXPOSE 8080 # 8080포트로 들어올 시 서비스 제공
ENTRYPOINT ["java", "-jar", "app.jar"] # 서비스 실행
[Docker Image build]
목적: Dockerfile의 설정대로 컨테이너가 생성될 수 있게 이미지를 빌드한다.
방법:
1.Dockerfile이 위치한 디렉터리로 이동
2.Build 명령어 실행
docker build -t <이미지 이름>:<태그> .
3.Docker Image가 잘 생성되었는지 확인
sudo docker images
[Docker compose로 도커 서비스 생성]
목적: 기존에 작성했던 docker-compose.yml 파일을 토대로 서비스를 생성한다.
방법:
1. docker-compose.yml이 있는 directory로 이동
2. Docker compose 명령어를 통해 컨테이너 및 기타 자원들 생성
docker-compose up -d
3. Docker ps를 통해 서비스가 잘 생성 및 구동되는지 파악
sudo docker ps
이슈 트러블 슈팅:
1. JPA Hibernate가 연결 안되는 이슈
- 원인: 1. application-prod.yml에서 jpa 구문을 추가 하지 않았음
2. application-prod.yml에서 jpa 구문을 추가 시 indent를 지키지 않았음
- 해결방법:
1. DB server 생성 후 env.properties의 정보들이 환경변수로 지정되어 있는지 확인( 잘 적용되어 있었음 )
2. 정상적인 application-prod.yml 파일로 변경 (jpa section 추가 및 spring.config 하위로 indent 처리)
spring:
config:
import:
file:env.properties
activate:
on-profile: prod
datasource:
url: jdbc:mysql://${MYSQL_HOST}:3306/${MYSQL_DB_NAME}
username: ${MYSQL_USERNAME}
password: ${MYSQL_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
show_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect
logging:
level:
root: WARN
2. Docker Image가 생성 안되는 이슈
- 원인: 스토리지 공간 부족
- 해결방법: EBS 용량 최대로 증가(프리티어시 30GB)
3. Dockerfile에서 directory를 찾을 수 없는 이슈
- 원인: COPY --from=build /app/build/libs/*.jar app.jar 구문에서 " *.jar "로 설정 시 찾을 수가 없음 정확한 파일명 입력
- 해결방법: 직접 생성된 jar 파일 명 입력 및 실행
COPY app/be/build/libs/be-0.0.1-SNAPSHOT.jar .
ENTRYPOINT ["java", "-jar", "be-0.0.1-SNAPSHOT.jar"]
4. 호스트 환경에서 빌드가 안되는 이슈
- 원인: 1.gradle이 env.properties를 찾지 못해서 빌드가 안됨, gradle 자체를 찾아오지 못함
2.javac(compiler)를 찾지 못하는 이슈
- 해결방법: 1.application-prod의 spring.config.import 부분이 " file:properties "로 되어있는데,
경로가 잘 못 되어서 찾지 못하는 거였음 - build하는 현재 경로 기준으로 파일 배치
2. open jdk 17 재설치
참조:
-Docker composer 다운: https://zzom.co.kr/182
'Dopamingo(연애 커뮤니티) 프로젝트 > 프로젝트' 카테고리의 다른 글
3.3 Make AI로 CI/CD 만들기 (0) | 2024.12.18 |
---|---|
3.1 AWS 인스턴스 생성 및 설정 (1) | 2024.12.16 |
1.0 초기 설정 및 기획 (4) | 2024.11.18 |