Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

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 インスタンス」がない!なんと! 理由はよくわからないけど、明らかにこれが原因ぽい。以下のサイトにコンテナの追加方法が書いてあった。

qiita.com

でも、これはそもそも、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のパッケージが書いてあった。

www.cyberciti.biz

あと、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"
      ]
    }
  ]
}