T_era
깃 액션으로 CICD 사용하기 본문
1. Dockerfile 작성하기
프로젝트의 가장 최상위 위치(.gitignore 파일이 있는 곳)에 Dockerfile이라는 이름의 파일을 만들기 확장자 X
# 1. 베이스 이미지 선택 (JDK 17, MAC 기반)
FROM eclipse-temurin:17-jdk
# 2. JAR 파일이 생성될 경로를 변수로 지정
ARG JAR_FILE_PATH=build/libs/*.jar
# 3. build/libs/ 에 있는 JAR 파일을 app.jar 라는 이름으로 복사
COPY ${JAR_FILE_PATH} app.jar
# 4. 컨테이너가 시작될 때 이 명령어를 실행
ENTRYPOINT ["java", "-jar", "/app.jar"]
#FROM: 어떤 환경을 기반으로 이미지를 만들지 선택.
#
#COPY: 내 컴퓨터에 있는 파일(빌드된 .jar 파일)을 도커 이미지 안으로 복사하는 명령어
#
#ENTRYPOINT: 도커 컨테이너가 시작될 때 실행될 명령어. 즉, java -jar app.jar 명령으로 스프링 부트 애플리케이션을 실행
- FROM: 어떤 환경을 기반으로 이미지를 만들지 선택합니다. openjdk:17-jdk-alpine은 JDK 17이 설치된 가벼운 리눅스 환경입니다.
- COPY: 내 컴퓨터에 있는 파일(빌드된 .jar 파일)을 도커 이미지 안으로 복사하는 명령어입니다.
- ENTRYPOINT: 도커 컨테이너가 시작될 때 실행될 명령어입니다. 즉, java -jar app.jar 명령으로 스프링 부트 애플리케이션을 실행합니다.
2. .dockerignore 작성하기
불필요한 파일들이 도커 이미지에 포함되지 않도록 .dockerignore 파일을 만듭니다. 이렇게 하면 이미지 용량이 줄고 빌드 속도가 빨라집니다.
# .dockerignore
.git
.idea
.gradle
3. 로컬에서 테스트
# 1. 프로젝트 빌드 (Gradle 기준)
./gradlew build
# 2. 도커 이미지 빌드 (my-app 이라는 이름으로)
docker build -t my-app .
# 3. 빌드된 이미지로 컨테이너 실행
docker run -p 8080:8080 my-app
http://localhost:8080로 접속해서 확인
도커 이미지를 배포할 EC2와 GitHub Actions가 AWS에 접근할 수 있도록 권한을 설정
1. AWS EC2 인스턴스 생성
- AWS 콘솔 접속 > EC2 > 인스턴스 시작
- 이름 설정: 알아보기 쉬운 이름
- OS 선택 (AMI): Ubuntu, 프리티어로 사용 가능한 버전
- 인스턴스 유형: t2.micro
- 키 페어 생성:
- 생성 후 반드시 저장
- 네트워크 설정 (보안 그룹):
- 보안 그룹 생성을 선택하고, 아래 규칙을 추가합니다.
- SSH (22번 포트):
- HTTP (80번 포트): 0.0.0.0/0
- 사용자 지정 TCP (8080번 포트): 0.0.0.0/0
- 보안 그룹 생성을 선택하고, 아래 규칙을 추가합니다.
- 스토리지 설정: 기본값(8GB)으로 충분
- 인스턴스 시작
2. EC2 서버에 Docker 설치하기
# SSH 접속 명령어 (Mac 기준)
# chmod 400 your-key.pem (최초 한 번만, 키 파일 권한 변경)
ssh -i "tera199810-KeyPair.pem" ubuntu@52.79.239.64
# 실행 최초에 yes입력해야함
# Ubuntu 패키지 업데이트
sudo apt-get update
# Docker 설치
sudo apt-get install -y docker.io
# ubuntu 사용자를 docker 그룹에 추가 (sudo 없이 docker 명령어 사용)
sudo usermod -aG docker ubuntu
# 변경사항 적용을 위해 SSH 접속 종료 후 재접속
exit
재접속 후 docker --version 명령어로 설치를 확인합니다.
3. GitHub Actions를 위한 IAM 사용자 생성
GitHub Actions가 내 AWS 계정에 접근해서 배포 작업을 하려면 권한이 필요
- AWS 콘솔 > IAM > 사용자 > 사용자 생성
- 사용자 이름: 알아볼 수 있도록 설정
- 권한 설정: 직접 정책 연결 선택 후 아래 내용 검색 후 선택.
- AmazonEC2FullAccess (EC2 제어 권한)
- AmazonS3FullAccess (S3 버킷 접근 권한, 배포 스크립트 저장용)
- AmazonRDSFullAccess (RDS DB 접근 권한)
- 사용자 생성을 끝내고 들어가서 액세스 키 만들기
- CLI를 선택하고, 경고 문구를 확인한 뒤 키 생성
- CSV로 다운받아서 저장
3. GitHub Actions을 위한 Docker Token발급
도커에 접근하기 위한 토큰 발급
- 도커 UI > 우측 상단 프로필 > Account Settings > Personal access tokens > Generate new Token
- 만료기한 설정
- 접근 권한 설정 Read,Write,Delete
- Generate 선택
- 제일 하단에 나온 두가지 값 저장
GitHub Actions 자동화 파이프라인 설정하기
1. GitHub Repository Secrets 설정
- 내 GitHub Repository > Settings > Secrets and variables > Actions
- New repository secret로 하나씩 추가
- AWS_ACCESS_KEY_ID: 위에서 발급받은 IAM 사용자의 액세스 키
- AWS_SECRET_ACCESS_KEY: 위에서 발급받은 IAM 사용자의 비밀 액세스 키
- AWS_REGION: 내 AWS 리전 코드 (예: ap-northeast-2 for Seoul)
- AWS_S3_BUCKET: 배포 스크립트를 저장할 S3 버킷 이름 (직접 만드셔야 합니다. 예: my-cicd-deploy-scripts)
- EC2_INSTANCE_ID: 배포할 EC2 인스턴스의 ID (EC2 콘솔에서 확인)
- EC2_HOST: EC2 인스턴스의 퍼블릭 IP 주소
- EC2_USERNAME: ubuntu (Ubuntu AMI 기준)
- EC2_SSH_KEY: 위에서 다운로드한 .pem 키 파일의 내용을 그대로 복사해서 붙여넣기(메모장으로 열고 --begin--부터 --end까지 전부 복사 붙여넣기)
- DOCKERHUB_TOKEN: 도커 토큰을 생성하며 나온 값 중dckr_pat_...으로 시작하는 값 복사 붙여넣기
- DOCKERHUB_USERNAME: 도커 토큰을 생성하며 나온 값 중 유저이름 부분만 붙여넣기 예(ljy981008)
2. cicd.yml 수정 (SSH 방식)
.github/workflows 폴더의 cicd.yml 파일
# 워크플로우의 전체 이름을 "CI/CD Docker to EC2"로 정했음.
name: CI/CD Docker to EC2
# 언제 이 워크플로우를 실행할지 정하는 부분임.
on:
push:
# "main" 브랜치에 코드가 push 될 때마다 실행될 거임.
branches: [ "main" ]
# 워크플로우가 해야 할 작업(job)들을 정의함.
jobs:
# "build-and-deploy"라는 이름의 작업을 하나 만들었음.
build-and-deploy:
# 이 작업은 GitHub이 제공하는 최신 우분투 가상머신에서 돌아감.
runs-on: ubuntu-latest
# 이 작업이 수행할 단계(step)들을 순서대로 나열함.
steps:
# 1단계: 코드 내려받기
- name: Checkout
# GitHub 저장소에 있는 코드를 가상머신으로 복사해오는 액션을 사용함.
uses: actions/checkout@v3
# 2단계: 자바(JDK) 설치
- name: Set up JDK 17
# 가상머신에 특정 버전의 자바를 설치하는 액션을 사용함.
uses: actions/setup-java@v3
with:
# 자바 버전을 '17'로 지정함.
java-version: '17'
# 'temurin'이라는 배포판을 사용함.
distribution: 'temurin'
# 3단계: gradlew 파일에 실행 권한 주기
- name: Grant execute permission for gradlew
# gradlew 파일이 실행될 수 있도록 권한을 변경함. 리눅스 환경이라 필수임.
run: chmod +x gradlew
# 4단계: 프로젝트 빌드
- name: Build with Gradle
# gradlew 명령어로 스프링 부트 프로젝트를 빌드함. 이걸 해야 .jar 파일이 생김.
run: ./gradlew build
# 5단계: 도커 빌드 환경 설정
- name: Set up Docker Buildx
# 도커 이미지를 효율적으로 빌드하기 위한 Buildx라는 툴을 설정함.
uses: docker/setup-buildx-action@v2
# 6단계: 도커 허브 로그인
- name: Login to Docker Hub
# 도커 이미지를 올릴 Docker Hub에 로그인하는 액션을 사용함.
uses: docker/login-action@v2
with:
# 아이디는 GitHub Secrets에 저장된 DOCKERHUB_USERNAME 값을 사용함.
username: ${{ secrets.DOCKERHUB_USERNAME }}
# 비밀번호는 GitHub Secrets에 저장된 DOCKERHUB_TOKEN 값을 사용함.
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 7단계: 도커 이미지 빌드 및 푸시(업로드)
- name: Build and push
# Dockerfile을 이용해 이미지를 만들고 Docker Hub에 올리는 액션을 사용함.
uses: docker/build-push-action@v4
with:
# 현재 폴더(.)에 있는 Dockerfile을 사용해서 빌드함.
context: .
# 빌드 성공하면 바로 Docker Hub로 푸시(업로드)함.
push: true
# 이미지 이름(태그)은 "아이디/my-spring-app:latest" 형식으로 지정함.
tags: ${{ secrets.DOCKERHUB_USERNAME }}/my-spring-app:latest
# 8단계: EC2 서버에 배포
- name: Deploy to EC2
# SSH를 통해 원격 서버(EC2)에 접속해서 명령어를 실행하는 액션을 사용함.
uses: appleboy/ssh-action@master
with:
# 접속할 EC2 서버의 IP 주소. Secrets에서 값을 가져옴.
host: ${{ secrets.EC2_HOST }}
# EC2 서버의 사용자 이름 (보통 ubuntu). Secrets에서 값을 가져옴.
username: ${{ secrets.EC2_USERNAME }}
# EC2 접속에 필요한 .pem 키. Secrets에서 값을 가져옴.
key: ${{ secrets.EC2_SSH_KEY }}
# EC2 서버에 접속해서 아래 스크립트를 순서대로 실행시킬 거임.
script: |
# EC2 서버에서도 Docker Hub에 로그인해야 이미지를 받을 수 있음.
docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }}
# Docker Hub에서 방금 올린 최신 버전의 이미지를 내려받음 (pull).
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/my-spring-app:latest
# 기존에 실행 중이던 'my-app' 컨테이너가 있으면 중지시킴. 없으면 그냥 넘어감 (|| true).
docker stop my-app || true
# 기존 'my-app' 컨테이너가 있으면 삭제함. 없으면 그냥 넘어감.
docker rm my-app || true
# 새로 받은 이미지로 'my-app'이라는 이름의 컨테이너를 실행함.
# -d: 백그라운드에서 실행, -p 8080:8080: 포트 연결
docker run -d -p 8080:8080 --name my-app ${{ secrets.DOCKERHUB_USERNAME }}/my-spring-app:latest
ECR을 쓰면 더 안전하고 빠르게 할 수 있다 하지만 복잡하다
RDS 연결
application.yml 프로젝트의 yml설정을 통해 rds 저장 설정을 추가
# 공통 설정
spring:
# 기본 프로필을 dev로 설정
profiles:
active: dev
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
show_sql: true
---
# 개발 환경(dev) 설정 - 로컬 DB 정보
spring:
config:
activate:
on-profile: dev
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/testDB
username: root
password: '비밀번호'
---
# 운영 환경(prod) 설정 - rds 설정
spring:
config:
activate:
on-profile: prod
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
---
로컬에서는 dev로 명시된 설정을 우선 실행하는데 후에 설정할 cicd.yml을 통해 우선순위를 prod를 했기 때문에 같은 yml에서 설정해도 된다
test/resources/application.yml
테스트 환경을 만들어놓지 않으면 rds가 작동하지않음
# 테스트 환경 전용 설정
spring:
datasource:
# H2 데이터베이스를 사용하도록 설정
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: create-drop
- RDS 인스턴스 생성
- AWS 콘솔에서 RDS > 데이터베이스 생성
- 표준 생성, 엔진 유형은 MySQL
- 템플릿은 프리티어
- DB 인스턴스 식별자 입력
- 마스터 사용자 이름 및 마스터 암호를 설정하고 반드시 메모를 해놓든 기억해놓기
- 연결 섹션에서 EC2 컴퓨팅 리소스에 연결은 연결 안 함으로. 보안 그룹을 직접 설정
- 보안 그룹 설정
- VPC 보안 그룹에서 새로 생성을 선택하고, 보안 그룹 이름 입력
- 나머지 설정은 그대로 두고 데이터베이스 생성을 클릭
- 생성이 완료되면 생성된 DB를 클릭하여 세부 정보 페이지로 이동 엔드포인트 주소를 복사해둔다. 이 주소가 yml의 DB_URL 환경변수 값
- 연결 & 보안 탭에서 VPC 보안 그룹 이름을 클릭
- 보안 그룹 페이지에서 인바운드 규칙 편집을 클릭하고 아래 규칙을 추가
- 유형: MYSQL/Aurora (3306)
- 소스: 규칙 추가를하고 사용자 지정을 선택, 검색창에 EC2 인스턴스가 사용 중인 보안 그룹의 ID(예: sg-...)를 찾아 선택
- 추가구성 > 퍼블릭 엑세스 허용으로 변경
- 규칙 저장
.GitHub Secrets 추가
- 내 GitHub Repository > Settings > Secrets and variables > Actions
- New repository secret로 하나씩 추가
- DB_URL: jdbc:mysql:// + 위에서 복사한 RDS 엔드포인트 주소 + /[데이터베이스명]
- 예: jdbc:mysql://my-db.xxxxxxxx.ap-northeast-2.rds.amazonaws.com:3306/testDB
- DB_USERNAME: 아까 기억해둔 RDS 생성 시 설정한 마스터 사용자 이름
- DB_PASSWORD: 아까 기억해둔 RDS 생성 시 설정한 마스터 암호
cicd.yml 수정
docker run -d -p 8080:8080 --name my-app ${{ secrets.DOCKERHUB_USERNAME }}/my-spring-app:latest
->
docker run -d -p 8080:8080 --name my-app \
-e SPRING_PROFILES_ACTIVE=prod \
-e DB_URL=${{ secrets.DB_URL }} \
-e DB_USERNAME=${{ secrets.DB_USERNAME }} \
-e DB_PASSWORD=${{ secrets.DB_PASSWORD }} \
${{ secrets.DOCKERHUB_USERNAME }}/my-spring-app:latest
위의 내용을 아래 내용으로 변경 (yml우선순위 및 rds 환경변수 추가)
'Programing > Datababse' 카테고리의 다른 글
| PostgreSQL 설치하고 스프링 프로젝트에 적용하기 (0) | 2025.06.14 |
|---|---|
| 데이터베이스 대표 시스템 중에 뭘 써야 할까? - Key-Value Store (1) | 2025.05.22 |
| 데이터베이스 대표 시스템 중에 뭘 써야할까? - RDB (0) | 2025.05.20 |
| 데이터베이스를 어떤 걸 써야할까? (0) | 2025.05.19 |
| 데이터베이스 키의 종류 및 정규화/반정규화 (0) | 2025.05.16 |