Docker로 프로젝트 배포하기

jomminii_before·2020년 3월 20일
15

Docker는 가상화 기술의 하나로 container virtualization 이라는 기술을 제공합니다. Docker는 컨테이너라는 가상 실행 환경 위에 application 배포 엔진을 더해 사용자의 코드를 어디서든 빠르고 가볍게 실행시킬 수 있게 해줍니다.

이 Docker를 이용해서 이번에 진행한 프로젝트를 EC2에 배포해보도록 하겠습니다.

로컬에서 도커 빌드하기

1.프로젝트 requirements.txt에 gunicorn 추가

프로젝트의 서버를 실행시키려면 도커의 이미지 내에도 gunicorn이 설치되어야합니다. 다른 프로그램을 쓰시면 다른걸 사용해도 됩니다. 도커에 프로그램을 빌드시킬 때 requirements.txt에 있는 프로그램들을 설치하기 때문에 여기 안에 gunicorn을 명시해주면 됩니다. 이 부분은 pip freeze로 할 수 있는데 아래 글을 보면서 참고해보시면 좋습니다.

>>> pip install gunicorn
Collecting gunicorn
  Using cached gunicorn-20.0.4-py2.py3-none-any.whl (77 kB)
Requirement already satisfied: setuptools>=3.0 in /Users/LeeJongMin/conda/envs/danaebang/lib/python3.8/site-packages (from gunicorn) (45.2.0.post20200210)
Installing collected packages: gunicorn
Successfully installed gunicorn-20.0.4

2. 연결할 데이터 베이스 정보 수정

저의 경우에는 my_settings.py라는 파일 안에 데이터베이스 정보를 작성해뒀는데, 여기에서 도커와 연결할 데이터베이스 정보를 작성해줘야합니다. 본 프로젝트의 데이터베이스는 AWS RDS에 올려뒀기 때문에 세팅 파일 안에 이 정보를 넣어줍니다. 기존에 설정이 되어있다면 Host와 Password 정보만 맞게 넣어주면 됩니다. 제 my_settings.py 설정은 아래 글을 보시면 확인해 보실 수 있습니다.

Django와 MySQL 연결하기


3. local에서 runserver를 해보고 의존성 확인

마지막으로 도커 이미지를 빌드하기 전에 로컬에서 프로젝트 서버가 잘 돌아가는지 확인해봅니다. 여기서 안되면 도커에서도 안됩니다.

>>> python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
March 20, 2020 - 14:50:08
Django version 3.0.3, using settings 'danaebang.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

4. Dockerfile 생성

이제 프로젝트 최상위 디렉터리에 도커 이미지 빌드 설정을 해주는 Dockerfile을 생성합니다. 확장자명은 없고, 파일명 전체가 Dockerfile 입니다.

파일 안에는 아래와 같은 내용을 채워줍니다.

>>> vi Dockerfile
#./Dockerfile 
FROM python:3                            [ 1 ]
WORKDIR /usr/src/app                     [ 2 ]

## Install packages 
COPY requirements.txt ./                 [ 3 ]
RUN pip install -r requirements.txt      [ 4 ]

## Copy all src files 
COPY . .                                 [ 5 ]

## Run the application on the port 8080 
EXPOSE 8000                              [ 6 ]

#CMD ["python", "./setup.py", "runserver", "--host=0.0.0.0", "-p 8080"] 
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "example.wsgi:application"]  [ 7 ]

[ 1 ] : 기반이 될 이미지 설정
[ 2 ] : 작업 디렉토리 설정(도커 이미지 내의 경로)
[ 3 ] : 현재 패키지 설치 정보를 도커 이미지에 복사
[ 4 ] : requirements.txt를 읽어서 도커 내에 프로그램 설치
[ 5 ] : 현재 프로젝트 최상위 디렉토리의 파일 전체를 도커의 경로에 모두 복사
[ 6 ] : 개방할 도커의 특정 포트번호. 여기서는 8000번 포트를 외부에 개방
[ 7 ] : gunicorn을 사용해서 서버를 실행. example 자리에는 내 프로젝트의 wsgi가 위치한 디렉토리를 명시


5. Dockerfile을 이용해 이미지 빌드하기

이제 Dockerfile이 있는 위치에서 쉘에 아래의 명령어를 쳐서 도커 이미지를 만듭니다. (그 전에 docker login으로 로그인을 해줍니다.) 이름 앞에 계정명을 안써도 되긴 하는데, 계정명을 안쓰면 가끔 에러가 뜰 수 있다고 해서 전 계정명을 입력했습니다.
마지막에 있는 "."은 현재 디렉토리에 있는 Dockerfile을 사용하겠다고 명시해주는 역할을 합니다.

docker build -t '도커허브에 가입한 계정명'/'이미지명':'버전' .
ex) docker build -t jongjong/project:0.1.0 .
>>> docker build -t jongjong/project:0.1 .
Sending build context to Docker daemon  97.17MB
Step 1/7 : FROM python:3
 ---> f88b2f81f83a
