Dockerを利用したDjangoの簡単な構築方法

Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.

Dockerとは,動作が非常に軽量であり,コンテナを使用してアプリケーションを構築,テスト,デプロイできるソフトウェアプラットフォームである.

今回は,Dockerを利用したDjangoの簡単な構築方法をこの記事にて記す.

実施環境

OS: Windows11
Visual Studio Code (VS Code) 1.75.1

Djangoを利用した簡単な構築方法

Djangoの簡単な構築方法

以下のようにDesk Topにディレクトリ"Django_test_230213″を作成する.

VS Codeを起動させる.

以下のように画面が開くので,"File"をクリックし,"Open Filder"を選択し,上記のディレクトリを選択する.

“Terminal"をクリックし,"New Terminal"を選択する.

Terminalにて,以下コマンドを実行し,Djangoをインストールする.

$ pipenv install django

以下コマンドを実行し,仮想環境にsubshellをlaunchする.

$ pipenv shell

以下コマンドを実行し,djangotestprojectを作成する.

$ django-admin startproject djangotestproject

以下コマンドを実行し,ディレクトリを"djangotestproject"上に移動する.

$ cd djangotestproject

以下コマンドを実行し,djangotestappを作成する.

$ django-admin startapp djangotestapp

“views.py"を以下のように編集する.

from django.http import HttpResponse

def first_view(request):
    return HttpResponse("I am learning Django and Docker")

“djangotestproject"内の"urls.py"をコピーし,"djangotestapp"内に貼り付ける."djangotestapp/urls.py"を以下のように編集する.

from django.urls import path
from .views import first_view

urlpatterns = [
    path('', first_view),
]

“djangotestproject/urls.py"を以下のように編集する.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('djangotestapp.urls'))
]

“djangotestproject/settings.py"の"INSTALLED_APP"を以下のように編集する.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djangotestapp', # 追記箇所
]

terminalに戻り,以下コマンドを実行する."http://127.0.0.1:8000/"をクリックすると,ブラウザが開く.

$ python manage.py runserver

Watching for file changes with StatReloader
Performing 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.
February 13, 2023 - 05:21:10
Django version 4.1.6, using settings 'djangotestproject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

“djangotestapp/views.py"に記載した以下文言が,ブラウザに出力される.

Dockerfileの作成

事前に以下URLにて,Docker Desktopをインストールする.

docker docs | Install Docker Desktop on Windows

“djangotestproject"プロジェクトに,"Dockerfile"を作成する.なお,"Pipfile"と"Pipfile.lock"を"djangotestproject"プロジェクトの下に移動させておく.

以下のようなpopも出現するので,"Install"をクリックする.

“djangotestproject/Dockerfile"を以下のように編集する.

FROM python:3.11

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /code

COPY Pipfile Pipfile.lock /code/
RUN pip install pipenv && pipenv install --system

COPY . /code/

“Pipfile"および"Pipfile.lock"を"djangotestproject"プロジェクトのディレクトリ内に移動させ,当該ディレクトリ上で以下コマンドを実行すると,ファイルおよびディレクトリ構造を確認できる.

$ ls


    ディレクトリ: C:\Users\shiro\Desktop\Django_test_230213\djangotestproject


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----     2023/02/13 月      4:57                djangotestapp
d-----     2023/02/13 月      4:41                djangotestproject
-a----     2023/02/13 月      5:21              0 db.sqlite3
-a----     2023/02/13 月      5:56            196 Dockerfile
-a----     2023/02/13 月      4:41            695 manage.py
-a----     2023/02/13 月      4:16            152 Pipfile
-a----     2023/02/13 月      4:16           1777 Pipfile.lock

以下コマンドを実行し,dockerを構築する.

$ docker build .

以下コマンドを実行すると,docker imageの一覧を確認できる.

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
<none>       <none>    408d415bc660   4 minutes ago   1.01GB

Docker Compose Fileの作成

VS Codeを開き,"djangotestproject"プロジェクトの下に"docker-compose.yml"ファイルを作成する.

