amazon EC2 + Docker 설치하기
목표 AWS EC2 Instance를 생성하고 사용하는 방법 알아보기 EC2 SSH를 이용해 Instance에 Docker 설치하기 AWS EC2란 EC2(Elastic Compute Colude) EC2는 AWS에서 제공하는 클라우드 컴퓨팅 솔루션으로 AWS region에 존재
zzzzseong.tistory.com
해당 글은 위 포스트와 이어지는 글입니다. EC2 Instance 생성 과정과 Docker 설치 방법을 보려면 위 포스트를 참고해주세요
Spring 프로젝트에 Dockerfile 추가하기
Docker Image 생성을 위해 Spring 프로젝트 root 경로에 Dockerfile을 생성한 후 Github repository에 push한다. 본인은 현재 oracle의 jdk17버전을 이용하고 있는데 프로젝트 jdk버전에 맞춰 FROM 절을 수정해주면 된다.
Github Actions workflow 생성하기
Github Actions 이용을 위해 repository에 들어가 Actions를 클릭 후 프로젝트에 맞는 Build 옵션을 선택한다. 본인은 Gradle기반 프로젝트를 이용하기 때문에 아래와 같이 선택하였다.
그럼 workflow 파일의 템플릿을 제공하고 프로젝에 맞춰 수정할 수 있다. 본인은 아래와 같이 작성했다. 코드에 포함되어있는 ${{ secrets.DATASOURCE_ URL}} 부분은 중요한 정보이기 때문에 github actions secrets 기능을 사용한 것이다. 뒤에 자세히 설명하겠습니다.
name: Spring Boot & Gradle CI/CD
# master branch에 push 또는 PR이 발생하면 workflow를 발생시킨다.
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
# .properties file 생성
- name: application.properties 생성
run: |
mkdir ./src/main/resources
touch ./src/main/resources/application.properties
echo spring.jpa.hibernate.ddl-auto=update >>./src/main/resources/application.properties
echo spring.datasource.url=${{ secrets.DATASOURCE_URL }} >>./src/main/resources/application.properties
echo spring.datasource.username=${{ secrets.DATASOURCE_USERNAME }} >>./src/main/resources/application.properties
echo spring.datasource.password=${{ secrets.DATASOURCE_PASSWORD }} >>./src/main/resources/application.properties
echo spring.datasource.driver-class-name=org.mariadb.jdbc.Driver >>./src/main/resources/application.properties
# JDK 17 설치
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'oracle'
# Spring Boot Application Build
- name: Spring Boot Application Build
run: ./gradlew build
# DockerHub Login
- name: DockerHub Login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME}}
password: ${{ secrets.DOCKERHUB_PASSWORD}}
# Docker Image Build
- name: Docker Image Build
run: docker build --platform linux --build-arg DEPENDENCY=build/dependency -t ${{ secrets.DOCKERHUB_USERNAME}}/${{ secrets.PROJECT_NAME }} .
# DockerHub Push
- name: DockerHub Push
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
# EC2 Instance 접속 및 애플리케이션 실행
- name: Run Application
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_KEY }}
script: |
sudo docker kill ${{ secrets.PROJECT_NAME }}
sudo docker rm -f ${{ secrets.PROJECT_NAME }}
sudo docker rmi ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.PROJECT_NAME }}
sudo docker run -p ${{ secrets.PORT }}:${{ secrets.PORT }} \
--name ${{ secrets.PROJECT_NAME }} \
-d ${{ secrets.DOCKERHUB_USERNAME}}/${{ secrets.PROJECT_NAME }}
✅ properties file 생성: application.properties 파일을 gitignore에 등록했기 때문에 프로젝트 빌드를 위해서 값들을 추가해준다. 명령어가 동작하지 않아 엄청 삽질을 했는데 github에 resource 파일이 안올라가 있었다. mkdir -> touch로 파일을 만들어준 후 값을 입력해 마무리 했다.
✅ JDK 설치: 본인 버전에 맞는 jdk를 설치해주면 된다.
✅ SpringBoot Application Build(.jar 파일 생성): repository에 올라와있는 파일들을 build하는 과정이다 하다가 에러가 몇번 났었는데 단위 테스트를 위해 만들어놓은 테스트 코드 파일이 문제를 일으켰다. Rollback 설정을 안해놔서 DB에 있는 값이 Unique하지 않다고 에러가 나길래 중복 데이터를 삭제하고 마무리 했다.
✅ DockerHub Login: docker 사용자 이름과 비밀번호를 넣어주면 된다.
✅ Docker Image Build: 이전 단계에서 build한 .jar 파일을 도커 이미지로 만드는 과정이다. 위와 같이 따라하면 Docker의 username/projectname 으로 image이름이 등록된다. EC2에 docker는 설치했지만 명령어를 실행할 수 없다는 에러가 뜨면 EC2에서 docker를 실행시켜줘야한다.
✅ DockerHub Push: EC2 Instance에서 Docker Image를 pull 할 수 있도록 DockerHub에 등록한다.
✅ EC2 Instance 접속 및 애플리케이션 실행: host 부분에 퍼블릭 IPv4 DNS 를 넣고 username에는 ssh username을 넣으면 되는데 각자 OS에 맞는 username을 선택하면 된다. 아래 링크를 참고해 알맞은 값을 선택하도록 하자. 본인은 amazon linux OS로 EC2를 사용하기에 ec2-user로 설정했다.
AWS EC2 Instance 의 ssh 접근시, OS별 기본 username
https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/managing-users.html OS/Distro Official AMI ssh Username Legacy / Community / Other AMI ssh Usernames Amazon Linux ec2-user Ubuntu ubuntu root Debian admin root RHEL 6.4 and later ec2-user RHEL 6.3 a
papababo.tistory.com
Github Actions Secrests 등록하기
위와 같이 workflow를 작성하고 push하면 정상적으로 동작하지 않을것이다. 이유는 secrets 에 들어가는 값이 모두 비어있기 때문이다. 값들을 하나하나 넣어보도록 하자. 아래와 같이 사용할 secrets 들을 하나씩 넣고 다시 workflow를 돌려보면 잘 될것이다.
아래와 같이 workflow가 정상적으로 작동했다면 EC2 Instance의 SSH에 접속해 docker container를 확인해보자. Github Actions를 통해 올린 애플리케이션이 원하는 포트 위에서 잘 돌아가고 있음을 확인할 수 있다.
이번 포스팅을 하며 정말 많은 에러를 겪었다. 하지만, 여러 자료를 찾아보며 문제를 해결할 수 있었고 백엔드 뿐만 아닌 서버 운영에 대한 지식도 많이 얻은 것 같다.
[ 참고자료 ]
[CI/CD] Github Actions를 활용한 CI/CD 파이프라인 구축 (+ Docker hub)
Github Actions를 활용한 CI/CD 파이프라인 구축 개념 EC2 Instance 생성, EC2 Instance에 Docker 설치, Docker Hub 회원가입이 되어있다고 가정 Github Repository에 프로젝트의 추가사항이나 변경사항 push 혹은 merge Git
chb2005.tistory.com