Elastic Beanstalk で,django+S3に、minicondaを加えてみる。
前の記事
pythonskywalker.hatenablog.com
やってみたこと
- minicondaの公式のdockerfileを少し修正する。
- minicondaのimageをdocker hubに登録する。
- そのimageを前の記事のDockerfileに挿入する。
- Dockerfileからbuildする。(local)
- localで成功したら、ECRに登録する。
- Dockerrun.aws.jsonでEBにデプロイする。
minicondaの公式のdockerfileを少し修正する。
FROM nabladesignlabs/eb-miniconda ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \ libglib2.0-0 libxext6 libsm6 libxrender1 \ libgtk2.0-0 \ git mercurial subversion RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \ wget --quiet https://repo.continuum.io/miniconda/Miniconda3-4.1.11-Linux-x86_64.sh -O ~/miniconda.sh && \ /bin/bash ~/miniconda.sh -b -p /opt/conda && \ rm ~/miniconda.sh RUN apt-get install -y curl grep sed dpkg && \ TINI_VERSION=`curl https://github.com/krallin/tini/releases/latest | grep -o "/v.*\"" | sed 's:^..\(.*\).$:\1:'` && \ curl -L "https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini_${TINI_VERSION}.deb" > tini.deb && \ dpkg -i tini.deb && \ rm tini.deb && \ apt-get clean ENV PATH /opt/conda/bin:$PATH
- ENTRYPOINTと、CMDは不要なので、削除しておく。
minicondaのimageをdocker hubに登録する。
上記のDockerfileをgithub経由で、automated_createしてdocker hubに登録する。
そのimageを前の記事のDockerfileに挿入する。
FROM python:2.7 RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi COPY /myapp/requirements.txt /requirements.txt RUN pip install -r /requirements.txt COPY /myapp /app RUN chown -R uwsgi /app COPY uwsgi.sh /uwsgi.sh RUN chmod +x /uwsgi.sh CMD ./uwsgi.sh
localでbuildしてみる。
$ docker build -t test . Error: pg_config executable not found.
。。。Error!!
libpq-dev
が必要らしいので、入れてみる。
この時に、dockerhub/eb-miniconda を上書きしたい場合は、
$ docker pull イメージ識別
のコマンドを入力する。再度ビルド。。。
$ docker build -t test . # error psycopg2 unable to execute 'gcc': No such file or directory error: command 'gcc' failed with exit status 1 # error uwsgi Exception: you need a C compiler to build uWSGI
うーん、またerror。
- gcc ->
apt-get install gcc
- C compiler ->
build-essential
,python-dev
が必要みたいなので、追加する。
再度build....
$ docker build -t ebtest . Successfully built
local成功!!これをECRに登録する。
ECRに登録
$ aws ecr get-login --region ap-northeast-1 $ docker login -u AWS -p .... 長い数字 $ docker build -t リポジトリ名 . $ docker tag リポジトリ名:latest リポジトリのURI:latest $ docker push リポジトリのURI:latest
Elastic Beanstalkにデプロイ
ERROR: Failed to start ECS task:
またerror!! Errorの順番的に、これは、ECSがうまくスタートできてないことが原因ぽいなぁ。。。
ECSに関しては、eb-ecs-mgr.log
をみると色々書いてあるらしい。。。
CS task stopped due to: Essential container in task exited.
どうも、コンテナのタスクがexitしてるのが原因でタスクが止まっているぽい。状況がよくわからないので、ECSコンソール->クラスター、タスク定義あたりをみてみる。
warnとか出てて、止まってた! これを一旦全てタスク解除して再度デプロイしてみる。
Encountered error starting new ECS task: { "failures": [ { "reason": "INACTIVE", "arn": "**************" } ], "tasks": [] }
やはり同じエラーが発生。。。reason INACTIVEとのこと。
aws公式サイトのQAを見てみる。
INACTIVE (container instance ID) The container instance that you attempted to launch a task onto was previously deregistered with Amazon ECS and cannot be used.
-> タスクを準備しようとしているコンテナインスタンスが、ECSから除外されいて、使えないよ。的なことが書いてある。
ECSのタスクとinstanceを見てみる。
停止理由 Essential container in task exited
以下のサイトに答えがあるぽいな。
Amazon ECS Troubleshooting - Amazon EC2 Container Service
Essential container in task exited Containers marked as essential in task definitions cause a task to stop if they exit or die. When an essential container exiting is the cause of a stopped task, the Step 6 can provide more diagnostic information as to why the container stopped.
step6 If you have a container that has stopped, expand the container and inspect the Status reason row to see what caused the task state to change.
とのことで該当箇所を見てみると、やっぱ、Essential container in task exitedとなっている。
ECSクラスターを確認してみると、なんと「ECS インスタンス」がない!なんと! 理由はよくわからないけど、明らかにこれが原因ぽい。以下のサイトにコンテナの追加方法が書いてあった。
でも、これはそもそも、miniconda入りのdockerfile自体がうまく稼働してないこと自体が問題なのかも知れない。
Dockerfileの修正
そもそもlocalでdocker-composeしたけど、うまく動かなかった(^ ^;) 原因を色々探っていたけど、どうもユーザー変更のあたりがうまくいっていないぽい。
なのでまずは、su - uwsgi -c "python /app/manage.py migrate"
を、python /app/manage.py migrate
とroot権限で実行させてみる。
あー、これだとうまくいくな。 でも「rootで実行してるから注意!」みたいな警告が出るからこれはやっぱり危険だ。
今順番的に、minicondaをinstallした後に、uwsgi
というユーザを作成するという手順になっているので、それを逆にしてみよう。。。
あー、これだとできるな!
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi RUN su -m uwsgi RUN apt-get...
よし、これでdokcer-compose up をしてみよう!
あー、通った!!でも、見慣れない警告が、、、
!!! no internal routing support, rebuild with pcre support !!!
とのこと。pcreのサポートで、rebuildしてくださいとのこと。 色々調べてると、debianのサイトにpcreのパッケージが書いてあった。
あと、uwsgiの公式ページにもyou need libssl-dev and pcre headers.
とのことなので、libssl-dev
も入れておく。
apt-get install -y libssl-dev libpcre3 libpcre3-dev \
これでいいはず。。。docker-compose up
してみる。。。あーできた〜!!
これで今度こそ、eb deployできるはず。
ECRに登録
$ aws ecr get-login --region ap-northeast-1 $ docker login -u AWS -p .... 長い数字 $ docker build -t リポジトリ名 . $ docker tag リポジトリ名:latest リポジトリのURI:latest $ docker push リポジトリのURI:latest
Elastic Beanstalk にデプロイ
以下のDockerrun.aws.jsonをアップ。。。できた〜〜!今回の戦いは長かった(^ ^) とりあえず、docker-comoposeで試す->Dockerrun.aws.jsonでデプロイの流れは忘れないようにしよう。
{ "AWSEBDockerrunVersion": 2, "volumes": [ { "name": "app-root", "host": { "sourcePath": "/var/app/current/app/" } } ], "containerDefinitions": [ { "name": "uwsgi", "image": "**********.***.ecr.ap-northeast-1.amazonaws.com/[レポジトリ名]:latest", "essential": true, "memory": 128, "mountPoints": [ { "sourceVolume": "app-root", "containerPath": "/src/app/" } ] }, { "name": "nginx", "image": "nabladesignlabs/nginx-django", "essential": true, "memory": 128, "portMappings": [ { "hostPort": 80, "containerPort": 80 } ], "mountPoints": [ { "sourceVolume": "app-root", "containerPath": "/src/app/" } ], "links": [ "uwsgi" ] } ] }