◾️ Deploy関連手順整理 (参考サイト)
1. python localでweb service開発完了(virtual envでの開発作業)
2. package関連内容export (pip freeze > requirements.txt)
3. 開発ソースgit push
4. VPS (dockerがinstallされた仮想machine準備)
=> docker GUI 操作用portainer container作成・実行
5. Docker file作成
6. Docker Imageファイル作成
7. Docker Container作成
- STEP 1 : python localでweb service開発完了
以前作業したpinterest app
- STEP2 : Generate output suitable for a requirements file
※ mac conda環境でpip freezeしたらisort / certifiなど不要内容も含まれたので削除
(pinterestEnv) $ pip freeze > requirements.txt
(pinterestEnv) $ cat requirements.txt
appdirs==1.4.4
asgiref==3.3.1
astroid==2.5.1
autopep8==1.5.5
beautifulsoup4==4.9.3
black==20.8b1
certifi==2020.12.5
click==7.1.2
Django==3.1.7
django-bootstrap4==2.3.1
django-environ==0.4.5
django-mathfilters==1.0.0
isort @ file:///tmp/build/80754af9/isort_1612243941122/work
.....
- STEP 3 : 開発ソースgit push
- STEP 4 : VPS (dockerがinstallされた仮想machine準備)
GCP compute engine利用
1. compute engine > vm instance作成 (ubuntu 18.04)
2. docker 関連 package install
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ docker -v
=> docker GUI 操作用portainer container作成・実行(portainer doc)
docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
url => compute engine instanceのpublic ip:9000
- STEP 5 : Docker file作成 (.envのSECRET_KEYはテスト用で*開発環境のみ*)
※注意:.envファイルのSECRET_KEYは本番には反映しないよう。開発用
FROM python:3.9.2
WORKDIR /home/
RUN git clone https://github.com/cit007/pinterest.git
WORKDIR /home/pinterest/
RUN echo "SECRET_KEY=xxxxx>.env
RUN pip install -r requirements.txt
RUN python manage.py migrate
EXPOSE 80
CMD ["python", "manage.py", "runserver", "0.0.0.0"]
- STEP 6 : Imageファイル作成
=> Images > uplaod tabから[STEP 5]で作成したDockerfileを選択し imageを作成
- 作成したpinterest_test_image:1イメージをcontainer実行(vm instance ssh)
$ docker run -d -p 8000:8000 pinterest_test_image:1
49e9fd614c93788a504f1a9f53b2a6c1d691b4e2d2f2e2644a565b5f4bd584aa
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
49e9fd614c93 pinterest_test_image:1 "python manage.py ru…" 6 seconds ago Up 5 seconds 0.0.0.0:8
000->8000/tcp vigorous_jones
493d0d9891fa portainer/portainer-ce "/portainer" About a minute ago Up About a minute 8000/tcp,
0.0.0.0:9000->9000/tcp portainer
a153e7ee9bd7 nginx "/docker-entrypoint.…" 43 hours ago Up 43 hours 0.0.0.0:8
0->80/tcp pinterest_nginx
◾️ 開発用としてPython Web ApplicationをDocker container実行しましたが、
本番ではこのようにデプロイするとNG. djangoを本番リリースし、runserverなどのコマンドを直接使用しないように注意を呼びかけている。(ref site)
=> Gunicorn利用してデプロイするため、requirements.txtファイルにgunicorn dependency追加して新しいイメージ作成し、デプロイする
$ pip install gunicorn
$ pip freeze > requirements.txt
$ git add requirements.txt
$ git commit -m "gunicorn package"
$ git push origin master
- Dockerfile再作成してDocker image作成
※ portainer利用でDockerfile uploadし、以前のcacheが影響するので注意
# CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
CMD ["gunicorn", "project-name.wsgi", "--bind", "0.0.0.0:8000"]
- cssなどが正しく提供されてない問題
$ docker run -d -p 8000:8000 pinterest_gunicorn:1
94b688e9548997c8afbc79ef0aee8db65753e0078b3cae6b82186172c3c5576e
root@pinterest-instance-1:/home/itcho0077# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
94b688e95489 pinterest_gunicorn:1 "gunicorn pragmatic.…" 4 seconds ago Up 3 seconds 0.0.0.0:800
0->8000/tcp thirsty_cannon
493d0d9891fa portainer/portainer-ce "/portainer" About an hour ago Up About an hour 8000/tcp, 0
.0.0.0:9000->9000/tcp portainer
a153e7ee9bd7 nginx "/docker-entrypoint.…" 44 hours ago Up 44 hours 0.0.0.0:80-
>80/tcp pinterest_nginx
◾️ DockerでpythonアプリをNGINXとGUNICORNで起動
NGINX container <-------GUNICORN------->Django container
1. request http://xxx.xxx.xxx.xxx:80
2. route request http://pinterest_gunicorn:8000 -> Django container
(NGINX containerとDjango containerは同じDocker networkにする)
- Docker network作成
◾️ pinterest_gunincorn:1 イメージを利用してdocker network選択しdjango_container作成
- GUNICORN 設定ファイル作成(site)
- 作成したnginx.conf ファイルをvm instance upload
-> nginx container経由でdjango container接続成功
◾️ staticfiles(python manage.py collectstatic)作成・NGINXとの連携手順
RUN python manage.py migrate
RUN python manage.py collectstatic
EXPOSE 8000
# CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
CMD ["gunicorn", "pragmatic.wsgi", "--bind", "0.0.0.0:8000"]
-> Dockerfileに collectstatic実行のイメージ(pinterest_gunicorn:2)作成
- static file対応のため既存container削除
root@pinterest-instance-1:/home/itcho0077# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d33d8a264522 nginx:latest "/docker-entrypoint.…" 2 days ago Up 2 days 0.0.0.0:80->80/tcp nginx_container
b163ad821764 pinterest_gunicorn:1 "gunicorn pragmatic.…" 2 days ago Up 2 days 8000/tcp django_container
493d0d9891fa portainer/portainer-ce "/portainer" 3 days ago Up 3 days 8000/tcp, 0.0.0.0:9000->9000/tcp portainer
root@pinterest-instance-1:/home/itcho0077# docker stop d33d8a264522 b163ad821764
d33d8a264522
b163ad821764
root@pinterest-instance-1:/home/itcho0077# docker rm d33d8a264522 b163ad821764
d33d8a264522
b163ad821764
- create static volume (static / media)
- create djnago container (同じnetwork設定)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
- create nginx-container (同じnetwork選択)
root@pinterest-instance-1:/home/itcho0077# cat nginx.conf
worker_processes auto;
events {
}
http {
server {
listen 80;
include mime.types;
location /static/ {
alias /data/static/;
}
location /media/ {
alias /data/media/;
}
location / {
proxy_pass http://django_container:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
◾️ mariadb container(using named volume)利用して環境構築する方法
- named volume作成(dbData)後、mariadb container作成
2. 次のDockerfileを利用してdjango_container用image(pinterest_gunicorn:3)作成
FROM python:3.9.2
WORKDIR /home/
RUN git clone https://github.com/cit007/pinterest.git
WORKDIR /home/pinterest/
RUN pip install -r requirements.txt
RUN pip install gunicorn
RUN pip install mysqlclient
RUN echo "SECRET_KEY=xxx" > .env
# RUN python manage.py migrate
RUN python manage.py collectstatic
EXPOSE 8000
# CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
# CMD ["gunicorn", "pragmatic.wsgi", "--bind", "0.0.0.0:8000"]
CMD ["bash", "-c", "python manage.py migrate --settings=pragmatic.settings.prod && gunicorn pragmatic.wsgi --env DJANGO_SETTINGS_MODULE=pragmatic.settings.prod --bind 0.0.0.0:8000"]
–settings=pragmatic.settings.prod
gunicorn pragmatic.wsgi –env DJANGO_SETTINGS_MODULE=pragmatic.settings.prod
3. develop/production deploy用ファイル構成
- 修正前:pragmatic > settings.py
- 修正後:pragmatic > setting > base.py(既存settings.pyの元) | dev.py | prod.py
DEPLOYし、dev.py とprod.pyそれぞれのDATABASESなどを設定
※ containerそれぞれ設定が毎回複雑で面倒です。各containerをdocker swarmを利用してservice化し、問題発生し自動起動するようにしましょう!