한영님과 함께하는 Docker 기초!
참고 문서
도커에 대한 개념은 첫 번째 링크가 아주 잘 정리해주었다 :) 나는 실습위주로 정리.
프로그램 설치
Python 설치 확인
$ brew list
$ python3 --version
python 은 기본적으로 python version 2 를 말하고 python3 는 version 3를 말한다!
python에서 소프트웨어 관리하는 패키지 관리 시스템인 pip(Python Package Index)도 pip 는 version 2, pip3 는 version 3 를 말한다.
Django 프로젝트 설치
Get started with Docker Desktop for mac 에 보면 nginx 기반의 boilerplate 프로젝트가 있는 것 같지만 Django 해보고 싶으니까 Django 설치해보자!
requirements.txt 만들기
얘는 왜 만들어보냐면 도커가 개발환경에 필요한 패키지들을 묶어서 이미지화 하고 그걸 이용해서 동일한 환경을 복제하기 쉽도록 만들어주는데 이미 이전부터 pip3 freeze / install 을 이용하면 패키지 목록을 파일에 저장하고 이 파일을 이용해서 패키지들을 재설치 할 수 있었다. 이런게 있었다 + 뒤에 가서 쓸거다.
- pip3 list : 현재 환경에 설치된 패키지 목록 조회
- pip3 freeze : 현재 환경 내에 설치된 패키지 목록을 특정 파일에 기록
- pip3 install : 파일에 저장된 패키지 목록을 설치
$ pip3 list
$ pip3 freeze > requirements.txt
$ cat requirements.txt
Django==2.1.5
pytz==2018.9
$ pip3 install requirements.txt
Docker Desktop 설치
Django 프로젝트 로컬 서버로 올리기
프로젝트 생성
$ django-admin startproject blog
위 명령어로 쟝고 템플릿 프로젝트를 생성할 수 있다. 프로젝트 이름이 blog!
만들어진 프로젝트는 기본적으로 다음과 같은 구조를 가진다.
blog
├── manage.py
└── blog
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
Django 프로젝트 서버 올려보기
blog 프로젝트에 기본적으로 생성되는 manage.py 파일을 통해 Django 프로젝트를 서버에 올릴 수 있다.
$ python3 blog/manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
February 07, 2019 - 04:05:00
Django version 2.1.5, using settings 'blog.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
ip 주소와 포트를 설정해주지 않으면 기본적으로 127.0.0.1:8000 으로 연결된다. python [name]/manage.py runserver [ip:port_number] 로 설정해줄 수 있다.
브라우저를 켜고 localhost:8000 으로 접속하면 쟝고 프로젝트의 개발버전(디폴트)이 올라간걸 알 수 있다!
화면 추가하기
Django에 화면을 추가하려면 화면을 구성할 .py 파일을 만들고 이를 urls.py 에 등록해주어야 한다.
views.py
from django.http.response import HttpResponse
def index(request):
return HttpResponse('<h1>Hello Django!</h1>')
이미 만들어져 있는 urls.py 파일에 우리가 만든 views.py파일에서 정의한 index 를 import 하고 url patterns 에 추가한다.
urls.py
from django.contrib import admin
from django.urls import path
from .views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
]
쟝고 프로젝트에 대한 추가적인 이해는 Django Documentation - Tutorial 을 참고하자!!!
이제 서버를 다시 올리면 (서버를 내리려면 Control+C) 아까의 로켓은 없어지고 Hello Django! 가 나온당! 우왕.
Docker 사용해보기
Docker Image 사용하여 서버 올리기
자 이제 이걸 Docker 를 사용해서 해보자. 우리는 이미 로컬에 python을 깔았지만, Docker를 통해 가상의 python 환경을 만들어내고 그 위에 서버를 띄워보자.
이미 많은 OS의 Docker Image들이 존재한다. 우리가 사용할 python 공식 Image는 Docker Hub 에서 찾을 수 있다.
Docker Hub에서 제공하는 python image들은 같은 버전임에도 다른 태그를 가진 이미지들이 존재한다. 자세한 설명은 Docker Docs 에서 확인 가능하다!
- Alpine : Alpine Linux
- Stretch : Debian Linux의 특정 버전
- Slim : Debian Linux의 특정 버전의 최소용량버전
정확히는 나도 더 공부하는 걸로!
암튼 우리는 python:3.7.2-slim 을 사용할거드앙.
$ docker images
$ docker run --rm -it python:3.7.2-slim /bin/bash
# pip install django
# django-admin startproject blog
# python blog/manage.py runserver
와! 도커를 이용해서 가상컨테이너에 python을 실행하고 그 안에서 django 를 설치한 뒤 프로젝트를 만들고 서버를 올렸다!
그치만 확인할 방법이 없는걸?! 그럼 도커랑 로컬을 연결할 수 있게 포트를 설정해주자.
$ docker run --rm -it -p 7999:8000 python:3.7.2-slim /bin/bash
# pip install django
# django-admin startproject blog
# python blog/manage.py runserver 0:8000
그럼 이제 localhost:7999 로 접속하면 docker의 8000 포트로 연결되어서 Django 프로젝트 화면이 나오게 된다.
Docker Image 생성
하지만! 도커는 가상머신이니까 내렸다 올렸다 할 때마다 다시 초기화 되서 매번 Django를 설치하고 프로젝트를 만들어야 하잖아?! 짱짱 귀찮으니까 자동화를 해보자.
도커 이미지를 실행할 때 자동으로 해야할 일들을 Dockerfile로 정의해주자. 이 도커파일은 우리가 전에 만들었던 Django 프로젝트의 하위에 있다. blog/Dockerfile (manage.py랑 같은 위치)
Dockerfile : 대소문자 주의, 확장자 없음 주의! 도커파일은 그냥 도커파일이다!
FROM python:3.7.2-slim
MAINTAINER caution.dev@gmail.com
RUN pip install django
WORKDIR /root
RUN django-admin startproject blog
WORKDIR /root/blog
CMD python manage.py runserver 0:8000
한 줄 씩 설명하자면 다음과 같다.
이 Docker Image는 python:3.7.2-slim 을 사용한다. python:3.7.2-slim 이미지에 Dockerfile이 있다면 거기에 정의된 명령어들을 수행할거다!
MAINTAINER : 이 Docker Image를 관리하는 관리자의 이메일 주소다!
RUN : 다음 명령어를 수행할거다! 여기서는 django를 설치한다.
WORKDIR : 작업을 수행할 디렉토리를 /root로 변경할 거야! (cd 로 경로 이동하는 거랑 비슷)
RUN : 다음 명령어를 수행할거다! 여기서는 django 프로젝트를 생성한다.
WORKDIR : 작업을 수행할 디렉토리를 /root/blog 로 변경할거야!
CMD : 컨테이너가 시작되었을 때 수행할 명령. Dockerfile에서 한 번만 사용할 수 있다. 여기서는 서버를 띄운다.
Dockerfile을 다 만들었으면 이제 Docker Build 를 수행하여 Docker Image를 만든다.
$ docker build -t blog .
$ docker images
docker images 명령어를 통해 만들어진 image 들을 확인할 수 있다.
자 이제 다시 docker를 실행시켜보자!
docker run --rm -it -p 7999:8000 blog
우왕 그러면 자동으로 django가 켜지고 서버까지 켜지는 걸 확인할 수 있다. localhost:7999 를 열면? 아마 로케트가 나올거다!
local 파일을 이용하여 docker에 서버 올리기
그런데 위에껄 하면 매번 새로운 프로젝트가 생성되고 그걸 켠다. 그럼 매번 컨테이너 내려가면 데이터 다 날아가는데 껏다 킬때마다 0부터 다시 코딩해야 한다. WHF!!!!!!!!!!!!!!!!
그러려고 만든 Docker가 아니니까, 우리가 이미 로컬에 만들었던 프로젝트를 이용해서 Docker에 올려보자.
Dockerfile 을 수정한다.
FROM python:3.7.2-slim
MAINTAINER caution.dev@gmail.com
COPY blog/requirements.txt /tmp/requirements.txt
RUN pip install -r /tmp/requirements.txt
COPY . /root/app
WORKDIR /root/app/blog
CMD python manage.py runserver 0:8000
새로운 명령어인 COPY가 생겼다. 이건 그야말로 로컬에 있는 파일을 Docker 로 복사할 때 사용한다.
앞서 만들었던 requirements.txt에는 django 를 포함한 현재 환경에서 사용되는 패키지들이 정의되어 있다. 그래서 이 파일을 복사한 뒤 RUN 명령어를 통해 이 파일에 있는 패키지들을 docker에서 설치한다. (결론적으로는 그러니까 장고를 설치해줄거다!)
그리고 현재 로컬에서 만들었던 Django project 를 그대로 복사한다. 매번 Django 프로젝트를 새로 생성하지 않고 로컬에서 작업한 내용을 가져다가 쓸 것이다. 0부터 코딩을 다시 할 필요가 없다!
Dockerfile을 수정했으면 다시 Docker Build 로 image를 새로 만들고 Docker를 실행시켜 보자.
$ docker build -t blog .
$ docker run --rm -it -p 7999:8000 blog
이제 localhost:7999 를 열면? 로케트가 아닌 Hello Django! 가 나올거다!
우와! 이제 제대로 로컬에서 Docker를 써봤다. 하지만 우리는 로컬서버를 돌리는 게 아니니까 (….) 의미가 없……진 않지만 실제 서버처럼 해보자. 한영님은 EC2를 이용하기로 했으니까 해본다.
EC2 만들기
ec2 인스턴스를 만들자
보안그룹을 http 와 ssh 를 같이 열어주자
https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html
.pem 파일 관리
.pem 파일은 인증에 사용되는 key 파일입니다. aws에 접속할 때 필요합니다! 이런 인증에 필요한 키 파일이나 인증서 파일은 ~/.ssh 에 옮겨서 관리합시다~! 그리고 키 파일이니까 권한 설정을 바꿔줍시다.
https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ec2-key-pairs.html#having-ec2-create-your-key-pair
chmod 400 /path/my-key-pair.pem
dns ipv4 : ec2-13-55-8-215.ap-southeast-2.compute.amazonaws.com
ssh -i cocozzang.pem ubuntu@ec2-13-55-8-215.ap-southeast-2.compute.amazonaws.com
DisallowedHost at / 문제
특정 호스트 이름으로 접속했을 때만 정상적으로 보여주도록 제한합니다
vi blog/settings.py
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['.amazonaws.com']
비어있다는 건 로컬 상에서만 돌릴 때! 그때는 오류가 안됩니당 :-)
도메인을 정확히 적어도 되지만 '.amazonaws.com'
정도만 적어줘도 괜찮습니다.
ls -al 명령어를 입력했을 때 요렇게 나와요!
-rwxr-xr-x 1 ubuntu ubuntu 538 Feb 6 08:15 manage.py* drwxrwxr-x 3 ubuntu ubuntu 4096 Feb 6 08:19 mysite/
EC2에서 Docker를 사용해 서버 띄워보기
-
sudo apt update sudo apt install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ 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 \ $(lsb_release -cs) \ stable" sudo apt update sudo apt install docker-ce docker-ce-cli
로컬에 있는 소스코드를 가져와서 EC2에 배포한다.
- ** scp**를 사용해 EC2로 파일 복사하기
scp -i ~/.ssh/<PEM_FileName>.pem -r . ubuntu@<EC2_Public_Domain>:/home/ubuntu/docker/
-r 재귀적
. 현재위치
ubuntu@
sudo docker build -t mashup -f Dockerfile
sudo docker un –rm -it -p 80:80 mashup
ALLOWED_HOSTS = [‘.amazonaws.com’, ‘loclhost’ ]
docker build -t mashup .
docker images
docker tag mashup cocozzang/mashup-docker-example
docker push cocozzang/mashup-docker-example
sudo docker run –rm -it -p 80:8000 cocozzang/mashup-docker-example