개발 환경
- Docker
- AWS EC2 Ubuntu
- Github Actions
- Spring boot
- Java 17
- Gradle
- 인텔리제이에서 코드를 작성 후, Github로 Push.
- Github에서 조건을 만족할 경우, Github Actions 실행.
(develop branch에 코드가 Push, Pull Request될 경우로 설정함) - Github Actions는 미리 작성해 둔 .yml 파일의 내용대로 프로세스가 진행
- 빌드
- 도커 repository에 이미지 push
- ssh로 서버에서 도커 이미지 pull 받아 실행
1. Docker file 작성
FROM openjdk:17-jdk // jdk 설정
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
FROM openjdk:17-jdk
- open jdk java 17 버전의 환경을 구성
ARG JAR_FILE=build/libs/*.jar
- build가 되는 시점에 JAR_FILE 이라는 변수명에 build/libs/*.jar 표현식을 선언했다는 의미
- build/libs 경로는 gradle로 빌드했을 때 jar 파일이 생성되는 경로입니다.
- Maven의 경우 target/*.jar 로 설정해주시면 됩니다.
COPY ${JAR_FILE} /app.jar
- 위에 선언한 JAR_FILE 을 /app.jar 로 복사합니다.
ENTRYPOINT ["java","-jar","/app.jar"]
- jar 파일을 실행하는 명령어(java -jar jar파일) 입니다.
ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"]
- 운영 및 개발에서 사용되는 환경 설정을 분리해서 사용할 경우, 위와 같이 ENTRYPOINT를 설정할 수 있음
참고!
- 스프링 부트 gradle 플러그인 2.5 버전부터 gradle 빌드 시 jar 파일 2개 생성
- 프로젝트 이름 - 버전 - .jar
- 프로젝트 이름 - 버전 - plain.jar
- build.gradle에 아래 코드 삽입
jar { enabled = false }
2. AWS EC2에 도커 설치하기
- 관리자 권한 부여
sudo su -
- Docker 설치 및 관련 스크립트 입력 (코드 복사)
# 업데이트
sudo apt-get update -y
# HTTP 패키지 설치
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common -y
# gpg 키 및 저장소 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository --yes \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# Docker 엔진 설치
sudo apt-get install docker-ce docker-ce-cli containerd.io -y
- 설치 확인
docker -v
3. Docker Repository 만들기
- dockerhub에 회원가입, 로그인 후 이미지를 저장할 Repository 생성
- Repository Name과 ID (koeyhk) 기억
4. Github Actions 스크립트 파일 생성
- Github repository - Actions - Java with Gradle 선택
name: Java CI with Gradle
on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
jobs:
develop-cd:
# (1) 실행 환경
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
# (2) JDK 17
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
# (3) Ignore yml 파일 추가
- name: Copy dev secret
env:
DEV_SECRET: ${{ secrets.APPLICATION_DEV_YML }}
DEV_SECRET_DIR: src/main/resources
DEV_SECRET_DIR_FILE_NAME: application-dev.yml
run: echo $DEV_SECRET | base64 --decode >> $DEV_SECRET_DIR/$DEV_SECRET_DIR_FILE_NAME
# (4) ./gradlew 권한 설정
- name: ./gradlew 권한 설정
run: chmod +x ./gradlew
# (5) Gradle build (Test 제외)
- name: Build with Gradle
run: ./gradlew build -x test
# (6) docker build & push to production
- name: Docker build & push to DockerHub
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -t ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest-dev .
docker push ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest-dev
# (7) GET GitHub IP
- name: get GitHub IP
id: ip
uses: haythem/public-ip@v1.2
# (8) aws 세팅
- name: aws 세팅
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
# (9) Add github ip to AWS
- name: Add GitHub IP to AWS
run: |
aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
# (10) 서버에 접속하여 도커 이미지를 pull 받고 실행하기
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.DEV_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.KEY }}
port: 22
script: |
sudo docker stop spring-dev
sudo docker rm spring-dev
sudo docker image rm ${{ secrets.DOCKER_REPO }}
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest-dev
sudo docker run -d --name spring-dev -p 8080:8080 -e spring.profiles.active=dev-env ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest-dev
# (11) REMOVE Github IP FROM security group
- name: Remove IP FROM security group
run: |
aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SG_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
- Github ip 주소에 대해 EC2의 보안 그룹을 추가해준 후 삭제 - (7), (9), (11)
- EC2에 접근하여 docker 배포하기 전에 보안 그룹 추가
- 모든 task가 종료된 이후 추가한 보안 그룹 삭제
- 현재 돌아가고 있는 컨테이너를 멈추고 삭제한 뒤 앞에서 빌드한 이미지를 pull 받고 컨테이너를 실행 - (10)
Tip! Gradle Caching
## gradle caching
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- 이 부분은 추가하지 않아도 무방하나 개인적으로 적용했을 때 빌드 시간이 20~30% 가량 향상되었다!
GitHub - actions/cache: Cache dependencies and build outputs in GitHub Actions
Cache dependencies and build outputs in GitHub Actions - GitHub - actions/cache: Cache dependencies and build outputs in GitHub Actions
github.com
5. Github Actions Secret Key 생성
- APPLICATION_DEV_YML: application-dev.yml 파일을 Base64로 인코딩해 넣어줌
- AWS_ACCESS_KEY_ID: IAM 액세스 키
- AWS_SECRET_ACCESS_KEY: IAM 비밀 액세스 키
- AWS_SG_ID : EC2 보안그룹으로 지정되어있는 '보안그룹의 ID'
- DEV_HOST : AWS EC2 인스턴스의 퍼블릭 IPv4 DNS
- DOCKER_USERNAME : 본인의 Docker Hub Username
- DOCKER_PASSWORD : 본인의 Docker Hub Password
- DOKER_REPO : 본인의 Docker Hub Repository
- EC2_USERNAME : AWS EC2 인스턴스의 Username (ex: ubuntu)
- KEY : AWS EC2 인스턴스를 생성할 때 저장된 pem 키
- -----BEGIN RSA PRIVATE KEY-----부터 -----END RSA PRIVATE KEY-----까지를 복사해서 이 값으로 넣어주면 됨
해당 과정을 거치며 발생한 오류들을 해결하는 과정을 다음 글에 작성하였다!
CI/CD 트러블 슈팅
AWS + Docker + Github Actions를 이용한 CI/CD 개발 환경 Docker AWS EC2 Ubuntu Github Actions Spring boot Java 17 Gradle 인텔리제이에서 코드를 작성 후, Github로 Push. Github에서 조건을 만족할 경우, Github Actions 실행. (deve
koeyhk.tistory.com
참고 블로그
'AWS, CI&CD' 카테고리의 다른 글
Github Actions + S3 + Code Deploy + Docker + Nginx을 활용한 무중단 자동 배포 환경 구축 (Blue/Green) (0) | 2023.12.18 |
---|---|
Blue-Green 배포 중 트러블 슈팅 (0) | 2023.10.03 |
EC2 RDS 연결 (0) | 2023.10.01 |