当サイトは、アフィリエイト広告を利用しています
PythonのWEBフレームワークであるDjangoの開発環境を
Dockerコンテナを使って構築してみる。
Dockerコンテナを使って開発環境を構築することで
ローカルマシンには基本的にはDocker以外をインストールしないので
ローカルの環境を汚さずできる。
また開発環境は構築はVScodeの拡張機能であるdevcontainerを使って
VScode上で行い、構築後もVScodeから操作できるようにする。
DockerとDjangoに関しては下記の書籍を参考にした
二冊とも初心者でもかなりわかりやすかったのでおススメです。
Dockerを使ってコンテナ内でDjangoの開発環境を作る
下記の環境で行う
Docker for Windowsのインストール方法については下記記事で 紹介しています
devcontainerの詳しい使い方については下記記事で
まとめています
プロジェクトは最終的には下記のような構成になる
.├── .devcontainer│ └── devcontainer.json├── docker│ ├── Dockerfile│ ├── docker-compose.yml│ └── requirements.txt└── dockerdjango├── db.sqlite3├── djangoapp│ ├── __init__.py│ ├── admin.py│ ├── apps.py│ ├── migrations│ │ ├── __init__.py│ │ └── __pycache__│ │ └── __init__.cpython-310.pyc│ ├── models.py│ ├── tests.py│ ├── urls.py│ └── views.py├── dockerdjango│ ├── __init__.py│ ├── asgi.py│ ├── settings.py│ ├── urls.py│ └── wsgi.py└── manage.py
各ディレクトリについて下記のような役割
Dockerコンテナ内の開発をVScodeからできる拡張機能
Devcontainerの設定ファイルを格納している
Djangoを使ってプロジェクトを開始した時に作成される
ディレクトリ。
ここがDjangoのメインとなる。
Djangoの開発環境コンテナを作成するための
dockerfileなど、コンテナ作成に関わるファイルを格納する
構成は最終的には上記のようになるが
作業中に作っていくファイルもあるのでここからは
順に説明していく。
まずはDjangoを使うためにPythonのコンテナを作成する
コンテナ作成に使うファイルはdockerディレクトリにまとめてある
コンテナはdocker-composeを使って作成する
コンテナはDjangoでWEBアプリを動かすための
の二つを用意する
クライアント用コンテナはちょっとした検証に使うので
実際、開発するだけの場合はなくてもいい。
version: "3"services:# サーバーdjango:container_name: "django"# Dockerfileをビルドbuild:context: .dockerfile: Dockerfiletty: true# プロジェクトをバインドマウントvolumes:- ../:/workspace# ポートマッピングを指定ports:- 8000:8000# クライアントclient:container_name: "client"image: python:3.10tty: true
各項目について少し解説する
trueにするとコンテナ内で対話的なシェルセッションを開始できる
※コンテナ内に入って操作するならつけといたほうが無難。
「ホスト側の相対Path:コンテナの絶対Path」で設定し
ホストとコンテナのvolumeをバインドさせる
ここではプロジェクトとworkspaceをバインドさせる
ボリュームにバインドさせることデータは永続化され
仮にコンテナを誤って消してもデータは消えない
※逆に言えば、バインドしていないとコンテナを消した時点で
コンテナの中身も飛ぶので注意!
ホストマシンのポートとコンテナ内のポートのマッピングを指定する
この設定をすれば、コンテナ内のポート8000にはホストのポート8000から
アクセスすることができる。
※ポート番号8000にしているのは8000はDjangoサーバーのデフォルトのポート番号のため
特に使われているとかでなければ8000を指定しておく。
Djangoコンテナのimageを作るためのDockerfileを作成する
# イメージFROM python:3.10# workspaceディレクトリを作成WORKDIR /workspace# workspaceにrequirements.txtをコピーCOPY requirements.txt /workspace/# requirements.txtのパッケージをインストールRUN pip install --upgrade pipRUN pip install -r requirements.txt
必要なパッケージのインストールは
「requirements.txt」
を使って行う
開発に必要なPythonのパッケージを記述する
Django==4.2.6
今は開発環境を作るだけなので「Django」のみを
書いている。
プロジェクトで他に必要になった場合はここに追加して
コンテナを作り直す、またはコンテナ内でpip installして対応する。
VScodeの拡張機能であるdevcontainerの設定ファイルも
ここで作成しておく
{// コンテナ名"name": "dockerdjango",// コンテナ作成に使うdocker-comopseファイルの相対パス"dockerComposeFile": "../docker/docker-compose.yml",// サービス名"service": "django",// コンテナ内のプロジェクトのルートフォルダを指定"workspaceFolder": "/workspace",// コンテナ停止時のアクション"shutdownAction": "stopCompose",// コンテナに入れるVScodeの拡張機能"extensions": ["ms-python.python","ms-toolsai.jupyter","mhutchie.git-graph"]}
service名はdocker-compose.ymlのservicesで設定したものと
一致させておく。
extensionsではコンテナにインストールするVScodeの拡張機能
をあらかじめ設定できる
vscodeのdevcontainerを使ってコンテナを作る
Docker for Windowsの場合は、Dockerを起動させておく
※させてないとできないので
F1でコマンドパレットを開いて、「コンテナを再度、開く」
を選択する
コンテナの作成の成功すると
下記のような画面になる
左下にコンテナ名が表示されている
ファイルに関してはプロジェクトごとバインドマウントしているので
そのまま表示されている
Djangoがインストールされてるか確認する
VScodeのターミナルで下記コマンドで確認できる
$ python -m django --version4.2.6
ターミナルはdockerに入った状態になっている
ここまででPythonのコンテナの作成は完了
Djangoが動かすためのPythonコンテナが作成できたので
実際にDjangoのプロジェクトを作成する
Djangoプロジェクトを作成する
作成は下記コマンドで実行する
django-admin startproject < project-name >
< project-name >に任意のプロジェクト名を設定する
今は「dockerdjango」で進める
django-admin startproject dockerdjango
実行すると下記のようなディレクトリとファイルが作成される
.├── .devcontainer│ └── devcontainer.json├── docker│ ├── Dockerfile│ ├── docker-compose.yml│ └── requirements.txt└── dockerdjango├── dockerdjango│ ├── __init__.py│ ├── asgi.py│ ├── settings.py│ ├── urls.py│ └── wsgi.py└── manage.py
まだこの後、プロジェクト配下にアプリを作成して
いくが、一旦、ここでDjangoサーバーを起動してアクセルできるか
確認する
Djangoサーバーの起動はmanage.pyがあるディレクトリに移動し
下記のコマンドで起動できる
python manage.py runserver
実際に起動してみる
$ cd dockerdjango/$ python manage.py runserverWatching for file changes with StatReloaderPerforming system checks...System check identified no issues (0 silenced).You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.Run 'python manage.py migrate' to apply them.October 24, 2023 - 14:31:43Django version 4.2.6, using settings 'dockerdjango.settings'Starting development server at http://127.0.0.1:8000/Quit the server with CONTROL-C.
起動できたので
次は下記のようにIPとポート番号を指定してDjangoサーバーを起動する
$ python manage.py runserver 0:8000Watching for file changes with StatReloaderPerforming system checks...System check identified no issues (0 silenced).You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.Run 'python manage.py migrate' to apply them.October 24, 2023 - 14:36:23Django version 4.2.6, using settings 'dockerdjango.settings'Starting development server at http://0.0.0.0:8000/Quit the server with CONTROL-C.
そして「http://localhost:8000/」
にアクセスすると
のようにDjangoの初期画面が表示される
Dockerのコンテナは、コンテナがそれぞれ独立した環境を持っているため
デフォルトではホストOSからアクセスできない状態になっている
そしてDjangoサーバーがデフォルトで待ち受けるIPアドレスが127.0.0.1(localhost)
のためIP、ポート番号なしで起動してもホストからはアクセスできない。
そのため起動時に
を指定して起動することでホストからアクセス可能になる。
ここまでで一応、Djangoプロジェクトを起動できたが
実際使う時はアプリを作るとおもうので簡単なアプリまで作ってみる
Djangoにおける「アプリ(App)」は
Django Webフレームワーク内の機能的なコンポーネントのことで
アプリケーション内の特定の機能セットを実装し、管理するための独立したモジュールになる。
イメージとしては下記のような感じ
プロジェクトに機能ごとのコンポーネント(アプリ)
がぶら下がっているイメージ
実際にアプリを作ってみる
アプリはmanage.pyがあるフォルダで下記コマンドを実行する
python manage.py startapp < app-name >
今は「djangoapp」で作る
python manage.py startapp djangoapp
作成後は下記のような構成になる
.├── .devcontainer│ └── devcontainer.json├── docker│ ├── Dockerfile│ ├── docker-compose.yml│ └── requirements.txt└── dockerdjango├── db.sqlite3├── djangoapp│ ├── __init__.py│ ├── admin.py│ ├── apps.py│ ├── migrations│ │ └── __init__.py│ ├── models.py│ ├── tests.py│ └── views.py├── dockerdjango│ ├── __init__.py│ ├── __pycache__│ │ ├── __init__.cpython-310.pyc│ │ ├── settings.cpython-310.pyc│ │ ├── urls.cpython-310.pyc│ │ └── wsgi.cpython-310.pyc│ ├── asgi.py│ ├── settings.py│ ├── urls.py│ └── wsgi.py└── manage.py
アプリができたので簡単に実装して
動かしてみる
プロジェクト(dockerdjango)とそれにぶら下がっているアプリ(djangoapp)
を作ったので実際に実装して動かしてみる。
まずは作成したアプリをプロジェクトにする
~INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','djangoapp.apps.DjangoappConfig']~
「DjangoappConfig」は下記のクラス名と合わせる
from django.apps import AppConfigclass DjangoappConfig(AppConfig):default_auto_field = 'django.db.models.BigAutoField'name = 'djangoapp'
DjangoウェブアプリケーションのURLパターンとビューを定義するためのファイル
URLのパスとそれに関連するビュー関数をマッピングする
プロジェクトとアプリにそれぞれurls.pyあるので編集する
※ない場合は作る
アプリのurls.pyから作る
アプリのurls.pyは自動で作成されないので自分で作る。
from django.urls import pathfrom .views import djangoappfuncurlpatterns = [path('djangoapp/', djangoappfunc),]
「djangoapp/」のpathでdjangoappfunc関数(あとで作る)を
呼び出すように設定しておく。
次はプロジェクトのurls.pyを編集する
※こちらは自動で作成されてている
from django.contrib import adminfrom django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),path('app/', include('djangoapp.urls')),]
includeでdjangoappのurls.pyを読み込むように設定する
これで'app'でアクセスが来た場合、アプリのurls.pyのパターンを
探しにいくようになる
これで
「http://localhost:8000/app/djangoapp/」
にアクセスするとdjangoappfunc関数の戻り値が画面に表示される
urlのマッピング設定はできたので、次はviews.pyで
djangoappfunc関数を定義する
from django.http import HttpResponsedef djangoappfunc(request):return HttpResponse("hello world")
文字列を返すだけの関数を実装しておく。
実装は終わったので実際に動かして動作を確認してみる
Djangoサーバーの起動はmanage.pyがあるディレクトリで
下記コマンドを実行する
$ python manage.py runserver 0:8000
繰り返しになるが、Dockerコンテナの中でDjangoサーバーを
起動しているのでホストのブラウザからアクセスするために
で起動する。
起動後、「http://localhost:8000/app/djangoapp/」に
アクセスすると下記のようになる
~HTTP request sent, awaiting response... 400 Bad Request2023-11-02 16:53:49 ERROR 400: Bad Request.~
上記のような通信エラーがでる場合は
setting.pyのALLOWED_HOSTSを設定することで解決できる
settings.pyのALLOWED_HOSTSに全てを許可するようにしておく
ALLOWED_HOSTS = ['*']
DjangoのALLOWED_HOSTS設定は
ウェブアプリケーションが受け入れることが許可されている
ホスト(ドメインまたはIPアドレス)のリストを指定するための重要なセキュリティ設定
開発時は「*」でいいが、本番にあげる時は厳密に設定する必要がある。
ホストからではなく別のコンテナ(クライアントコンテナ)
からアクセスしてみる。
同様に下記コマンドでDjangoサーバーを起動する
$ python manage.py runserver 0:8000
そしてクライアントコンテナから「http://localhost:8000/app/djangoapp/」
に対してアクセスをwgetで行うと下記のようなエラーとなる
$ wget http://localhost:8000/app/djangoapp/--2023-10-25 13:03:25-- http://localhost:8000/app/djangoapp/Resolving localhost (localhost)... 127.0.0.1, ::1Connecting to localhost (localhost)|127.0.0.1|:8000... failed: Connection refused.Connecting to localhost (localhost)|::1|:8000... failed: Cannot assign requested address.Retrying.~
localhostはホストから見たときの話なので別のコンテナからは
アクセスできない。
アクセスするためには
settings.pyのALLOWED_HOSTSにコンテナのサービス名を加える
ALLOWED_HOSTS = ['django']
そして
「http://django:8000/app/djangoapp/」
でアクセスしてやれば通信できる
$ wget http://django:8000/app/djangoapp/--2023-10-25 13:09:16-- http://django:8000/app/djangoapp/Resolving django (django)... 172.31.0.2Connecting to django (django)|172.31.0.2|:8000... connected.HTTP request sent, awaiting response... 200 OKLength: 11 [text/html]Saving to: ‘index.html.1’index.html.1 100%[==================================================================================================================>] 11 --.-KB/s in 0s2023-10-25 13:09:16 (1.48 MB/s) - ‘index.html.1’ saved [11/11]
取得したhtmlを確認すると
hello world
となっており通信できることがわかる
最初はプロジェクトがないので、Djangoサーバーを起動させることは
できないが、プロジェクト作成後はdocker-composeで実行時に一緒に
Djangoサーバーを起動させるようにできる
version: "3"services:# サーバーdjango:container_name: "django"# Dockerfileをビルドbuild:context: .dockerfile: Dockerfiletty: true# プロジェクトをバインドマウントvolumes:- ../:/workspace# ポートマッピングを指定ports:- 8000:8000# Djangoサーバーを起動するコマンドを追加# command: ["python", "/workspace/djangoPararel/dockerdjango/manage.py", "runserver", "0:8000"]command: >-python /workspace/dockerdjango/manage.py runserver 0:8000# クライアントclient:container_name: "client"image: python:3.10tty: true
docker-compose.ymlにサーバーを起動するコマンドを追記する
Dockerを使ってPythonのDjangoフレームワークを使って開発環境を
構築してみた。
Djangoサーバーと通信するあたりで少しつまづいたが
Dockerの仕様を考えることで解決できた。
まだ使い出したところだがWEBフレームワークとしては
割と使いやすそうと感じた。
構築したコンテナ上のDjangoをVScodeでのデバッグ方法については下記でまとめています