본문 바로가기

Dev Story/아키텍처

Docker 를 처음 적용해보는 분들에게 도움을 드리는 글 (설정법 포함)

# 개요

글이나 영상 포스팅시 요약 단어와 문장을 분석 해주는 웹앱을 만들게 되어 호스팅 할려고 이것저것 알아보던중 heroku 에 배포 하면 무료로 사용 할 수 있다는 것을 알고 기쁜 마음에 관련 문서들을 읽어 봤지만 내가 만든 앱 의 구성은 nginx+react+fastapi 로 이루어져있기 때문에 단순하게 heroku git 에 push 하면 바로 배포가 되지 않는다.

 

다른 방법은 없을가 방법을 찾던중 docker container 형식으로 배포할 수 있다는 것을 알게 되었고 혼자 사용 하는 서버에 배포 할 건데 굳이 docker 가 필요 할가? 라는 고민에 빠지게 되었는데 이내 필요하다는 결론에 이르게 된다. 이유는 한 서버에 (서버가 감당 할 수 있는) 여러 프로젝트를 올리게 될것이고 그곳에는 복잡한 패키지 의존성 문제들이 산재 할거라는게 예상 된다.

 

그럴때 이런 문제점을 해결 해줄수 있는게 docker라는 생각에 이르자 예전에 약간 맛만 봤던 docker 를 이참에 제대로 알아 보자는 취지에 기록을 남겨 둘려고 한다.

 

위키 백과에 따르면 도커(Docker)는 리눅스 응용 프로그램들을 프로세스 격리 기술들을 사용해 컨테이너로 실행하고 관리하는 오픈 소스 프로젝트이다. 라고 정의 되어 있다. (도커의 가상화 관련 내용은 이 링크에서 확인 바랍니다.)

 

오픈 소스 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 오픈 소스(open source) 제품에는 소스 코드,[1] 디자인 문서,[2] 또는 제품의 내용을 사용할 권한이 포함된다. 대체적으로 이를 오픈 소스 모델이라고 부르며 여기

ko.wikipedia.org

사용해보면서 느낀 점을 비유 하자면 붕어빵 틀을 만들고 붕어빵을 찍는 형태이다. 틀은 이미지라고 불리고 붕어빵은 컨테이너로 불린다. 붕어빵 안에는 팥도 있고 크림도 있는 즉 여러 프로세스가 존재하고 그 프로세스 셋 들을 바로 서버에서 실행 시킬수 있는 구조이다.

 

그러면 이미지 를 만드는 방법을 알아야 하고 실제로 서버에 실행될 컨테이너(= 프로세스 셋) 를 실행 시키면 원하는 서버 배포가 끝이 난다.

 

* 이미지 를 생성 하는 방법 에는 두가지가 있다.

1.컨테이너 (= 이미지에서 실행된 인스턴스) 가 실행 된 상태에서 수정작업을 한 후 docker commit  명령어를 이용해 반영된 이미지를 굽는 것

  • docker commit <CONTAINER_ID> <IMAGE_NAME>:<TAG>

2. Dockerfile (*꼭 철자 대소문자 필히 준수)을 생성하고 만들고자 하는 이미지를 스크립트로 작성하여 이미지 생성

실제로 사용한 스크립트는 뒷부분에 캡처 해 두었다.

  • docker build -t <IMAGE_NME>:<TAG> . (. 은 현재 위치=dockerfile 파일위치)

* 생성된 이미지를 인스턴스화 시키면 그것이 바로 컨테이너 가 되는 것이다.

  •  docker run -d --name <컨테이너명 정의> -p 80:80 <IMAGE_NAME>:<TAG>

-d: 데몬(=백그라운드) 로 컨테이너를 실행 하는 파라미터 그로 인해 명령어를 계속 칠 수 있다. -d 옵션이 없으면

새로운 cmd 창 하나 더 열어야 한다.

-p:  포트 정의하는 파라미터 로 왼쪽이 컨테이너 외부에서 들어 오는 포트: 컨테이너 내부에서 작동 하는 포트 

 

* 선택사항이긴 한데 여러 컨테이너를 관리 할 수 있도록 해주는 docker-compose.yml 스크립트 예문 이다.