作成したymlファイルを以下のように編集する.

version : '3.11' # python version

services:
  web:
    build: . # current directory
    container_name: web
    command: >
      bash -c "python manage.py runserver 0.0.0.0:8000"
    ports:
      - 10555:8000

terminalを開き,"djangotestproject"ディレクトリに移動し,以下コマンドを実行する.

# docker compose up

[+] Building 2.5s (10/10) FINISHED
 => [internal] load build definition from Dockerfile                                             0.1s
 => => transferring dockerfile: 235B                                                             0.0s 
 => [internal] load .dockerignore                                                                0.1s 
 => => transferring context: 2B                                                                  0.0s
 => [internal] load metadata for docker.io/library/python:3.11                                   1.8s 
 => [1/5] FROM docker.io/library/python:3.11@sha256:e7e3b031dbf71514d0a8d759d8417b04f8dcf483aec  0.0s
 => [internal] load build context                                                                0.2s 
 => => transferring context: 9.14kB                                                              0.0s
 => CACHED [2/5] WORKDIR /code                                                                   0.0s 
 => CACHED [3/5] COPY Pipfile Pipfile.lock /code/                                                0.0s 
 => CACHED [4/5] RUN pip install pipenv && pipenv install --system                               0.0s 
 => [5/5] COPY . /code/                                                                          0.2s
 => exporting to image                                                                           0.2s
 => => exporting layers                                                                          0.1s 
 => => writing image sha256:05d0a44a7a735e4457dfa283bec5166815db6ee483223f59e5c137e5870fb62e     0.0s 
 => => naming to docker.io/library/djangotestproject-web                                         0.0s 
[+] Running 2/2
 - Network djangotestproject_default  Created                                                    0.6s 
 - Container web                      Created                                                    0.2s
Attaching to web
web  | Watching for file changes with StatReloader
web  | Performing system checks...
web  |
web  | System check identified no issues (0 silenced).
web  | 
web  | You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
web  | Run 'python manage.py migrate' to apply them.
web  | February 13, 2023 - 15:04:09
web  | Django version 4.1.6, using settings 'djangotestproject.settings'
web  | Starting development server at http://0.0.0.0:8000/
web  | Quit the server with CONTROL-C.

ブラウザのURLに"localhost:10555″と入力すると,以下のように構築したDjangoの内容が反映される.

追加のcompose command

上記にて実行したdocker compose upは止めず,実行しているterminalとは別に新たなterminalを作成する."djangotestproject"プロジェクトにて,以下コマンドを実行すると,以下のようなファイル構成となっている.

$ ls


    ディレクトリ: C:\Users\shiro\Desktop\Django_test_230213\djangotestproject


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----     2023/02/13 月      4:57                djangotestapp
d-----     2023/02/13 月      4:41                djangotestproject
-a----     2023/02/13 月      5:21              0 db.sqlite3
-a----     2023/02/13 月     23:58            226 docker-compose.yml
-a----     2023/02/13 月      6:14            196 Dockerfile
-a----     2023/02/13 月      4:41            695 manage.py
-a----     2023/02/13 月      4:16            152 Pipfile
-a----     2023/02/13 月      4:16           1777 Pipfile.lock

以下コマンドを実行すると,docker composeコマンドの一覧が出力される.

$ docker compose --help

Usage:  docker compose [OPTIONS] COMMAND

Docker Compose

Options:
      --ansi string                Control when to print ANSI control
                                   characters ("never"|"always"|"auto")
                                   (default "auto")
      --compatibility              Run compose in backward compatibility mode
      --env-file string            Specify an alternate environment file.
  -f, --file stringArray           Compose configuration files
      --parallel int               Control max parallelism, -1 for
                                   unlimited (default -1)
      --profile stringArray        Specify a profile to enable
      --project-directory string   Specify an alternate working directory
                                   (default: the path of the, first
                                   specified, Compose file)
  -p, --project-name string        Project name

