Djangoroidの奮闘記

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

Elastic Beanstalk EC2-単一Containerにnginx+uwsgi+djangoを入れてみる (途中で挫折編)

概要

Elastic Beanstalk EC2-単一Containerにnginx+uwsgi+djangoでデプロイしてみる。 途中で挫折しました。。。

参考サイト

qiita.com

やって見たこと

  • Ubuntu Containerを作って必要なモジュールなどをinstallしておく。
  • サンプルのdjangoアプリを作る。
  • uwsgiでアプリを表示させてみる。
  • nginx+uwsgiでアプリを表示させてみる。
  • その設定のdockerfileを書いてみる。
  • DockerfileをlocalのPCで走らせてみる。
  • Dockerfileをebにデプロイしてみる。

Ubuntuのcontainerを起動させて、必要なパッケージなどをinstallする。

# ubuntuのimageからcontainerを起動させる。
$ docker run -it ubuntu /bin/bash

# 以下は、container内で必要なパッケージをinstallする
root@ee02ed11cd1a:/# apt-get update
root@ee02ed11cd1a:/# apt-get -y upgrade
root@ee02ed11cd1a:/# apt-get -y install python-dev python-pip nginx
root@ee02ed11cd1a:/# pip install -U pip
root@ee02ed11cd1a:/# pip install django uwsgi

これで一旦container側の設定は完了!

サンプルのdjangoアプリを作成する。

# 適当な環境をpyenvで作成する
$ pyenv activate EBDjangoNginx
$ pip install -U pip
$ pip install django (これは、container内のdjangoとversionは合わせておく必要はあり)

# djangoプロジェクトの作成
$ django-admin startproject mysite
$ cd mysite

# djangoアプリの作成
$ python manage.py startapp hello

settings.pyを少し編集する。

# mysite/settings.py

LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'

INSTALLED_APPS = [
         'hello',
]

hello/views.py を編集

from django.http import HttpResponse
from django.shortcuts import render


def main(request):
        return HttpResponse("Hello!")

mysite/urls.pyを編集

from django.conf.urls import url
from django.contrib import admin
import hello.views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^hello/', hello.views.main, name='hello'),
]

ちゃんと表示されるか試してみる。

$ python manage.py migrate
$ python manage.py runserver

http://127.0.0.1:8000/hello/にアクセスしてみる。。。Hello!と表示された!

djangoアプリをcontainerに移してみる。

https://hub.docker.com/_/django/

djangoの公式docker imageの解説によると、

WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .

とあるので、さっき作ったhelloアプリのコードは、/usr/src/app/以下に配置すればいいと思われる。 なので、mysite以下のファイルを全て/usr/src/app/に配置してみる。

# ホストPC->containerにファイルをコピーしてみる。
$ docker cp . ee02ed11cd1a:/usr/src/app/

一応ちゃんとcpされているか、container内部から確認してみる。

$ docker start ee02ed11cd1a
$ docker attach ee02ed11cd1a

root@ee02ed11cd1a:/# cd usr/src/app/
root@ee02ed11cd1a:/usr/src/app# ls
db.sqlite3  hello  manage.py  mysite

おー、一応ちゃんと入ってるぽいな(^ ^) containerでもちゃんと動くか確認してみる。

# python manage.py runserver

無事動いた!ただ、container内で実行しているだけなので、これでは表示はできない。 一旦、containerからexitして、portなどを指定して実行してみる。。。。

と思ったけど、一度起動した後に、port指定するのは、ちょっとめんどくさいぽいので、今回のcontainerを元に、imageを作って、新しいcontainerを作るか〜(^ ^;)ミスった。。。

Dockerfile(第1段階)を作ってみる。

djangoの公式イメージを参考に以下の通り設定した。

FROM ubuntu

RUN apt-get update \
    && apt-get -y upgrade \
    && apt-get install -y --no-install-recommends \
        python-dev python-pip nginx \
        postgresql-client \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .

EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

EXPOSEはよくワカンらんけど、containerのポートを公開するということだから、container間のリンクで使われることが多いみたい。 blog.devneko.net

多分今回の例では要らないけど、今後Dockerfile修正するときに、必要になるかも知んないから入れておこう。

いざ build!

$ docker build -t ebdjaninx .

error発生!!

Exception: you need a C compiler to build uWSGI

どうも、公式サイトによると、build-essential, python-devが必要な模様。なので、以下の通り修正して再度トライ!

Dockerfile

RUN apt-get update \
    && apt-get -y upgrade \
    && apt-get install -y --no-install-recommends \
        python-dev python-pip nginx build-essential\
        postgresql-client \
        python-setuptools \
    && rm -rf /var/lib/apt/lists/*

いざビルド!

$ docker build -t ebdjaninx .

通った!次はコンテナでテストしてみる。

作ったimageで、containerをrunさせてみる。

$ docker run -d -p 8000:8000 d3c22fd7feb5(コンテナID)

できた!

これは、ホストpcの8000を、containerの8000に繋いでcontainerを起動するという指示。(逆なのかな。containerからホストPCにつなぐのかな。)

試しに、127.0.0.1:8000にアクセスしてみると、ちゃんと動いとるな!

これで準備はできてきたので、あとは、uwsgiと、nginxを設定する感じだなぁ。

・・・

結構頑張ったつもりでしたが、自力でuwsgi, nginxの設定は無理でした(^ ^;) ということで、すでにnginx, uwsgi, djangoで設定されている、docker hubのimageを使って進めてみることにします。