version 은 문법에 맞게 지정 services 는 컨테이너를 정의 하는 노드로 하위에 nginx와 konlweb 컨테이너가 정의 되어 있다. build 는 이미지가 빌드 될 위치를 지정 통신할 ports 지정  이외에도 네트워크, 데이터볼륨, 컨테이너간 연결 등 세부적인 기능들도 정의 할 수 있다. 자세히 알아 볼려면 * 여기 를 참고 

 

docker-compose up 명령어로 정의한 내용을 실행 하면 아래 와  같이 이미지가 빌드 되고 컨테이너가 실행 되는 것을 확인 할 수 있다.

 

각 컨테이너 Dockerfile 에 정의된 CMD 명령어가 실행된 것도 확인 할 수 있다.

Docker Desktop 에서도 이미지 생성및 컨테이너가 실행중인 걸 확인 된다.

 

처음에는 이 파일들의 문법을 굳이 익힐 필요가 있을가 해서 간단하게 작성 한후 컨테이너 터미널에 붙어서 세부 서버 작업을 시작 했었다. 그리고 테스트 하다가 다시 컨테이너를 수정해야 하는 경우가 발생 했는데 생각 해보니 이 컨테이너는 이미지로 부터 복사된 붕어빵 같은 존재라 이미지 를 수정 해야지 다음에 컨테이너가 삭제 되더라도 수정된 내용을 반영 할거라는 생각이 들었다.

 

그럴려면 직접 이미지를 바로 수정이 안되고 수정 할려는 이미지를 인스턴스화 시킨 컨테이너를 실행해서 그 컨테이너 안에 있는 내용을 변경 한 후 commit 하여 이미지 빌드를 해야 한다는 것을 알게 되었고 운영을 하다가 먼가 수정 사항이 이루어 질때마다 컨테이너 를 실행 -> 컨테이너 수정 ->  컨테이너 빌드 (= 이미지 에 반영) 형식이 되어서 개발 프로세스가 복잡 해진 데다가  은근 스트레스 받는 구석도 있다. 변경전 이미지를 가지고 다시 그 전에 했던 작업을 되돌아가서 해야 하는 상황이 발생한다.  

 

이런 상황을 필자가 직접 겪어 보니 Dockerfile 로 작성 하는 방식이 필요 하다는 것을 알게 되었다. 이미지를 만들 세부적인 절차를 정의 해놓고 빌드를 했을때 정상적으로 작동되면 올바른 이미지가 생성 될것이고 오류가 났을 경우에는 그 부분을 수정 해 나가면 된다.

 

그리고 개발 프로세스가 처음 스크립트 작성할때는 시간이 걸리겠지만 한번 작성 한 후에는 모든과정이 위에 상황보다

빠르게 될 것이다.

(사실 이 문법을 익히기 싫어서 앞전 프로세스 형태로 진행 해보다가 결국엔 필요 하다는 것을 깨달았다.)

 

필자가 개발한 Dockerfile 내용은 아래와 같다.

# Dockerfile

- 대략 구성은 아래와 같다.

1. Nginx 

 . react build 된 파일

 

2. fastapi

 .python3.8

 .fastapi 관련 패키지

 .Java1.8

 .konlpy 관련 패키지 

 

1. Nginx Dcokerfile

2. fastapi Dcokerfile

FROM: 기본 베이스가 되는 운영체제를 정의 한다. 

ENV: 환경변수 선언

RUN: 실행할 명령어

WORKDIR : 작업을 실행할 위치

COPY: 로컬PC 경로에서 컨테이너 에 있는 폴더의 복사 위치

EXPOSE: 컨테이너와 통신할 포트 설정

CMD: 위에 과정이 다 끝나고 마지막에 실행할 명령어 인데 이부분을 지정 하지 않으면 컨테이너는 아무런 실행 을 하지 않고 종료 된다. (필자는 이런 개념을 몰라서 오류가 난줄 알고 로그를 찾았지만 로그는 찾을수 없었다... 오류가 아니기 때문에;;)

 

https://www.fnv-dev.co.kr/ 이곳에 위프로젝트가 구성된 사이트로 글 포스팅 할때 핵심 키워드, 문장, 구절을 리스트업 해주는걸 도와주는 기능을 가지고 있다.