Ecoex 서비스 페이지 배포 파이프라인 구성

Daniel Seo·2021년 4월 24일
0
post-custom-banner

현재 진행중인 에코엑스 서비스 페이지의 개발 파이프라인을 구성하면서 그 과정을 글로 남겼습니다.

Prerequisites

먼저 현재 개발되어 넘겨받은 소스는 HTML, CSS, JS로만 구성이 되어있고 그 안에는 약 140MB에 달하는 이미지와 동영상파일도 함께 있었습니다. 개발환경을 구성하기에 앞서 앞으로 이 서비스 페이지가 어떻게 유지보수되고 활용될 것인지에 따라 그 환경을 구성하는 방법이 각각 다르겠지만, 주어진 시간과 리소스에 따라 가장 간단하면서도 유지보수를 하기 위한 필수적인 Tool들을 사용하여 구축하기로 했습니다.

대용량의 이미지와 영상

기본적으로 배포와 소스관리를 위해서 모든 코드를 git repository로 관리하려고 했으나 주어진 소스들 중에는 대용량의 이미지(.png, .jpg)와 영상파일(.mp4)등이 포함되어 있었고 이 파일들을 git과 같은 scm에 포함시킬 수는 없었습니다. 그렇기 때문에 이런 미디어 파일들을 서버 외부 혹은 내부의 저장소에 별도로 위치시키고 나머지 코드들만 scm으로 관리가 되어야만 했습니다.

위와 같은 문제를 해결하기 위해 다음과 같은 문제들에 대해서 고민해야 했습니다.

  • 어떻게 CI/CD 환경을 구축할 것인가?
  • 미디어 파일 (이미지, 영상)을 어디에 위치시킬 것인가?
    - 외부에 위치시킨다 (S3 Storage)
    - 내부에 위치시킨다 (서버 내 직접 저장)

어떻게 CI/CD 환경을 구축할 것인가?

현재 스터디중인 Docker와 Jenkins를 이용해서 배포 파이프라인을 구축해놓은 샘플 프로젝트가 있었고, 시간이 많이 없어서 이를 활용하기로 결정했습니다. 기본적으로 프론트엔드 라이브러리인 React와 같은 라이브러리에서 build를 했을 때 나온 결과와 파일구조가 동일하므로, 컨테이너화를 위한 Dockerfile을 이용하기로 했고 마찬가지로 build 과정을 제외한 Jenkins의 파이프라인도 동일하게 가져갈 수 있었기 때문에 쉽게 CI/CD 환경을 구축할 수 있었습니다.

기본적으로 Local, Dev, Prod 환경이 있고, Github에도 각각 dev 브랜치와 master 브랜치를 두어 각각의 브랜치에 업데이트를 하면 이 코드들을 가져다가 dockerizing 한 후에 각 서버에 배포하는 파이프라인을 두었습니다.

미디어 파일 (이미지, 영상)을 어디에 위치시킬 것인가?

위와 같은 배포 파이프라인 구축을 하기 위해서는 어찌되었든 미디어 파일을 일반 코드와 별도로 관리가 필요했습니다. 용량이 크기 때문에 이를 함께 도커 이미지로 만들면 이미지가 매우 커지고 배포하는데 있어서 몸집이 무겁기 때문에 이를 피해야 했습니다. 그래서 크게 두가지 방법으로 생각했는데 하나는 일반적인 프로젝트에서 사용하는 S3 storage, 아니면 내부 서버에 직접 파일들을 두는 것으로 생각했습니다.

S3 Storage

S3 stroage를 사용하는 것은 이후 미디어 파일에 대한 유지보수 측면에서도 매우 큰 장점이 있지만, 현재 해당 파일들이 S3에 위치하지 않다는 것, S3에 넣는 코드나 그에 대한 url을 저장하고 있는 DB도 없다는 것이 현재로서는 구축해야하는 시간이 부족하다고 생각했습니다. 뿐만 아니라 S3에 미디어 파일들을 넣으면 코드 내에서 그 파일들을 불러오는 경로 또한 전부 수정이 되어야 하기 때문에 현재로써는 시간이 부족하다고 생각했습니다.

서버 내 저장

서버 내 저장하는 방법으로는 직접 ftp 등을 통해 미디어 파일들을 서버로 보내서 그 코드들이 직접 서버 내 파일을 불러오는 방법입니다. 하지만 모든 코드들이 컨테이너화 되어서 EC2 서버내 파일에 직접 Access하려면 별도의 방법이 필요했습니다. 이를 해결하기 위해 구글링한 결과, Docker의 Volume을 이용하면 쉽게 해결할 수 있다는 것을 알았습니다.

Docker Volume은 별도의 공간을 생성해 컨테이너가 공유할 수 있는 데이터들을 위치시키고 한 개의 혹은 여러개의 컨테이너가 해당 공간을 공유할 수 있도록 하는 기술입니다.이를 참고하여 각각 필요한 이미지 파일들을 해당 Docker Volume 에 위치시키고 서비스 하고 있는 컨테이너에서 이 볼륨을 기존 이미지 파일의 경로에 각각 Mount를 시켰습니다.


그리고 아래와 같은 순서로 해당 내용을 진행했습니다.

  • Docker Volume 생성

  • 미디어 파일 해당 Volume에 위치

  • 서비스 컨테이너에 Volume 마운트 하여 Run

1. Docker Volume 생성

# 데스크탑용 이미지
$ docker volume create img-d 

# 모바일용 이미지
$ docker volume create img-m

2. 미디어 파일 해당 Volume에 위치

  • img-d volume의 경로
    /var/lib/docker/volumes/img-d/_data
  • img-m volume의 경로
    /var/lib/docker/volumes/img-m/_data

3. 서비스 컨테이너에 Volume Mount 하여 Run

서비스 페이지의 시작경로가 /usr/share/nginx/html이기 때문에 기존 소스에서 이미지가 있던 경로에 해당 volume들을 각각 마운트 시킵니다.

  • Images for mobile :
    Mount 경로 : /usr/share/nginx/html/m/img
  • Images for desktop :
    Mount 경로 : /usr/share/nginx/html/img

그리고 Container를 Run 할때 두 볼륨을 각각 원하는 위치에 Mount하여 Run 합니다.

결과

Jenkins 배포를 통해 코드 수정 없이도 이미지를 잘 불러와 이상없음이 확인되었습니다.

Q&A

Q: Is it possible to mount multiple volumes into single container?

A: Yes : https://stackoverflow.com/questions/18861834/mounting-multiple-volumes-on-a-docker-container/18861869

profile
배움을 나누는 개발자입니다
post-custom-banner

0개의 댓글