Step 2/7 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 48b1397fae7d
Step 3/7 : COPY requirements.txt ./
 ---> f6782e5cb3c7
Step 4/7 : RUN pip install -r requirements.txt
 ---> Running in 9d6612e02861
Collecting asgiref==3.2.3
  Downloading asgiref-3.2.3-py2.py3-none-any.whl (18 kB)
  ~~~
  
Step 5/7 : COPY . .
 ---> 41449b5911cb
Step 6/7 : EXPOSE 8000
 ---> Running in 52fbf8aa4e42
Removing intermediate container 52fbf8aa4e42
 ---> 5e2aba021983
Step 7/7 : CMD ["gunicorn", "--bind", "0.0.0.0:8000", "project.wsgi:application"]
 ---> Running in d81526492674
Removing intermediate container d81526492674
 ---> 481b7f7169f6
Successfully built 481b7f7169f6
Successfully tagged jongjong/project:0.1

이미지가 빌드된 후 docker images를 쉘에 쳐보면 만들어진 이미지를 볼 수 있습니다.

>>> docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
jongjong/project        0.1                 481b7f7169f6        6 seconds ago       1.1GB
python                   3                  f88b2f81f83a        3 weeks ago         933MB

6. 빌드된 이미지 실행해보기

-d는 지속적으로 실행하기 위한 옵션이고, -p는 포트포워딩을 한다는 의미입니다. 호스트 포트는 내가 열 포트의 번호이고, 컨테이너 포트는 위에서 Dockerfile을 만들때 설정한 8000 포트로 설정됩니다.

docker run --name '컨테이너 명' -d '데몬으로 실행하기 위한 옵션' -p '호스트 포트':'컨테이너 포트' '이미지명'
ex) docker run --name jong01 -d -p 8000:8000 jongjong/project:0.1.0
>>> docker run -d -p 8000:8000 jongjong/project:0.1
3d1c79166938fe502a2aebc957a94ede0e59bf940fe168650c2be91a1c3641e2

docker ps를 사용하면 현재 실행중인 컨테이너를 확인할 수 있습니다.

>>> docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                    NAMES
3d1c79166938        jongjong/project:0.1      "gunicorn --bind 0.0…"   4 seconds ago       Up 3 seconds        0.0.0.0:8000->8000/tcp   hungry_beaver
>>> docker stop hungry_beaver
hungry_beaver
>>> docker start hungry_beaver
hungry_beaver
>>> docker stop hungry_beaver
hungry_beaver

docker stop 컨테이너명 으로 컨테이너를 중단할 수 있고, 또 중단한 컨테이너를 docker start 컨테이너명으로 다시 실행할 수 있습니다. 그리고 컨테이너가 필요없어지면 docker rm 컨테이너명 으로 컨테이너를 삭제할 수 있습니다. 컨테이너를 삭제한다고 빌드한 이미지는 삭제되지 않으니 걱정 마세요!


7. 이미지 푸시

이제 이미지를 푸시하면 되는데, 깃허브에서 내 코드를 레퍼지토리에 푸시하는 개념과 같다고 생각하면 됩니다. 도커에도 도커 레퍼지토리가 있어서 나의 이미지를 올려놓을 수 있습니다.

>>> docker push '이미지명'
>>> docker push jongjong/project:0.1.0

EC2에 배포하기

8. 터미널에서 도커에 로그인

터미널에서 docker login을 입력하면 계정 정보를 입력하라는 메시지가 나타납니다. 입력을 완료하고 나면 도커에 로그인이 됩니다.

>>> sudo docker login
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

9. EC2에 접속 후 도커 설치

제 EC2는 우분투로 되어있기 때문에, 맥에 설치했을때와는 다른 방식으로 도커를 설치 해줘야합니다. 아래의 명령어들을 한줄씩 입력해주면 설치가 됩니다.

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common 
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" 
sudo apt update 
apt-cache policy docker-ce
sudo apt install docker-ce

10. 도커에 이미지 pull 하기

로컬에서와 마찬가지로 docker login으로 로그인을 한 후 도커 레퍼지토리에 있는 이미지를 pull 해오면 됩니다. 우분투에서는 권한설정 문제가 있어서 모든 명령어를 칠 때 앞에 sudo를 쳐주세요!

>>> sudo docker pull '이미지명'
sudo docker pull jongjong/project:0.1.0

pull 을 해오고 난 후, sudo docker images -a를 치면 pull된 이미지가 보입니다.


11. 이미지 실행하기

이미지를 실행하기 위해서는 로컬에서와 마찬가지로 run 명령어를 실행하면 됩니다.

sudo docker run --name '컨테이너명' -d -p 8000:8000 jongjong/project:0.1.0
>>> sudo docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
jongjong/project         0.1                 481b7f7169f6        5 minutes ago       1.1GB
profile
https://velog.io/@jomminii 로 이동했습니다.

1개의 댓글

comment-user-thumbnail
2021년 9월 9일

안녕하세요. 글 잘 보았습니다.
혹시 ec2 에 배포할 경우, apache2 나 nginx 를 이용한 라우팅은 따로 안해주시나요?

답글 달기