この記事は BeProud Advent Calendar 2018の 13日目の記事です BeProud Advent Calendar 2018 - Adventar普段忙しくてなかなかブログを書けない人のケツを叩くための BeProud アドベントカレンダーです 内容は技術的なことなら何でもOK BeProud に関係してる人なら誰でも、としたいんですが 枠が限られているので [BeProud](https://www.beproud.jp/) の社員か元社員の方に優先的に入ってもらいたい気持ちです カレンダー作成者でも枠の登録削除はできないようなので良識の範囲で登録してください 何かあれば [Twitter](https://twitter.com/crohaco) で連絡くださいhttps://adventar.org/calendars/3338
時代は既に EKS かもしれませんが、 以前案件で ECS
に Django
アプリをデプロイしたので プロジェクト構築手順を 残しておきます。
時間を無駄にしたくないし他の人にもしてほしくないので 俺の屍を超えていけ(定期)
- info
- 実は作るのは2回目なんで、すぐ終わるかなーと思ってたら
権限関係のトラブルが続出して精神が折れかけたので 今回は
AdministratorAccess
権限で作ることにします。 - DNS は Route53 を使おうかと思ったんですが移管とかめんどくさいし、 新ドメインを取るお金がもったいないので別サイトで管理している既存のドメインを使います。
- 今回のシナリオは以下です
- Djampleという私が作成したサンプル用アプリを ECS にデプロイ
- PostgreSQL (RDS) に接続する
- ドメインとして
djample.crohaco.net
を割り当てる - HTTPS 対応する
- 実は作るのは2回目なんで、すぐ終わるかなーと思ってたら
権限関係のトラブルが続出して精神が折れかけたので 今回は
準備
認証情報
グループ と ユーザを作成。
グループには AdministratorAccess
ポリシーを割り当てています。
(なぜ test-user にしなかったのか.)
Setup awscli
Docker イメージをPUSHするのに awscli を使うのでインストールします
$ pip install awscli $ aws --version aws-cli/1.15.60 Python/3.7.0 Darwin/15.6.0 botocore/1.10.59
アクセス情報を設定します。
他の案件と混ざると困るので \--profile
を使って名前空間的なものを区切ります。
$ aws configure --profile djample AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXX AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Default region name [None]: us-west-2 Default output format [None]:
これによって --profile djample
を指定することで
今回登録した認証情報を使うことができるようになりました
リポジトリをクローンする
続いて、デプロイ対象のイメージを作成するためのサンプルプロジェクトを用意します。 GitHub - righ/djample: django sample projectdjango sample project. Contribute to righ/djample development by creating an account on GitHub.https://github.com/righ/djample
$ git clone https://github.com/righ/djample
とりあえず準備はここまでです。
なんか作業が行ったり来たりするのでどこまでを準備としていいのか迷いますが、 長すぎると萎えるのでこのくらいで。
ECR
Dockerリポジトリを作ろう
Docker イメージをPUSHするためのリポジトリを作成します。
- app
- nginx
リポジトリが作成できたら PUSH するためのイメージを作成します
イメージをビルドする
さて、一旦コンソールに戻ります
イメージをビルドするときに毎回、アップデートとかが動くと嫌なので ベースイメージを作ることにします。
$ docker build -t djample-base . Sending build context to Docker daemon 49.51MB Step 1/4 : FROM ubuntu:18.04 AS djample-base ---> 74f8760a2a8b Step 2/4 : RUN useradd www --create-home --shell /bin/bash ---> Using cache ---> 536f8417ec7c Step 3/4 : WORKDIR /home/www ---> Using cache ---> fc05ab643d75 Step 4/4 : RUN set -x; apt-get update -y && apt-get install -y cron && apt-get install -y python3.6 python3-pip python3.6-venv && apt-get install -y postgresql-client && apt-get install -y libpcre3 libpcre3-dev && /usr/bin/python3.6 -m venv venv/ && chown www:www -R venv/ ---> Using cache ---> b352cf8215de Successfully built b352cf8215de Successfully tagged djample-base:latest
続いて、上記のイメージをベースとしてサービスの動作に必要なイメージをビルドします。
それぞれの コンテナを作成するための Dockerfile は
deployment/
に出力したので -f でそのなかの Dockerfile パスを指定します
- app
- nginx
$ docker build -t djample-app . -f deployment/app/Dockerfile Sending build context to Docker daemon 49.51MB Step 1/13 : FROM djample_base:latest ---> b352cf8215de Step 2/13 : ARG requirements="requirements/requirements.txt" ---> Using cache ---> afffa1452c17 Step 3/13 : ARG preprocess="echo start processing" ---> Using cache ---> 384ba1153e6a Step 4/13 : ARG project="djample" ---> Using cache ---> 9d5339019178 Step 5/13 : USER www ---> Using cache ---> 56bcc23886d3 Step 6/13 : RUN mkdir ${project} ---> Using cache ---> 74b1c103567f Step 7/13 : WORKDIR /home/www/${project} ---> Using cache ---> 95086a8bc327 Step 8/13 : ADD apps/ apps/ ---> 9d0bd7ad2939 Step 9/13 : ADD templates/ templates/ ---> 9e837f364578 Step 10/13 : ADD static/ static/ ---> 2e1a601ebd96 Step 11/13 : ADD requirements/ requirements/ ---> c2cb99f51868 Step 12/13 : RUN set -x && ../venv/bin/pip install -r ${requirements} ---> Running in 2a61a9c3b944 + ../venv/bin/pip install -r requirements/requirements.txt Collecting Django==2.0.7 (from -r requirements/run.txt (line 2)) Collecting six==1.11.0 (from -r requirements/run.txt (line 3)) Collecting psycopg2==2.7.5 (from -r requirements/run.txt (line 4)) Collecting psycopg2-binary==2.7.5 (from -r requirements/run.txt (line 5)) Collecting pytz==2018.5 (from -r requirements/run.txt (line 6)) Collecting Jinja2==2.10 (from -r requirements/run.txt (line 7)) Collecting djangorestframework==3.8.2 (from -r requirements/run.txt (line 8)) Collecting uWSGI==2.0.17.1 (from -r requirements/run.txt (line 9)) Collecting MarkupSafe>=0.23 (from Jinja2==2.10->-r requirements/run.txt (line 7)) Downloading https://files.pythonhosted.org/packages/08/04/f2191b50fb7f0712f03f064b71d8b4605190f2178ba02e975a87f7b89a0d/MarkupSafe-1.1.0-cp36-cp36m-manylinux1_x86_64.whl Installing collected packages: pytz, Django, six, psycopg2, psycopg2-binary, MarkupSafe, Jinja2, djangorestframework, uWSGI Successfully installed Django-2.0.7 Jinja2-2.10 MarkupSafe-1.1.0 djangorestframework-3.8.2 psycopg2-2.7.5 psycopg2-binary-2.7.5 pytz-2018.5 six-1.11.0 uWSGI-2.0.17.1 Removing intermediate container 2a61a9c3b944 ---> e7890ce4a544 Step 13/13 : CMD ${preprocess} && ../venv/bin/uwsgi --ini apps/uwsgi.ini ---> Running in eb439b9be16b Removing intermediate container eb439b9be16b ---> 468b3fc446c6 Successfully built 468b3fc446c6 Successfully tagged djample_app:latest
$ docker build -t djample-nginx . -f deployment/nginx/Dockerfile Sending build context to Docker daemon 49.52MB Step 1/19 : FROM node:latest AS webpack ---> 52fe93b8eea7 Step 2/19 : ARG webpack_config="webpack/webpack.prod.js" ---> Using cache ---> f10c7a39da94 Step 3/19 : ADD frontend/ frontend/ ---> Using cache ---> e0791031a12a Step 4/19 : WORKDIR frontend/ ---> Using cache ---> c1cd1acb2433 Step 5/19 : RUN set -x && npm install && $(npm bin)/webpack --config ${webpack_config} ---> Using cache ---> ecde11b80e71 Step 6/19 : FROM djample_base AS app ---> b352cf8215de Step 7/19 : ARG requirements="requirements/requirements.txt" ---> Using cache ---> afffa1452c17 Step 8/19 : WORKDIR /home/www ---> Using cache ---> 02db9470d977 Step 9/19 : ADD apps/ apps/ ---> Using cache ---> 127af7a8471b Step 10/19 : ADD requirements/ requirements/ ---> Using cache ---> f96e2ee6b9a3 Step 11/19 : ADD static/ static/ ---> 6c851b25121b Step 12/19 : RUN set -x && venv/bin/pip install -r ${requirements} && venv/bin/python apps/manage.py collectstatic --noinput --settings=settings.base ---> Running in 31d48872a4f6 + venv/bin/pip install -r requirements/requirements.txt Collecting Django==2.0.7 (from -r requirements/run.txt (line 2)) Collecting six==1.11.0 (from -r requirements/run.txt (line 3)) Collecting psycopg2==2.7.5 (from -r requirements/run.txt (line 4)) Collecting psycopg2-binary==2.7.5 (from -r requirements/run.txt (line 5)) Collecting pytz==2018.5 (from -r requirements/run.txt (line 6)) Collecting Jinja2==2.10 (from -r requirements/run.txt (line 7)) Collecting djangorestframework==3.8.2 (from -r requirements/run.txt (line 8)) Collecting uWSGI==2.0.17.1 (from -r requirements/run.txt (line 9)) Collecting MarkupSafe>=0.23 (from Jinja2==2.10->-r requirements/run.txt (line 7)) Downloading https://files.pythonhosted.org/packages/08/04/f2191b50fb7f0712f03f064b71d8b4605190f2178ba02e975a87f7b89a0d/MarkupSafe-1.1.0-cp36-cp36m-manylinux1_x86_64.whl Installing collected packages: pytz, Django, six, psycopg2, psycopg2-binary, MarkupSafe, Jinja2, djangorestframework, uWSGI Successfully installed Django-2.0.7 Jinja2-2.10 MarkupSafe-1.1.0 djangorestframework-3.8.2 psycopg2-2.7.5 psycopg2-binary-2.7.5 pytz-2018.5 six-1.11.0 uWSGI-2.0.17.1 + venv/bin/python apps/manage.py collectstatic --noinput --settings=settings.base Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/selector-icons.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/calendar-icons.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-calendar.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-deletelink.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-addlink.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/README.txt' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/LICENSE' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-yes.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-alert.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/inline-delete.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-clock.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-changelink.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/tooltag-add.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-unknown.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-no.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/search.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/icon-unknown-alt.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/tooltag-arrowright.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/sorting-icons.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/gis/move_vertex_off.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/img/gis/move_vertex_on.svg' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/LICENSE.txt' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/README.txt' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Regular-webfont.woff' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Bold-webfont.woff' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/fonts/Roboto-Light-webfont.woff' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/base.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/responsive_rtl.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/rtl.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/forms.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/responsive.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/widgets.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/login.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/autocomplete.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/fonts.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/changelists.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/dashboard.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/vendor/select2/LICENSE-SELECT2.md' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/vendor/select2/select2.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/css/vendor/select2/select2.min.css' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/core.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/SelectBox.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/popup_response.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/collapse.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/timeparse.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/collapse.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/inlines.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/actions.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/change_form.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/SelectFilter2.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/cancel.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/actions.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/jquery.init.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/prepopulate_init.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/autocomplete.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/calendar.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/prepopulate.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/urlify.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/inlines.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/prepopulate.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/jquery.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/jquery.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/jquery/LICENSE-JQUERY.txt' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/LICENSE-SELECT2.md' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/select2.full.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/select2.full.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/he.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ru.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ro.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/lv.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sv.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/vi.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/fi.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/eu.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/da.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/nb.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/de.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/zh-CN.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/id.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ca.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/it.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/gl.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/zh-TW.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/pl.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sk.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/az.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/fr.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/es.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ja.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/hr.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/mk.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/hu.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/tr.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/hi.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/nl.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/en.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/bg.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/et.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ar.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sr.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ms.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/el.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/th.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/cs.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/fa.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/sr-Cyrl.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/lt.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/km.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/is.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/pt-BR.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/pt.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/ko.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/select2/i18n/uk.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/xregexp.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/xregexp.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/vendor/xregexp/LICENSE-XREGEXP.txt' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js' Copying '/home/www/venv/lib/python3.6/site-packages/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/img/glyphicons-halflings-white.png' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/img/grid.png' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/img/glyphicons-halflings.png' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.svg' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/fontawesome-webfont.ttf' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.eot' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.ttf' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/glyphicons-halflings-regular.woff2' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/fontawesome-webfont.eot' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/fontawesome-webfont.woff' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/fonts/fontawesome-webfont.svg' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/css/bootstrap.min.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/css/bootstrap-theme.min.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/css/prettify.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/css/font-awesome-4.0.3.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/css/default.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/css/bootstrap-tweaks.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/js/default.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/js/bootstrap.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/js/jquery-3.3.1.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/js/coreapi-0.1.1.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/js/prettify-min.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/js/csrf.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/js/ajax-form.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/img/grid.png' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/img/favicon.ico' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/css/highlight.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/css/jquery.json-view.min.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/css/base.css' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/js/jquery.json-view.min.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/js/highlight.pack.js' Copying '/home/www/venv/lib/python3.6/site-packages/rest_framework/static/rest_framework/docs/js/api.js' 151 static files copied to '/home/www/static', 2 unmodified. Removing intermediate container 31d48872a4f6 ---> 3926aa0a8826 Step 13/19 : FROM nginx:perl ---> 8cf54770ff0a Step 14/19 : ADD deployment/nginx/uwsgi_params /etc/nginx/uwsgi_params ---> 27023a82e194 Step 15/19 : ADD deployment/nginx/nginx.conf /etc/nginx/nginx.conf ---> 802c94a3f80f Step 16/19 : ADD deployment/nginx/conf.d/ /etc/nginx/conf.d/ ---> 6b984577c912 Step 17/19 : COPY --from=app /home/www/static/ /usr/share/nginx/static/ ---> 9f3f12e4d8b4 Step 18/19 : COPY --from=webpack frontend/assets/ /usr/share/nginx/static/assets/ ---> 097978bd29a3 Step 19/19 : CMD ["nginx", "-g", "daemon off;"] ---> Running in 0c0dd0cf6337 Removing intermediate container 0c0dd0cf6337 ---> 87edefa4dbbc Successfully built 87edefa4dbbc Successfully tagged djample_nginx:latest
イメージをPUSHする
プライベートなコンテナリポジトリを使う場合、docker クライアントで認証が必要になります。
今回は AWS ということもあり ECR を使うことにするので、 awscli から認証していきます。
とはいっても簡単で、 aws ecr
のコマンドで
認証コマンドが出力されるので $()
で囲んでそのまま実行してあげるだけです。
# profile とか リージョンは各自変えること $(aws --profile djample ecr get-login --no-include-email --region us-west-2) WARNING! Using --password via the CLI is insecure. Use --password-stdin. Login Succeeded
上記のように Login Succeeded
とでれば認証成功です。
おめでとうございます。いやまだ続くけど。
- info
An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::XXXXXXXXXXXX:user/test-djample is not authorized to perform: ecr:GetAuthorizationToken on resource: \*
と出る場合、AmazonEC2ContainerServiceforEC2Role
が足りていないので追加する- Amazon ECR エラーメッセージのトラブルシューティング - Amazon ECRhttps://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/common-errors.html
- Amazon ECRhttps://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/ECR_IAM_policies.html
少し経つと有効になります。多分 AdministratorAccess
だと発生しません
- djample-app
- djample-nginx
$ docker tag djample-app:latest XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app:latest $ docker push XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app:latest The push refers to repository [XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-app] 6836c8c88b45: Pushed 615d45681fa6: Pushed 15b6883e063f: Pushed c5eee45b9f53: Pushed 8e771df6e17b: Pushed dab2c9255521: Pushed 016210a3d295: Pushed ef7a479213de: Pushed 374f3534200b: Pushed 8fec0692e6a1: Pushed 219d5a9f3bbe: Pushed 67b9b2a215ea: Pushed 956940650d5d: Pushed latest: digest: sha256:6e78416aee66fd997e9d3eacb15ee602a14dba76a72fcb0dbc100dcd39f4c6f8 size: 3031
$ docker tag djample-nginx:latest XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx:latest $ docker push XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx:latest The push refers to repository [XXXXXXXXXXXX.dkr.ecr.us-west-2.amazonaws.com/djample-nginx] f514a6aae98f: Pushed 82544808b996: Pushed 942f421fc8f4: Pushed 67f95e015a50: Pushed 3803fdb990e6: Pushed 5871f1dd9014: Pushed 4cc529071e3b: Pushed cdb3f9544e4c: Pushed latest: digest: sha256:8b467500656e208d712a8ae7cb25f13896cf81e207d891469e9848b8da6f7d93 size: 1987
- info
- 上記をやっても
no basic auth credentials
と出た場合、リージョンが間違っている可能性があります。 denied: User: arn:aws:iam::XXXXXXXXXXXX:user/test-djample is not authorized to perform: ecr:InitiateLayerUpload on resource: arn:aws:ecr:us-west-2:XXXXXXXXXXXX:repository/djample-app
と出る場合、AmazonEC2ContainerRegistryPowerUser
が足りていないので追加する- Amazon ECRhttps://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/ecr_managed_policies.html#AmazonEC2ContainerRegistryPowerUser
- ERROR: The request could not be satisfiedhttps://forums.aws.amazon.com/thread.jspa?threadID=223156
- 少し経つと有効になります。多分
AdministratorAccess
だと発生しません
- 上記をやっても
さて、コンソールでの操作は以上です。
証明書
HTTPS でアクセスするために、証明書を発行します。
何故かメール認証を選択しても全然メールが来なかったので DNS で認証することにします。
DNS に CNAME で 認証情報を登録します。 先頭の _
は入力しなくてOKです。
認証が終わったようです
VPCを作る
今回は Create Default VPC で Default VPC を作成します.
Default VPC を作ると 3つのサブネットも自動的に作成され 3つのアベイラビリティゾーンに割り振られるようです。
- info
- 後述するロードバランサが 2つ以上のサブネットを必要とするので、自分でVPCを作る場合はサブネット分割をする必要があります。
- CIDR とかよくわからない場合は (他のサービスに影響がないなら) デフォルトVPC を使えばよいです
Security group
AWSではアクセス制御に セキュリティグループを用います。
今回も作っていきましょう。
EC2 dashboard から 2つの Security group を作成します。
Web 用
Inbound で 80, 443 だけ許可します
DB 用
Web のセキュリティグループからのみアクセスできるようにします。
Inbound の設定で TCP5432 の通信を djample-web のセキュリティグループからのみ許可します
RDS instance
DBもイメージにしてよかったんですが、普通はホストも分けたいと思うので今回は RDS の PostgreSQL (最小スペック)にします。
- ユーザ
- djampleuser
- パスワード
- djamplepass
- DB
- djampledb
で PostgreSQL を 建てます。
VPC と セキュリティグループは先ほど作成したものをアタッチしましょう.
今回、エンドポイントは
djample.civihq7xgpb5.us-west-2.rds.amazonaws.com
で作成されました
- info
パブリックアクセシビリティを有効にしないとアドレスが発行されません
[The VPC vpc-XXXXXXX associated with the default subnet group does not exist. Please delete the default subnet group or specify another subnet group. (Service: AmazonRDS; Status Code: 400; Error Code: InvalidVPCNetworkStateFault; Request ID: 3a0fea9b-9262-49fa-b194-464b4475079b)] のように言われる場合、 RDS のメニューから
Subnet groups
を開き、該当するサブネットグループを削除するとうまくいくようです。罠だろこれ。あなたが神か
I know it\'s closed, but to help someone searching on google, I\'ve deleted a vpc and created a new default vpc and I got this problem, to solve this, I go to Amazon RDS > Subnet groups > and I deleted the subnet group, and worked
ロードバランサーを作成する
Fargate に振り分けるためにロードバランサが必要なので作成しましょう。
EC2 dashboard から操作します。
Target Groups
後述する Load Balancer に設定するために Target group を先に作成します。
- Target type は IP を設定
- VPC は 先程作成したものと同じものを設定
その他はデフォルトで Create します。
Load Balancer
ロードバランサーを作成します。 選択するのは Application Load Balancer
(通称:ALB) です。
今回は HTTPS での通信に対応するために Listeners に HTTPS
を追加します
HTTPS に対応する場合 次のページで セキュリティの設定があります。
- 証明書を作成している場合は、ここで選択できます。
- セキュリティポリシーについては特にこだわりがないので
ELBSecurityPolicy-2016-08
を使います
セキュリティグループには先ほど作成したグループを指定します。
ルーティングの設定では 先ほど作成した target-grouop を指定します。
Register Targes
はスルーして、入力に問題がなければ作成してしまいましょう。
作成された Load balancer の URL をDNSにも登録します (このUIはスタードメインのものです)
- info
- Route53 を使っている場合はそちらで登録してください。
ECS
さて、ようやく パーツが揃いました。
ここからは ECS の設定です。
Task Definition (for web service)
ECS における処理の最小単位は Task です。
Web サービス用のタスクを作成します。
- Task Role を指定
- Requires compatibilities には
FARGATE
を作成 - Task size は最小を指定
Container
使用するコンテナを指定
- Container name には識別するためのコンテナ名を指定
- Image には ECR に登録した リポジトリの URL を指定
- DockerHubなど別のリポジトリに登録されている場合はそれを指定しても良い
- コンテナが開放しているポート番号をポートマッピングに指定
- 設定値などの環境変数を指定
- djample-app
- uwsgi が 3031 ポートで待ち受けているので
3031
をポートマッピングに指定 - DjangoのDB接続情報を環境変数で渡すようにしたので、先程のRDSの情報を割り当てます。
- 環境変数名は settings の変数名を
__
で区切ったものにしました。 - 詳細は settings/env.pyを参照
- uwsgi が 3031 ポートで待ち受けているので
- djample-nginx
- ポートマッピングに 80 (HTTP) を指定
- info
- Task はバージョンで管理されており、変更する場合は新たなリビジョンを追加することで対応します
- 後述するサービスに指定するときもリビジョン番号まで含めて指定する
Task Role
がない場合、 IAM Console からecsTaskExecutionRole
を作成- ロールのポリシーが足りないと
CannotPullECRContainerError
やCannotStartContainerError
が発生します - 今回は
AdministratorAccess
をアタッチしました
- ロールのポリシーが足りないと
- Task はバージョンで管理されており、変更する場合は新たなリビジョンを追加することで対応します
Cluster
今回は Fargate
を選択します
クラスタ名を指定し、 VPC は先程のものを使うので作成しません。
Service
クラスタの中に サービスを作成します
- Task Definition には先ほど作成した
djample-web
を指定します。- タスク定義は新たなリビジョンを作って変更するため、リビジョン番号まで含めて指定する
- (いろいろ試行錯誤したため revision が進んでます)
- サービス名は
web
にしました - デプロイタイプはローリングアップデートにします
ネットワーク設定には VPC と セキュリティグループには先ほど作成したグループを指定します。 先程作成したものを指定します。
Load balancing には application Load Balancer
を選択し、
先ほど作成した djample-alb
を指定します。
コンテナ名:ポート
に nginx:80:80
を指定し
Add to load balancer
ボタンをクリックすると
設定画面が開くので リスナーポートとターゲットグループ名を指定します
- その他は デフォルトで次のページへ
- オートスケーリングは今回指定せずに次へ
- 確認して問題なければそのまま作成
クラスタに割り当てたURLにアクセスしてみると
見れました!
では Django admin にログインしようとすると
500 エラーが出ました。
これはテーブルがないからですね
- info
- ここで 503 が出る場合、ロードバランサーの設定がおかしいです。 多分target group とかかな?
- 当該ドメインは削除済みなのでアクセスできません。
migration task
DBを初期化するためのマイグレーション用のタスクを作ります。
web サービス用のタスクと環境変数が共通しているので使いまわして作ることにします。
djample-web
を選択して Create new revision
で開いて、タスク名を変更します。 今回は djample-migration
にします。ほかは変えない
Container 定義に移動して次のように操作します。ほかは変えない。
djample-nginx
はこのタスクでは不要なので消します (消さなくても動くけど意味ない)djample-app
コンテナを開いてコンテナで実行するコマンドを指定します。- ENVIRONMENT(環境)セクションに移動して、マイグレーションコマンドを指定します
../venv/bin/python3,apps/manage.py,migrate,--settings=settings.env
- 区切り文字は スペースではなく
,
(カンマ) なので注意
- 区切り文字は スペースではなく
Action から Run Task
を選択
- info
- いろいろ設定してますが、セキュリティグループは
djample-web
だけで良かったと思います- デフォルトで新規作成になっているので、既存のセキュリティグループから選択しましょう。
- subnet は多分一つで十分です
- いろいろ設定してますが、セキュリティグループは
実行がおわりました
もう一度適当にログインしてみましょう。
エラーが変わりました。DBには接続できているみたいですがレコードがないエラーですね。
無事アクセスできているようなのでこれで終わってもいいんですが、せっかくなんでログインまでしてみたいと思います。
createuser task
当該アプリでは createuser ってコマンドを用意してあるので、これをラップするタスクを使ってユーザを作成してみましょう。
migration タスクをコピーして名前を変更
あとは実行コマンドを変更します.
admin/admin
の superuser を作ります- パスワードの指定がない場合は Joe (ユーザ名==パスワード)になります
--superuser
を指定すると スーパーユーザになる- このとき 自動的にスタッフになる
'
(シングルクォート) は引用符ではなくそのままユーザ名に採用されてしまうので注意
先ほどと同じように実行します。終わったようです。
ログインしてみます
できましたーーーーーーー
終わりっ
参考
How to Deploy Docker Containers | AWShttps://aws.amazon.com/getting-started/hands-on/deploy-docker-containers/ ECS+ECR環境でDockerコンテナをデプロイする - Qiita#前置きDockerで開発環境が動作するようになったはいいけれど、これだけではまだ道半ば。開発で使用したDockerイメージがそのまんま本番環境にデプロイされるところまでいってなんぼでしょう。…https://qiita.com/furu8ma/items/6dcf596ee67780e8807f
他にも参考にしたサイトがあったと思うんだけど、リンクを取っておくの忘れました;; ごめんなさい