AWS ElasticBeanstalk의 Docker플랫폼을 사용한 Django 배포
Django
AWS
Docker
settings모듈 분할
mysite/
settings/
__init__.py
base.py
local.py
debug.py
Docker설치
Get Docker CE for Ubuntu
Install Docker for Mac
ubuntu:16.04 컨테이너 실행
docker run --rm -it ubuntu:16.04 /bin/bash
Dockerfile_base작성
FROM ubuntu:16.04
MAINTAINER dev@lhy.kr
RUN apt-get -y update
RUN apt-get install -y python-pip
RUN apt-get install -y git vim
# pyenv
RUN apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils
RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
ENV PATH /root/.pyenv/bin:$PATH
RUN pyenv install 3.6.3
# zsh
RUN apt-get -y install zsh
RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh || true
RUN chsh -s /usr/bin/zsh
# pyenv settings
RUN echo 'export PATH="/root/.pyenv/bin:$PATH"' >> ~/.zshrc
RUN echo 'eval "$(pyenv init -)"' >> ~/.zshrc
RUN echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.zshrc
# pyenv virtualenv
RUN pyenv virtualenv 3.6.3 app
# uWGSI install
RUN /root/.pyenv/versions/app/bin/pip install uwsgi
# Nginx install
RUN apt-get -y install nginx
# supervisor install
RUN apt-get -y install supervisor
# pip
ENV LANG C.UTF-8
COPY requirements.txt /srv/requirements.txt
RUN /root/.pyenv/versions/app/bin/pip install -r \
/srv/requirements.txt
Dockerfile_base를 사용해서 이미지 생성
docker build -t base . -f Dockerfile_base
이후 작업은 Dockerfile에 작성
FROM base
MAINTAINER dev@lhy.kr
ENV LANG C.UTF-8
COPY requirements.txt /srv/requirements.txt
RUN /root/.pyenv/versions/app/bin/pip install -r /srv/requirements.txt
COPY . /srv/app
RUN mkdir -p /var/log/uwsgi/mysite
COPY .config/nginx/app.conf /etc/nginx/sites-available/
RUN rm -rf /etc/nginx/sites-enabled/*
RUN ln -sf /etc/nginx/sites-available/app.conf /etc/nginx/sites-enabled/app.conf
WORKDIR /srv/app/mysite
RUN /root/.pyenv/versions/app/bin/python manage.py migrate --noinput
RUN /root/.pyenv/versions/app/bin/python manage.py collectstatic --noinput
EXPOSE 80 8012
Docker 명령어들
현재 위치를 기준으로 Dockerfile을 이용해 새 이미지 생성
docker build . -t [이미지이름(태그명)]
현재 위치를 기준으로 특정 파일을 이용해 새 이미지 생성
docker build . -t [이미지태그명] -f [파일명]
이미지를 컨테이너로 실행하며 셸로 이동
docker run --rm -it [이미지명] /bin/zsh
이미지로 컨테이너를 실행하며 포트 연결
docker run --rm -it -p <외부포트>:<컨테이너포트> <이미지명> <실행할 명령>
실행중인 컨테이너에 명령 실행
docker exec [container id] [실행할 명령]
실행중인 컨테이너에 접속 후 셸 실행하고 싶을 경우
docker exec -it [container id] /bin/zsh
Delete all docker containers
docker rm $(docker ps -a -q)
Delete all docker images
docker rmi $(docker images -q)
Delete name docker images force
docker rmi -f $(docker images --filter "dangling=true" -q)
Dockerfile에 uWSGI, Nginx관련 설정 추가 및 실행 확인
Dockerfile
FROM base
MAINTAINER dev@lhy.kr
ENV LANG C.UTF-8
# 파일 복사 및 requirements설치
COPY . /srv/app
RUN /root/.pyenv/versions/app/bin/pip install -r \
/srv/app/requirements.txt
# pyenv local설정
WORKDIR /srv/app
RUN pyenv local app
# Nginx
RUN cp /srv/app/.config/nginx/app.conf \
/etc/nginx/sites-available/
RUN rm -rf /etc/nginx/sites-enabled/*
RUN ln -sf /etc/nginx/sites-available/app.conf \
/etc/nginx/sites-enabled/app.conf
# uWSGI
RUN mkdir -p /var/log/uwsgi/app
Terminal
docker run --rm -it -p 8012:80 eb /bin/zsh
nginx
/root/.pyenv/versions/app/bin/uwsgi -i /srv/app/.config/uwsgi/app.ini
이후 로컬 브라우저에서 localhost:8012
로 접속이 되며, 해당 로그가 컨테이너 내부의 /var/log/uwsgi/app/<date>.log
파일에 쌓이는지 확인
DockerHub
DockerHub
에 저장소를 만들고 로컬 터미널에서 로그인을 시킨다.
이후 docker pull/push
시 해당 인증을 사용한다.
Terminal
docker login
# base이미지에 새 태그명 azelf/base를 붙인다
docker tag base azelf/base
# azelf/base저장소에 해당 이미지를 push
docker push azelf/base
EB CLI
애플리케이션 생성
eb init
환경 생성
eb create
배포
eb deploy
빌드 관련 오류 보기
eb ssh
cat /var/log/eb-activity.log
.ebextensions/01_nginx_https_redirect.config
files:
"/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf":
mode: "00644"
owner: root
group: root
content: |
map $http_upgrade $connection_upgrade {
default "upgrade";
"" "";
}
server {
listen 80;
gzip on;
gzip_comp_level 4;
gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
}
access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
access_log /var/log/nginx/access.log;
location / {
proxy_pass http://docker;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
if ($http_x_forwarded_proto = 'http') {
return 301 https://$host$request_uri;
}
}