DEV-STUDY/Infra

AWS EC2(우분투)에 도커 이미지 배포하기

HwangJerry 2023. 8. 17. 13:12

도커는 오늘날 전 세계에서 개발자들이 가장 많이 사용하는 오픈소스 2위에 등극될 만큼 많이 활용되는 기술인데요. (1위는 git 입니다.) 이번 포스팅에서는 도커를 이용하여 AWS EC2 환경에 배포를 해보면서, 왜 다들 도커를 사용하는지 느껴보는 시간을 가져보겠습니다! 도커는 깔려있다고 가정합니다.

 

0. 실습 환경

  • 윈도우 11
  • jdk 17
  • springboot
  • intelliJ ultimate
  • docker desktop
  • EC2 : ubuntu 22.04

 

1. AWS EC2와 소스 코드 세팅하기

우선 배포할 코드와 서버 컴퓨터 역할을 해줄 EC2가 필요할 것입니다. 저의 경우에는 현재 진행하고 있는 프로젝트 코드를 배포하려고 하고 있으며, 서버 컴퓨터는 프리티어 EC2인 t2.micro를 이용할 것입니다.

 

2. jar build하기

로컬에서 도커파일을 작성해 줍니다. 저는 jar파일을 도커 이미지에 담아서 배포하는 방식을 활용할 예정이므로, 먼저 그레이들 명령어를 이용하여 자바 스냅샷(jar)을 생성해 주었습니다. 이 때, 편의상 plain jar가 생성되는 것을 막기 위해 build.gradle에 아래와 같이 세팅을 한 채로 상황에 따라 ./gradlew bootJar 또는 ./gradlew clean build를 해줍니다.

jar {
    enabled = false
}

3. Dockerfile 작성하기

우리는 자바 17을 이용하므로, jdk17이미지를 활용하도록 도커파일을 설정해보겠습니다.

FROM openjdk:17
ARG JAR_FILE=build/libs/*.jar
#WORKDIR = /usr/src/app
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=stage","app.jar"]

저는 stage 서버를 배포하는 과정이기 때문에 -Dspring.profiles.active=stage라는 값을 주게 되었습니다. 그 외의 명령어는 우리가 아는 jar 파일 명령어를 묶어둔 것입니다.

 

4. 도커 이미지 생성하기

도커 이미지 빌드는 도커파일이 있는 경로에서 아래와 같이 입력하면 됩니다.

docker build -t {도커 유저네임}/{이미지 이름 명명}:{태그 네임; usu. 버전 명명} ./

 

위 명령어는 자신의 아이디와 이미지 이름 명명을 세팅하고, 해당 이미지를 ./ 경로에 있는 도커파일을 이용하여 build 하겠다고 하는 의미입니다. 이 과정에서 permission 관련 문제가 발생한다면 login을 해주면 됩니다.

 

5. 도커 이미지 push하기

아래 명령어를 이용하여 도커 이미지를 도커 허브로 올립니다. 이는 간단히 깃의 원격 저장소로 올린다는 느낌으로 받아들여도 좋습니다.

docker push {도커 유저네임}/{이미지 네임}:{태그 네임}

 

6. EC2에 도커 설치

EC2 인스턴스를 생성한 뒤에, 인스턴스에 접속하여 도커를 설치해줘야 합니다. 개인적으로 이 단계가 가장 까다로웠고, 이 부분만 무사히 해결된다면 docker를 사용하여 배포하는 과정이 매우 간단해 집니다. 아래 예시는 도커 공식 홈페이지를 참고하였습니다.

 

conflict 가능성 있는 패키지 uninstall

for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

 

apt 패키지를 업데이트

sudo apt-get update

 

apt가 HTTPS 레포지토리를 사용할 수 있도록 하는 패키지 설치

sudo apt-get install ca-certificates curl gnupg

 

도커의 official GPG key를 등록 (curl 명령어로 docker의 GPG key를 불러와서 apt에 추가)

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

 

도커 엔진을 받아올 레포지토리 설정

echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

 

apt 패키지를 다시 업데이트

 sudo apt-get update

 

최신 버전의 도커 엔진(Docker Engine), 도커 컨테이너(containerd), 도커 컴포즈(Docker Compose) 설치

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

 

설치 확인

docker --version

설치 확인은 위 명령어로 하거나, docker run hello-world를 하기도 합니다. 공식 문서에서는 hello world 이미지를 실행했네요.

 

sudo 없이 docker 명령어 사용하기 (permission denied 해결하기)

계속 sudo를 붙여주기도 번거롭고, 한번 sudo 없이 해보면 permission denied되는 것을 알 수 있습니다. 이는 현재 사용자가 (aws 정책에 따라) ec2의 root user 권한을 자동으로 부여받지 못해서인데요. 이를 해결하기 위해 현재 사용자를 docker group에 포함시켜줘야 합니다.

sudo usermod -aG docker ${USER}

 

 터미널 재시작 후(shell session reload 목적) 아래 명령어로 결과를 확인하여 console 출력 끝에 docker가 붙어있는지 확인하면 잘 된 것입니다. 만약 shell session을 reload하기 위해서 터미널을 재부팅하는게 번거롭다면 newgrp docker 명령어를 사용하면 됩니다. (만약 여전히 Got permission denied while trying to connect to the Docker.. 에러가 난다면 ec2 인스턴스를 재접속할 것)

newgrp docker # reload the shell session
id -nG

 

서비스 status 확인

systemctl status docker --no-pager -l

 

7. (ec2 내에서) 도커 허브로부터 내가 로컬에서 올린 이미지 다운로드하기

docker pull {docker username}/{docker image name}:{image tagname}

만약 이 과정에서 permission denied가 된다면 login을 해주면 됩니다.

 

8. (ec2 내에서) 이미지 실행하기

외부에서 해당 도메인으로 접속하게 할 때 포트포워딩 설정 옵션은 -p {외부 접속 포트번호}:{내부 서버 포트번호}

백그라운드 실행(터미널을 종료해도 계속 실행되도록)하려면 -d

실행할 때 환경변수를 주입해주려면 -e {환경변수 이름}={환경변수 값} 을 같이 입력해주면 됩니다.

docker run -d \
-e SECRET_KEY=${SECRET_KEY} \
-e RDS_ENDPOINT=${RDS_ENDPOINT} \
-e RDS_PORT=${RDS_PORT} \
-e RDS_DB_NAME=${RDS_DB_NAME} \
-e RDS_USERNAME=${RDS_USERNAME} \
-e RDS_PASSWORD=${RDS_PASSWORD} \
-p 8080:8080 \
{DOCKER USERNAME}/{IMAGE NAME}

위 커맨드에서 ' \ ' 는 그냥 줄바꿈 문자라고 이해하시면 됩니다. 가독성을 위해 이렇게 작성하였는데, 그냥 띄어쓰기(공백)로 구분하시고 쭈욱 명령어를 나열하셔도 무방합니다.

 

위 과정을 모두 거치면 EC2에 도커 이미지 배포가 완료됩니다. 만약 이미지를 업데이트하면 그걸 push하고, ec2에서 다시 pull 한 뒤에 run 하면 업데이트를 거칠 수 있습니다.