일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- JWT
- DevOps
- CI/CD
- springboot
- JPA
- 프로그래머스
- Java
- docker
- 테스트 코드
- Kafka
- AWS
- trouble shooting
- Redis
- swagger
- Til
- 유효성 검사
- Github Actions
- spring boot
- rabbitmq
- querydls
- MSA
- 아키텍처
- EC2
- 멀티 모듈
- 어노테이션
- Intellij
- aop
- testcode
- 객체지향원칙
- algorithm
- Today
- Total
개발노트
25.02.28 GitHub Actions(CI / CD)와 Docker로 AWS에 자동 배포하기 (1) 본문
개요
이번 팀프로젝트에서 Docker와 Nginx ,GitHub Actions를 사용해 무중단 배포를 했었다.
팀원중에 배포를 담당하시는 분이 모든 걸 맡아 진행하셨다. 나는 인프라적인 지식이 부족해 도움이 되지못했다.
다음 프로젝트가 시작되기전에 부족한 부분을 채워둘려고 GitHub Actions 와 Docker로 AWS로 배포하는 법을 학습해보고 기록해보려한다.
1. EC2 서버 준비
1 - 1. 주요 인스턴스 설정
Ubuntu는 오픈 소스로 제공되며 라이선스 비용이 없어, 개인 개발자도 부담 없이 사용할 수 있다.
또한, 가벼운 OS로 EC2의 리소스를 효율적으로 활용할 수 있도록 최적화되어 있으며, 특히 Ubuntu Server 버전은 GUI 없이 최소한의 패키지만 포함하고 있어 성능과 보안 측면에서 유리하다.
AWS에서는 LTS(Long Term Support) 버전을 공식 지원하며, 보안 업데이트를 제공해 안정적인 운영이 가능하다.
뿐만 아니라, Docker, Kubernetes, Python, Java 등 다양한 개발 환경을 구축하기에 적합하며, Docker 공식 문서에서도 Ubuntu를 가장 많이 사용되는 OS로 권장할 만큼 컨테이너 환경에 최적화되어 있다.
또한, SSH를 통해 원격으로 쉽게 접근할 수 있어 서버 관리가 편리하기 때문에, 나는 Ubuntu를 사용해보려고 한다.
1 - 2. 인스턴스 유형 설정
AWS 프리티어에서 최대 12개월 동안 매월 750시간 정도 무료로 제공되는 t2.micro를 선택했다.
유료로 사용하더라도 시간당 요금이 가장 저렴한 편이라 개인 개발자가 부담 없이 사용하기가 좋다.
성능이 높은 인스턴스는 아니지만 나한테는 충분하다.
1 - 3. 키 발급받기
RSA 알고리즘은 공개 키 암호화 방식중하나로 AWS, SSH, SSL/STL 인증서 등에서 널리 사용될만큼 신뢰성이 높은 알고리즘이다. AWS EC2에서는 기본적으로 RSA 키 페어를 지원하며 대부분의 SSH 클라이언트와 호환성이 좋다.
RSA는 안정적이고 보안성이 뛰어나며, AWS 및 SSH 환경에서 널리 사용되는 공개 키 암호화 방식이기 때문에 선택
.pem 파일은 OpenSSH 및 AWS에서 기본적으로 지원하는 키 형식이다. Linux 및 macOS 환경에서 .pem 파일을 그대로 사용하여 SSH 접속이 가능하다. 또 AWS EC2 SSH 접속 시 추가 변환 없이 바로 사용할 수 있는 장점이 있다.
.ppk처럼 다른 형식을 사용하면 변환 작업이 필요하다.
.pem 형식은 AWS 표준 프라이빗 키 형식이며, 추가 변환 없이 SSH 접속이 가능하고 관리가 용이하기 때문에 사용
❗❗❗ 생성된 키 페어는 상당히 중요하니 꼭 잃어버리지않게 잘 관리해야한다❗❗❗
1-4. 네트워크 설정
이제 모든 설정이 완료되었으니, 인스턴스 시작 버튼을 눌러 서버 구매를 완료하자.
2. 배포할 프로젝트에 Dockerfile 생성
1. 로컬 PC에서 Docker 설정하기
1 - 1. Dockerfile 명령어 정리
Dockerfile을 작성하기전에 주요 명령어들을 정리하려한다.
지시어 | 설명 |
FROM | 베이스 이미지 지정 |
LABLE | 이미지에 메타데이터 추가 |
ENV | 환경 변수 설정 |
WORKDIR | 작업 디렉터리 변경 |
COPY | 로컬 파일을 컨테이너로 복사 |
ADD | 파일 복사 + 압축 해제 가능 |
RUN | 컨테아너 내부에서 명렁어 실행 |
CMD | 컨테이너 실행 시 기본 실행 명령어( 변경 가능 ) |
ENTRYPOINT | 컨테이너 실행 시 고정 실행 명령어 ( 변경 불가 ) |
EXPOSE | 컨테이너가 사용할 포트 지정 |
VOLUME | 데이터 유지 ( 볼륨 마운트 ) |
ARG | 빌드 시 환경 변수 설정 |
HEALTHCHECK | 컨테이너 상태 확인 |
USER | 컨테이너 내 실행할 사용자 설정 |
ONBUILD | 부모 이미지에서 후속 빌드 시 실행할 명령어 |
STOPSIGNAL | 컨테이너 종료 시 사용할 신호 지정 |
SHELL | 기본 실행할 셀( shell ) 변경 |
MULTI-STAGE | 멀테스테이지 빌드를 사용하여 최적화 |
1 - 2. Spring Boot - Dockerfile 생성 및 설정
# Dockerfile
# JDK 17 기반의 경량화된 이미지 사용
FROM openjdk:17-jdk-slim
# 작업 디렉터리 설정
WORKDIR /app
# 인자 설정 - JAR_File
ARG JAR_FILE=build/libs/*.jar
# JAP 파일 복사
COPY ${JAR_FILE} app.jar
# 컨테이너 실행 명령어
ENTRYPOINT ["java", "-jar", "app.jar"]
FROM : 도커 이미지의 기본(Base) 이미지를 설정한다.
openjdk:17-jdk-slim 은 OpenJDK의 공식 Docker 이미지 이며 slim 버전은 불필요한 패키지를 제거한 경량화된 버전으로,
컨테이너 크기를 줄여 성능을 향상시킨다.
WORKDIR : 컨테이너 내부에서 사용할 작업 디렉터리( 기본 폴더 )를 설정한다.
이후의 모든 파일 복사( COPY ) 및 실행 ( ENTRYPOINT ) 명령어는 /app 디렉터리에서 실행된다
디렉터리는 미리 생성할 필요 없이 자동 생성된다.
ARG : Docker 이미지 빌드 시 사용되는 빌드 시점 변수이다.
JAR_FILE=build/libs/*.jar 는 Spring Boot 프로젝트에서 생성된 JAR 파일을 지정하는 역할을 한다.
Spring Boot 프로젝트에서 ./gradlew build 를 실행하면 기본적으로 build/libs/ 경로에 JAR 파일이 생성된다.
ARG 값은 빌드 중에만 사용 가능하고, 컨테이너 실행 시에는 접근할 수 없음.
COPY : 로컬 ( 호스트 ) 에서 컨테이너 내부로 파일을 복사한다.
build/libs/*.jar 에 해당하는 Spring Boot 애플리케이션 JAR 파일을 app.jar 로 복사한다.
ENTRYPOINT 컨테이너가 실행될 때 기본적으로 실행할 명령어를 지정
해당 설정은 java -jar app.jar 명령어를 실행하여 Spring Boot 애플리케이션을 실행함
고정된 실행 명령어로, 컨테이너가 실핼될 때 항상 실행된다.
1 - 5. application.yml 파일 수정
spring:
application:
name: "board_API"
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://postgres-container:5432/board_api
username: jjsh0208
password: Gusdk5540!
localhost 환경이 아닌 postgres-container 컨테이너와 연결해서 사용할것이기때문에 url을 수정해준다.
1 - 5. 애플리케이션 Jar 파일로 Build
intellJ 터미널에서 ./gradlew clean bootjar 명령어를 실행해 jar 파일로 빌드해준다
1 - 6. Docker Image Build
# 기본 명령어
# -t 옵션은 이미지를 태깅하는 역할
# docker build t <dockerHub Id>/<이미지 명>:<태그명> <빌드할디렉터리>
# 이미지 빌드 실행
docker build -t board-api .
. 는 현재 디렉터리를 의미한다
1 - 7 Docker Hub에 image 업로드 하기
# docker push <dockerHub Id>/<image 파일명>:<태그명>
docker push ddongkka/board-api
3. AWS EC2에서 Docker 설치 및 컨테이너 실행
1. EC2 접속하기
나는 윈도우 운영체제 이기때문에 IntelliJ 를 통해 EC2에 접속해보겠다.
SFTP는 Secure File Transfer Protocol의 약자로, 네트워크 상에서 파일을 안전하게 전송하기 위한 프로토콜이다.
SFTP는 SSH (Secure Shell) 프로토콜 위에서 작동하며, 데이터 전송을 암호화하여 보안을 제공하며,일반적으로 SFTP를 사용하여 파일을 업로드하거나 다운로드하고, 파일 및 디렉터리를 관리합니다.
Host 에는 연결하려는 EC2의 퍼블릭 IPv4 주소를 넣어준다.
username에 ubuntu를 넣어주고 키 페어 인증을 선택한 후 저장한 키 페어를 선택해준다.
모든 설정이 끝나면 Test Connection으로 연결에 성공했는지 테스트해본다.
2. AWS EC2에서 Docker 및 Docker Compose 설치
Dokcer 설치
#시스템 패키지를 최신 버전으로 업데이트한다.
sudo apt update && sudo apt upgrade -y
# Docker를 설치하기위해 필요한 기본 도구들을 설치해준다.
sudo apt install -y ca-certificates curl gnupg
# Docker의 공식 GPG키를 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Docker의 공식 apt 저장소를 추가
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 패키지 업데이트
sudo apt-get update
# Docker 설치
sudo apt-get install docker-ce docker-ce-cli containerd.io
도커 설치 확인
docker --version
3. Docker Network 생성
sudo docker network create board_network
3. Docker 이미지 다운로드 및 컨테이너 실행
명령어를 입력하면 해당 도커 이미지가 로컬환경에 없을 경우 자동으로 허브에서 다운로드하므로 생략해도 무방하다.
나는 절차적를 지키고싶어서 앞에서 허브에 push한 이미지를 받아 컨테이너를 실행해보겠다.
우선은 현재 앱에서 사용할 postgres 이미지를 다운받아 설정을 디비 환경을 구성해보겠다.
Spring Boot image 및 postgresSQL image 다운로드
# sudo docker pull <dockerHub Id>/<이미지 명>:<태그 명>
# 배포할 스프링부트 프로젝트 이미지
sudo docker pull ddongkka/board-api
# postgreSQL
sudo docker pull postgres:latest
Docker 컨테이너 실행하기
docker run --name postgres-container --network board_network -e POSTGRES_DB=board_api -e POSTGRES_USER=jjsh0208 -e POSTGRES_PASSWORD=Gusdk5540! -p 5432:5432 -d postgres:latest
# --name postgres-container -> 컨테이너 이름 설정
# --network board_network -> 네트워크 연결
# -e POSTGRES_DB=board_api -> 생성할 DB 이름
# -e POSTGRES_USER=jjsh0208 -> DB 사용자 이름
# -e POSTGRES_PASSWORD=Gusdk5540! -> DB 비밀번호
# -p 5432:5432 -> 로컬 포트와 컨테이너 포트 매핑
# -d postgres:latest -> 백드라운드 실행 및 postgreSQL 이미지 사용
docker run --name board-api --network board_network -p 8080:8080 -d ddongkka/board-api
# --network board_network -> 네트워크 연결
# -p 8080:8080 -> 로컬 포트와 컨테이너 포트 매핑
# -d board_api:api -> 백그라운드 실행 및 spring boot app 이미지 사용
Docker 컨테이너 실행 확인
# Docker 실행중인 컨테이너 확인
sudo docker ps
# Docker 모든 컨테이너 확인 ( 정지된것도 포함 )
sudo docker ps -a
4. 결과 확인
이제 DB에 정상적으로 값이 들어갔는지 확인해본다.
sudo docker exec -it postgres-container bash -c "psql -U jjsh0208 -d board_api"
이렇게 도커 네트워크를 통해 postgreSQL 컨테이너와 나의 springboot 앱 컨테이너가 연결된것도 확인할 수 있었다.
이제 다음은 CI/CD를 적용해보겠다.
'DevOps' 카테고리의 다른 글
25.03.31 Spring Boot Acturator , Prometheus, Grafana (0) | 2025.03.31 |
---|---|
25.03.30 모니터링 시스템 (0) | 2025.03.30 |
Github Actions 와 CI/CD 란? (0) | 2025.03.04 |
25.03.03 GitHub Actions(CI / CD)와 Docker로 AWS에 자동 배포하기 (2) (0) | 2025.03.03 |
25.02.27 도커와 주요 명령어 (0) | 2025.02.27 |