Commands:
  build       Build or rebuild services
  convert     Converts the compose file to platform's canonical format
  cp          Copy files/folders between a service container and the local filesystem
  create      Creates containers for a service.
  down        Stop and remove containers, networks
  events      Receive real time events from containers.
  exec        Execute a command in a running container.
  images      List images used by the created containers
  kill        Force stop service containers.
  logs        View output from containers
  ls          List running compose projects
  pause       Pause services
  port        Print the public port for a port binding.
  ps          List containers
  pull        Pull service images
  push        Push service images
  restart     Restart service containers
  rm          Removes stopped service containers
  run         Run a one-off command on a service.
  start       Start services
  stop        Stop services
  top         Display the running processes
  unpause     Unpause services
  up          Create and start containers
  version     Show the Docker Compose version information

Run 'docker compose COMMAND --help' for more information on a command.

以下コマンドを実行すると,現在実行中のcompose projectのリストを確認できる.

$ docker compose ls

NAME                STATUS              CONFIG FILES
djangotestproject   running(1)          C:\Users\shiro\Desktop\Django_test_230213\djangotestproject\docker-compose.yml

以下コマンドを実行すると,containerのリストを確認できる.

$ docker compose ps
NAME                IMAGE                   COMMAND                  SERVICE             CREATED             STATUS              PORTS
web                 djangotestproject-web   "bash -c 'python man…"   web                 23 minutes ago      Up 7 minutes        0.0.0.0:10555->8000/tcp

以下コマンドを実行すると,containerからのoutputを確認できる.

$ docker compose logs

web  | Watching for file changes with StatReloader
web  | Performing system checks...
web  |
web  | System check identified no issues (0 silenced).
web  |
web  | You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
web  | Run 'python manage.py migrate' to apply them.
web  | February 13, 2023 - 15:04:09
web  | Django version 4.1.6, using settings 'djangotestproject.settings'
web  | Starting development server at http://0.0.0.0:8000/
web  | Quit the server with CONTROL-C.
web  | [13/Feb/2023 15:06:02] "GET / HTTP/1.1" 200 31
web  | Not Found: /favicon.ico
web  | [13/Feb/2023 15:06:03] "GET /favicon.ico HTTP/1.1" 404 2269
web  | [13/Feb/2023 15:06:15] "GET / HTTP/1.1" 200 31
web  | Not Found: /favicon.ico
web  | [13/Feb/2023 15:06:15] "GET /favicon.ico HTTP/1.1" 404 2269
web  | Watching for file changes with StatReloader
web  | Performing system checks...
web  |
web  | System check identified no issues (0 silenced).
web  |
web  | You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
web  | Run 'python manage.py migrate' to apply them.
web  | February 13, 2023 - 15:20:21
web  | Django version 4.1.6, using settings 'djangotestproject.settings'
web  | Starting development server at http://0.0.0.0:8000/
web  | Quit the server with CONTROL-C.
web  | [13/Feb/2023 15:20:26] "GET / HTTP/1.1" 200 31
web  | [13/Feb/2023 15:21:22] "GET / HTTP/1.1" 200 31

なお,以下コマンドを実行すると,containerとネットワークが止まり,削除される.

$ docker compose down

[+] Running 2/2
 - Container web                      Removed                                         0.5s 
 - Network djangotestproject_default  Removed                                         0.6s

今回は削除せずに,ブラウザに出力する内容を変える.以下のように"views.py"を変更する.

from django.http import HttpResponse

# Create your views here.
def first_view(request):
    return HttpResponse("I am learning Django, Docker and Docker compose") # 変更箇所

terminalに戻り,以下コマンドを実行する.

$ docker compose build

