docker-compose를 통하여 AWS EC2에 배포하기

끝날 때까지 끝난 게 아니다, 배포가 남지 않았는가?

Yujin Jeong
7 min readFeb 20, 2023

서비스 개발을 완료했다면 이제 배포를 해야 합니다. 배포하기 위해서 원격 서버에 필요한 언어와 라이브러리, 환경 변수를 설정해줘야 하는 데 docker를 사용하면 하나의 docker image로 모든 환경 설정이 완료된 컨테이너를 만들어 돌릴 수 있기 때문에 배포가 수월해진다는 장점이 있어 docker를 이용해 배포해보도록 했습니다.

0. nginx proxy 구조 파악하기

다음은 배포하고자 할 서비스의 nginx proxy 구조를 이미지로 정리한 것입니다.

클라이언트에서 서비스의 80번 포트로 진입 시 Proxy 서버로 접속하게 됩니다. Proxy 서버는 요청을 보낼 때 URL의 host 부분을 정해주지 않아도 서버 스스로 Endpoint에 따라 요청을 대신해 처리해 줍니다. 위 서비스에선 / 경로로 접근할 경우 Frontend에 연결되며 /dashboard경로로 요청 시 Backend로 요청을 보냅니다.

1. EC2 인스턴스 생성

이름 및 태그

이름 및 태그 > 명확하게 구분할 수 있는 서비스명을 설정해 줍니다. (ex. my-service-alpha.0.12 등등)

애플리케이션 및 OS 이미지

JS와 Express를 돌리기 위해 Linux를 선택했습니다.

인스턴스 유형

Free Tier로 표시된 항목 선택(개인 프로젝트 배포가 목적이라 Free Tier 한도 내에서 서비스를 운영하는 것을 목적으로 했습니다.)

키 페어

키 페어는 인스턴스에 접근하기 위해 필요한 보안 키입니다. 키 페어 는 초기 생성 시 한 번만 다운받을 수 있으니 분실하지 않도록 로컬 컴퓨터에 잘 보관해야 합니다.

네트워크 설정

네트워크 설정은 외부에서 EC2 인스턴스로 들어오는 인바운드 관련 설정입니다. SSH 접속은 보안상의 이유로 내 IP에서만 접속할 수 있게 하고 HTTPS 트래픽 허용을 추가해줍니다.

스토리지

Free tier 최대 용량은 30GB이므로 인스턴스 용량을 30GB로 설정해 줍니다. 인스턴스를 하나만 돌릴 예정이라 30GB로 설정했지만, 둘 이상의 인스턴스를 돌린다면 프리티어에 초과되어 과금이 될 수 있기 때문에 주의해야 합니다.

그 외 설정 > 디폴트 값 사용

1–1. 보안그룹 규칙

proxy 서버의 진입점을 80번 포트로 설정해주었기 때문에 80번 포트를 개방해줘야 합니다. 모든 IPv4 주소에서 80번 포트에 접근할 수 있도록 설정해주었습니다.

2. 키 페어로 EC2 인스턴스에 접속하기

키 페어가 보관된 pem 파일의 권한이 너무 오픈되어 있으면 AWS에서 접근을 거부하기 때문에 권한을 제한해 줘야 합니다.

// rw------- 
// 소유자에게만 읽기, 쓰기 지원
chmod 600 x.pem

그다음 SSH 프로토콜을 이용하여 원격으로 EC2 리눅스 서버에 접속합니다.

// Amazon Linux 2 또는 Amazon Linux AMI의 경우 사용자 이름은 ec2-user입니다.
// CentOS AMI의 경우 사용자 이름은 centos 또는 ec2-user입니다.
// Debian AMI의 경우 사용자 이름은 admin입니다.
// Fedora AMI의 경우 사용자 이름은 fedora 또는 ec2-user입니다.
// RHEL AMI의 경우 사용자 이름은 ec2-user 또는 root입니다.
// SUSE AMI의 경우 사용자 이름은 ec2-user 또는 root입니다.
// Ubuntu AMI의 경우 사용자 이름은 ubuntu입니다.
// Oracle AMI의 경우 사용자 이름은 ec2-user입니다.
// Bitnami AMI의 경우 사용자 이름은 bitnami입니다.

$ ssh -i [pem파일 경로] [사용자 이름]@[ec2의 퍼블릭 IPv4 주소 또는 도메인]

아래와 같이 뜨면 접속에 성공한 것입니다.

3. 접속한 인스턴스에 docker, docker-compose, git을 설치하고 git clone으로 프로젝트를 복사하기

최초 접속 시 root 계정의 password가 미정이기 때문에 먼저 root 계정 비밀번호부터 생성해주도록 합니다.

$ sudo passwd root
$ Enter new UNIX password: xxx
$ Retype new UNIX password: xxx
$ passwd: password updated successfully

그다음 docker, docker-compose를 설치해줍니다.

docker 설치

$ sudo yum update -y // 패키지 업데이트
$ sudo yum install docker -y // yum으로 docker 설치
$ docker -v // 설치 후 docker 버전 확인
$ sudo service docker start // docker 시작
$ sudo usermod -aG docker ec2-user // Docker 그룹에 ec2-user 추가

docker-compose

$ sudo curl \ 
> -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" \
> -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose // docker-compose 실행 권한 적용

$ docker-compose --version // 설치 후 docker-compose 버전 확인

git 설치 후 프로젝트 복사하기

$ sudo yum install git -y
$ git version // 설치 후 git 버전 확인
$ git clone [REPO_URL] [DIR] // git clone 명령어 실행

모든 준비가 완료되었다면 프로젝트를 복사해온 폴더로 이동하여 docker-compose up 명령어를 실행해 docker container를 실행하면 됩니다.

4. 프리티어 EC2 메모리 부족 현상

docker-compose up실행 중 이미지 빌드 과정에서 멈춰 진행되지 않는 벽돌 현상이 발생했습니다. 자세한 에러 파악을 위해 EC2 로그 파일을 살펴보았습니다.

활성 인스턴스 > 작업 > 모니터링 및 문제해결 > 시스템 로그 가져오기

로그 메시지 확인 결과 눈에 띄는 Out of memory 문구가 있다. EC2 메모리가 부족하여 더 이상 빌드가 진행되지 않고 있던 것이었다.

현재 램이 1GB 뿐인 프리티어 인스턴스 t2.micro를 사용하고 있기 때문에 이런 문제가 발생한 것이다. 메모리 부족 문제를 해결하기 위해선 swap memory 설정을 해줘야 한다. 현재 부족한 디스크 용량을 가상 메모리인 swap memory로 대체하는 것이 목적이다.

AWS에서 권장하는 swap memory의 용량은 다음과 같다.

현재 프리티어 인스턴스 기준으로 swap memory를 2GB 정도로 할당해 주는 것이 권장된다.

swap memory를 할당하는 법은 AWS에서 공식 문서로 제공해주고 있다.

--

--