AWS EC2에서 Docker를 활용해 배포해보기
Ubuntu에서 Docker, Docker Compose 설치하기
Ubuntu에서 Docker, Docker Compose 설치하기
sudo apt-get update && \
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo apt-key fingerprint 0EBFCD88 && \
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
sudo apt-get update && \
sudo apt-get install -y docker-ce && \
sudo usermod -aG docker ubuntu && \
newgrp docker && \
sudo curl -L "https://github.com/docker/compose/releases/download/2.27.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose && \
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
잘 설치됐는지 확인
docker -v # Docker 버전 확인
docker compose version # Docker Compose 버전 확인
AWS ECR(Elastic Container Registry)이 뭘까? 왜 배울까?
AWS ECR이 뭘까?
필요한 이미지를 다운로드 받을 때 Dockerhub이라는 곳에서 다운받는다고 했었다. Dockerhub에서는 이미지를 저장 및 다운받을 수 있는 저장소 역할을 한다고도 했다.
Dockerhub과 동일한 역할을 하는 서비스가 하나 더 있다. 그게 바로 AWS ECR이다. AWS ECR도 이미지를 저장 및 다운받을 수 있는 저장소 역할을 한다. 우리는 이 AWS ECR에 대해 배울 것이다.
왜 Dockerhub 대신에 AWS ECR을 사용하는가?
최근에는 AWS 클라우드 환경에서 인프라를 구축하는 일이 많아졌다. AWS ECR을 사용하면 다른 AWS Resource와의 연동이 편하고, AWS 내에서 한 번에 관리할 수 있기에 편하다는 장점이 있다.
AWS ECR을 왜 배우는지?
Docker를 사용하지 않았을 때 많은 사람들이 사용하는 배포 전략 중 하나는 Github을 활용하는 방법이다. 프로젝트 코드를 Github에 Push 한 뒤에, AWS EC2에 접속해서 해당 코드를 Pull 받아서 실행시키는 방식을 많이 사용한다. 이 방식은 프로젝트 코드 전체를 EC2로 이동시켜야 하며, 프로젝트 코드를 실행시킬 런타임 환경(Node, JDK 등)도 설치되어 있어야만 실행이 된다.
Docker의 가장 큰 장점은 이식성이다. Docker만 깔려있으면 어디에서든 내가 원하는 프로젝트를 실행시킬 수 있다는 게 장점이다. 이 때 Github을 활용해 프로젝트 코드 전체를 EC2로 옮겨 Docker 기반으로 실행시켜도 된다. 하지만 프로젝트에서 필요한 코드에 대해서만 Docker 이미지로 빌드해, EC2에서는 그 이미지만 다운받아서 실행시키는 게 훨씬 심플하다.
AWS ECR을 배우는 이유는 훨씬 간단하게 프로젝트를 배포하고 실행시키기 위해서이다.
[실습] AWS ECR(Elastic Container Registry) 사용해보기
[맥(Mac OS)]
brew install awscli
aws --version # 잘 출력된다면 정상 설치된 상태
[윈도우(Windows)]
이 링크(https://awscli.amazonaws.com/AWSCLIV2.msi)를 다운받아 설치하기
cmd를 실행시켜서 아래 명령어 입력해보기
aws --version # 잘 출력된다면 정상 설치된 상태
[우분투(Ubuntu)]
sudo apt install unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
$ aws --version # 잘 출력된다면 정상 설치된 상태
-- IAM 생성하기
IAM에서 사용자 생성하기
Access Key 발급하기
AWS CLI로 액세스 키 등록하기
aws configure
AWS Access Key ID [None]: <위에서 발급한 Key id>
AWS Secret Access Key [None]: <위에서 발급한 Secret Access Key>
Default region name [None]: ap-northeast-2
Default output format [None]:
-- AWS ECR(Elastic Container Registry) 셋팅하기
Docker 이미지를 저장할 수 있는 저장소를 만들어보자.
일반적으로 하나의 리포지토리에는 한 종류의 이미지만 저장하고 관리한다.
-- 이미지 빌드해서 AWS ECR에 Push, Pull 해보기
Dockerfile 작성하기
FROM openjdk:17-jdk
ENTRYPOINT ["/bin/bash", "-c", "sleep 500"]
이미지 빌드 및 push 하기
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ...
docker build --platform linux/amd64 -t hwiro-web-server .
docker tag hwiro-web-server:latest ...
docker push ...
이미지 pull 받아보기
docker image rm -f [Container ID] # 기존 갖고있던 이미지 지우기
docker pull 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server
docker image ls
002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server
: 이 값 자체가 이미지 이름이다. 길어서 어색해보일 뿐이다.
[실습] AWS EC2에 Spring Boot 배포하기
로컬 환경에서 프로젝트 셋팅
spring.io에서 Java-17 버전으로 선택
간단한 코드 작성
AppController
@RestController
public class AppController {
@GetMapping("/")
public String home() {
return "Docker, World!";
}
}
DockerFile
FROM openjdk:17-jdk
COPY build/libs/*SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
Spring Boot 프로젝트 빌드하기
./gradlew clean build
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com
docker build -t instagram-server .
docker tag instagram-server:latest 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server:latest
docker push 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server:latest
AWS EC2에서 AWS CLI 설치 및 액세스 키 등록하기
AWS ECR로부터 이미지 다운받아 컨테이너 띄우기
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com
docker pull 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server
docker run -d -p 8080:8080 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server
혹시나 아래와 같은 에러가 발생했다면?
이 에러의 원인은 CPU 아키텍처 환경이 다르다는 뜻이다. 조금 더 자세히 설명하자면, 이미지 빌드는 M1과 같은 ARM 기반의 환경에서 진행하고, 이미지 실행은 ARM 기반의 환경이 아닌 곳에서 할 때 위와 같은 에러가 발생한다.
위 에러를 해결하기 위해서는 이미지를 실행시키고자 하는 CPU 아키텍처에 맞춰서 이미지를 빌드해야 한다. 로컬 환경에서 아래와 같이 다시 빌드한 뒤 AWS ECR로 Push하자.
./gradlew clean build
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com
docker build --platform linux/amd64 -t instagram-server .
docker tag instagram-server:latest 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server:latest
docker push 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server:latest
-- AWS EC2의 CPU 아키텍처 확인하는 방법
lscpu
x86_64 = linux/amd64
--aws 서버에 배포하기
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com
docker pull 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com
docker image ls
docker run -d -p 8080:8080 [이미지 이름]
-- docker compose로 실행해보기
compose.yml
services:
instagram-server:
image: 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server:latest
ports:
- 8080:8080
docker compose up -d --build
# 이미지 업데이트 시
docker compose pull
docker compose up -d --build
잘 작동하는지 확인.
docker ps
docker logs
[실습] AWS EC2에 Spring Boot, MySQL, Redis 배포하기
compose.yml에 MySQL, Redis 관련 내용 추가하기
compose.yml
services:
instagram-server:
image: 002177417362.dkr.ecr.ap-northeast-2.amazonaws.com/instagram-server:latest
ports:
- 8080:8080
depends_on:
my-db:
condition: service_healthy
my-cache-server:
condition: service_healthy
my-db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: pwd1234
MYSQL_DATABASE: mydb
volumes:
- ./mysql_data:/var/lib/mysql
ports:
- 3306:3306
healthcheck:
test: [ "CMD", "mysqladmin", "ping" ]
interval: 5s
retries: 10
my-cache-server:
image: redis
ports:
- 6379:6379
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 5s
retries: 10
컨테이너 실행하기
docker compose up -d --build
# 잘 실행되고 있는 지 확인
docker ps
docker compose ps
docker compose logs
댓글을 작성해보세요.