[+] Building 2.0s (10/10) FINISHED
 => [internal] load build definition from Dockerfile                                  0.0s
 => => transferring dockerfile: 32B                                                   0.0s 
 => [internal] load .dockerignore                                                     0.0s 
 => => transferring context: 2B                                                       0.0s 
 => [internal] load metadata for docker.io/library/python:3.11                        1.6s 
 => [internal] load build context                                                     0.0s
 => => transferring context: 1.10kB                                                   0.0s 
 => [1/5] FROM docker.io/library/python:3.11@sha256:e7e3b031dbf71514d0a8d759d8417b04  0.0s 
 => CACHED [2/5] WORKDIR /code                                                        0.0s 
 => CACHED [3/5] COPY Pipfile Pipfile.lock /code/                                     0.0s 
 => CACHED [4/5] RUN pip install pipenv && pipenv install --system                    0.0s 
 => [5/5] COPY . /code/                                                               0.1s
 => exporting to image                                                                0.1s
 => => exporting layers                                                               0.1s 
 => => writing image sha256:a0b2f5b7e348dccf2efdba8692f6de070589aaff59661902679c9f7c  0.0s 
 => => naming to docker.io/library/djangotestproject-web                              0.0s 

その後,以下コマンドを実行する.

$ docker compose up

[+] Running 2/2
 - Network djangotestproject_default  Created                                         0.7s 
 - Container web                      Created                                         0.1s
Attaching to web
web  | Watching for file changes with StatReloader
web  | Performing system checks...
web  |
web  | System check identified no issues (0 silenced).
web  | 
web  | You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
web  | Run 'python manage.py migrate' to apply them.
web  | February 13, 2023 - 15:43:41
web  | Django version 4.1.6, using settings 'djangotestproject.settings'
web  | Starting development server at http://0.0.0.0:8000/
web  | Quit the server with CONTROL-C.

ブラウザのURLに"localhost:10555″と入力すると,"views.py"を変更した後の内容が反映される.

containerの内部への移動

現状,上記で作成したdockerは動き続けている.

$ docker compose ps
NAME                IMAGE                   COMMAND                  SERVICE             CREATED             STATUS              PORTS
web                 djangotestproject-web   "bash -c 'python man…"   web                 8 minutes ago       Up 13 seconds       0.0.0.0:10555->8000/tcp

以下コマンドを実行すると,containerの中に入ることができる.

docker exec -it web /bin/bash
root@b8e6ce384760:/code# 

以下コマンドを実行すると,containerのファイル構成や現在の位置を確認することができる.

/code# ls
Dockerfile  Pipfile.lock  djangotestapp      docker-compose.yml
Pipfile     db.sqlite3    djangotestproject  manage.py

/code# pwd
/code

以下コマンドを実行すると,varディレクトリおよびlibディレクトリ下のファイル構成を確認することができる.

/code# cd /var
/var# ls
backups  cache  lib  local  lock  log  mail  opt  run  spool  tmp

/var# cd lib

/var/lib# ls
apt  dpkg  git  misc  pam  python  systemd  ucf

Volumeのマウント

上記では,"views.py"の内容を反映させるためには,"docker compose down"を実行し,内容を更新後,"docker compose build"から"docker compose up"を実行する必要があった."mount a volume"を実施することで,自動的にsyncさせる方法を記す.

“views.py"を以下のように編集する.

from django.http import HttpResponse

# Create your views here.
def first_view(request):
    return HttpResponse("I am learning Django and Docker Volumes!!") # 変更箇所

“docker-compose.yml"を以下のように編集する.

version : '3.11' # python version

services:
  web:
    build: . # current directory
    container_name: web
    command: >
      bash -c "python manage.py runserver 0.0.0.0:8000"
    ports:
      - 10555:8000
    volumes: # 以下が変更点(working directoryを記す)
      - .:/code

terminalで以下コマンドを実行する.

$ docker compose build

$ docker compose up

rebuildしたので,当然"views.py"の内容が反映される.

“views.py"のみ以下のように編集する.

from django.http import HttpResponse

# Create your views here.
def first_view(request):
    return HttpResponse("I am learning Django and Docker Volumes!! They are great!") # 変更点

ブラウザを確認すると,すぐに反映していることが確認できる.

参照

Udemy | Docker for Python Django Developers

docker docs | Volumes

docker docs | Bind mounts

docker hub | mariadb

以上