自分で作るDocker/Djangoバックエンド開発環境構築手順

Django
記事内に広告が含まれています。

PythonのフルスタックWebフレームワークと言えば、Djangoというくらいに有名です。当然Docker Hubに公式イメージがあるんだと思っていましたが、この通り現在は(実際は2016年からなので随分前から)非推奨(DEPRECATED)となっていました。

非推奨なのであれば自分で作るしかないと思いこの記事を書きました。開発者の皆さんの助けになればいいなと思います。

またDjango REST frameworkも同様に公式イメージがないので手作りする方が安心かなと思いました。

  1. この記事を読んでできるようになること
  2. Docker Desktopの使い方
  3. Pipenvの使い方
  4. DjangoとDjango REST frameworkの違い
  5. Djangoのインストール
    1. リポジトリ用ディレクトリの作成
      1. コマンド(ターミナル1)
    2. リポジトリディレクトリの移動
      1. コマンド(ターミナル1)
    3. PythonのDocker公式イメージへの起動とログイン
      1. コマンド(ターミナル1)
    4. pipコマンドのアップグレード
      1. コマンド(ターミナル1)
      2. 出力結果(ターミナル1)
    5. pipenvのインストール
      1. コマンド(ターミナル1)
      2. 出力結果(ターミナル1)
    6. DjangoおよびDjango REST frameworkのインストール
      1. コマンド(ターミナル1)
      2. 出力結果
  6. Django REST frameworkのプロジェクト作成
    1. Django REST framework用プロジェクトのディレクトリ作成
      1. コマンド(ターミナル1)
    2. Django REST framework用プロジェクトのディレクトリへの移動
      1. コマンド(ターミナル1)
    3. Pipenvシェルの起動
      1. コマンド(ターミナル1)
    4. Djangoプロジェクトの作成
      1. コマンド(ターミナル1)
    5. Djangoプロジェクトディレクトリへの移動
      1. コマンド(ターミナル1)
    6. Djangoアプリケーションの作成
      1. コマンド(ターミナル1)
      2. ディレクトリ階層
    7. データベースマイグレーション
      1. コマンド(ターミナル1)
      2. コマンド(ターミナル1)
      3. 出力結果
    8. 管理ユーザーの作成
      1. コマンド(ターミナル1)
      2. 入力&出力結果
    9. Serializersの作成
    10. Viewsの作成
    11. URLsの作成
    12. Settings
      1. Pagination
      2. Django REST frameworkの設定
    13. Dockerイメージの保存
      1. コマンド(ターミナル2)
      2. 出力結果(ターミナル2)
      3. コマンド(ターミナル2)
      4. コマンド(ターミナル1)
    14. Django開発サーバの起動
      1. コマンド
    15. 動作確認
      1. トップ画面(ログイン前)
      2. ログイン画面
      3. トップ画面(ログイン後)
      4. User List
      5. User Instance
  7. 付録
  8. まとめ

この記事を読んでできるようになること

  • お手元のPCでDjangoを使ったWebアプリ開発ができるようになります。
  • PythonのDocker公式イメージを使ってDjango開発環境を構築する方法を学習できます。
  • DjangoとDjango REST frameworkを組み合わせたバックエンド開発ができるようになります。

Docker Desktopの使い方

Docker Desktopのインストール方法に関しては以下記事をご参考ください。

Pipenvの使い方

Pipenvの使い方に関しては以下記事をご参考ください。

DjangoとDjango REST frameworkの違い

DjangoはWebアプリケーションフレームワークです。Ruby on Railsなどと同じ位置付けです。

Django
The web framework for perfectionists with deadlines.

対してDjango REST frameworkは、DjangoにREST APIを組み込むためのライブラリです。

Home - Django REST framework
Django, API, REST, Home

Djangoのインストール

本記事ではターミナルを複数使うので、ターミナル1とターミナル2という形で分けて書いております。

リポジトリ用ディレクトリの作成

コマンド(ターミナル1)

私の場合、リポジトリ関係はホームディレクトリ内のreposというディレクトリ内に保存しています。そこにdjangoというgitプロジェクトを作成しています。ちなみに「~」はチルダといい、ホームディレクトリを意味します。ディレクトリの作成は皆さんのお好きなようにやってください。

mkdir -p ~/repos/drf-on-docker

リポジトリディレクトリの移動

コマンド(ターミナル1)

先ほど作成したディレクトリに移動します。

cd ~/repos/drf-on-docker

PythonのDocker公式イメージへの起動とログイン

コマンド(ターミナル1)

先ほど作成した~/repos/djangoディレクトリをPythonコンテナ内の/appディレクトリにマウントし、コンテナ名をdjangoと名付け、bashでログインします。

docker run -it --rm -v $(pwd):/app -w /app --name django python:latest /bin/bash

pipコマンドのアップグレード

コマンド(ターミナル1)

Pythonイメージは、最初からpipコマンドがインストールされていますが、そのバージョンが古いので予めアップデートしておきます。ここはそんなに重要ではないです。無視しても警告が出るくらいです。

pip install --upgrade pip

出力結果(ターミナル1)

WARNING: Running pip as the ‘root’ user can result in.. という警告が出ていますが、Dockerコンテナ内で作業する以上はrootユーザーになってしまうので無視して大丈夫です。

Requirement already satisfied: pip in /usr/local/lib/python3.12/site-packages (23.2.1)
Collecting pip
  Obtaining dependency information for pip from https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl.metadata
  Downloading pip-24.0-py3-none-any.whl.metadata (3.6 kB)
Downloading pip-24.0-py3-none-any.whl (2.1 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 3.7 MB/s eta 0:00:00
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 23.2.1
    Uninstalling pip-23.2.1:
      Successfully uninstalled pip-23.2.1
Successfully installed pip-24.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

pipenvのインストール

コマンド(ターミナル1)

パッケージ管理コマンドのpipenvをインストールします。

pip install pipenv

出力結果(ターミナル1)

Successfully installedから始まるメッセージにpipenvが含まれていればインストールが正常に終了したと判断していいでしょう。同様の警告メッセージが出ますが無視してください。

Collecting pipenv
  Downloading pipenv-2023.12.1-py3-none-any.whl.metadata (19 kB)
Collecting certifi (from pipenv)
  Downloading certifi-2024.2.2-py3-none-any.whl.metadata (2.2 kB)
Requirement already satisfied: setuptools>=67 in /usr/local/lib/python3.12/site-packages (from pipenv) (69.0.3)
Collecting virtualenv>=20.24.2 (from pipenv)
  Downloading virtualenv-20.25.0-py3-none-any.whl.metadata (4.5 kB)
Collecting distlib<1,>=0.3.7 (from virtualenv>=20.24.2->pipenv)
  Downloading distlib-0.3.8-py2.py3-none-any.whl.metadata (5.1 kB)
Collecting filelock<4,>=3.12.2 (from virtualenv>=20.24.2->pipenv)
  Downloading filelock-3.13.1-py3-none-any.whl.metadata (2.8 kB)
Collecting platformdirs<5,>=3.9.1 (from virtualenv>=20.24.2->pipenv)
  Downloading platformdirs-4.2.0-py3-none-any.whl.metadata (11 kB)
Downloading pipenv-2023.12.1-py3-none-any.whl (3.1 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.1/3.1 MB 471.0 kB/s eta 0:00:00
Downloading virtualenv-20.25.0-py3-none-any.whl (3.8 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.8/3.8 MB 1.3 MB/s eta 0:00:00
Downloading certifi-2024.2.2-py3-none-any.whl (163 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 163.8/163.8 kB 1.2 MB/s eta 0:00:00
Downloading distlib-0.3.8-py2.py3-none-any.whl (468 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 468.9/468.9 kB 2.4 MB/s eta 0:00:00
Downloading filelock-3.13.1-py3-none-any.whl (11 kB)
Downloading platformdirs-4.2.0-py3-none-any.whl (17 kB)
Installing collected packages: distlib, platformdirs, filelock, certifi, virtualenv, pipenv
Successfully installed certifi-2024.2.2 distlib-0.3.8 filelock-3.13.1 pipenv-2023.12.1 platformdirs-4.2.0 virtualenv-20.25.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

DjangoおよびDjango REST frameworkのインストール

コマンド(ターミナル1)

djangoおよびdjangorestframeworkをインストールします。

pipenv install django djangorestframework

出力結果

Creating a virtualenv for this project...
Pipfile: /app/Pipfile
Using default python from /usr/local/bin/python (3.12.1) to create virtualenv...
⠋ Creating virtual environment...created virtual environment CPython3.12.1.final.0-64 in 89ms
  creator CPython3Posix(dest=/root/.local/share/virtualenvs/app-4PlAip0Q, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
    added seed packages: pip==24.0
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment!
Virtualenv location: /root/.local/share/virtualenvs/app-4PlAip0Q
Creating a Pipfile for this project...
Installing django...
Resolving django...
Added django to Pipfile's [packages] ...
✔ Installation Succeeded
Installing djangorestframework...
Resolving djangorestframework...
Added djangorestframework to Pipfile's [packages] ...
✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock (709498677962b597deb7755151c892205b5602857f054bab7de772221152085a)!
Installing dependencies from Pipfile.lock (52085a)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

Django REST frameworkのプロジェクト作成

ここからDjango REST frameworkのプロジェクト作成に入ります。

Django REST framework用プロジェクトのディレクトリ作成

コマンド(ターミナル1)

Django REST framework用のプロジェクトディレクトリを作成します。ここではわかりやすくprojectとします。

mkdir project

Django REST framework用プロジェクトのディレクトリへの移動

コマンド(ターミナル1)

先ほど作成したprojectディレクトリに移動します。

cd project

Pipenvシェルの起動

コマンド(ターミナル1)

pipenvの仮想環境にログインします。

pipenv shell

Djangoプロジェクトの作成

Djangoプロジェクトを作成します。最後のドット(.)必要なので注意してください。

コマンド(ターミナル1)

django-admin startproject project .

Djangoプロジェクトディレクトリへの移動

projectディレクトリに移動します。

コマンド(ターミナル1)

cd project/

Djangoアプリケーションの作成

Djangoアプリケーションを作成します。ここではわかりやすくappとします。

コマンド(ターミナル1)

django-admin startapp app

ディレクトリ階層

.
├── Pipfile
├── Pipfile.lock
├── manage.py
└── project
    ├── __init__.py
    ├── app
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

データベースマイグレーション

初回のデータベースマイグレーションを行います。

コマンド(ターミナル1)

ディレクトリを移動します。

cd /app

コマンド(ターミナル1)

python manage.py migrate

出力結果

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

管理ユーザーの作成

コマンド(ターミナル1)

python manage.py createsuperuser --username admin --email [email protected]

入力&出力結果

パスワードを2回入力してください。

Password:
Password (again):
Superuser created successfully.

Serializersの作成

Serializersとはデータ表現のためのクラスです。今回は project/app/serializers.py を作成します。お好みのIDEかエディタで作成し保存してください。

from django.contrib.auth.models import Group, User
from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'groups']


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ['url', 'name']

Viewsの作成

Viewsは他のWebフレームワークでいうところのビジネスロジックにあたるところです。今回はproject/app/views.py を作成します。

from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsets

from project.app.serializers import GroupSerializer, UserSerializer


class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]


class GroupViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer
    permission_classes = [permissions.IsAuthenticated]

URLsの作成

URLsは他のWebフレームワークでいうところのディスパッチャです。どのパスにアクセスしてきた時にどのメソッドを呼び出すかなどを定義します。今回はproject/urls.py を作成します。

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

from project.app import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]

urlpatterns += router.urls

Settings

SettingsはDjangoの設定ファイルです。今回はproject/settings.pyを作成します。

Pagination

ページネーションとは表示件数が多い時などに一定の件数ずつ表示する機能です。

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

Django REST frameworkの設定

INSTALLED_APPS‘rest_framework’, を追加しください。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]

Dockerイメージの保存

コマンド(ターミナル2)

ここまでの状態をDockerイメージとして保存したいと思います。そのためには、別ターミナルを開きdjangoコンテナのIDを知る必要があります。別ターミナルから以下コマンドを実行してください。

docker ps -a | grep django

出力結果(ターミナル2)

一番左に出るIDがコンテナIDです。それをコピーしてください。

892f0a022dec   python:latest                                                  "/bin/bash"              2 minutes ago   Up 2 minutes                                                                  django

ちなみにターミナル1側のプロンプトに表示されているroot@以下のコロンまでの間の値もコンテナIDになりますのでそちらをコピーしても大丈夫です。

root@892f0a022dec:/app#

コマンド(ターミナル2)

先ほど開いた別ターミナルでDockerイメージを保存します。docker commitコマンドを使用し、-aオプションには’作者の名前 <メールアドレス>‘、-mオプションにはコミットメッセージ先ほどコピーしたコンテナIDコンテナのイメージ名を指定します。

docker commit -a '名前 <メールアドレス>' -m 'Install django' 892f0a022dec django:latest

コマンド(ターミナル1)

/bin/bashでログインしているターミナルは不要になったのでDockerコンテナからログアウトします。

exit

Django開発サーバの起動

コマンド

Djangoの開発用サーバを起動します。注意点としてはDockerコンテナとして起動するので、0.0.0.0:8000が重要になってきます。これがないとデフォルトで127.0.0.0:8000で起動することになり、あくまでコンテナ内部でしかアクセスできない形になってしまいます。また-pオプションで8000:8000を指定していますがこちらも重要です。これはコンテナで待ち受けている8000番ポートを自身のPCの8000番ポートに転送する設定になります。

docker run -it --rm -v $(pwd):/app -p 8000:8000 --name django django:latest pipenv run python manage.py runserver 0.0.0.0:8000

動作確認

トップ画面(ログイン前)

このURL http://localhost:8000 にアクセスしてみましょう。 以下のようなページが表示されるはずです。またアクセスするたびにターミナルにアクセスログが記録されることが確認できると思います。右上にあるログインボタンでログインすることができます。

ログイン画面

トップ画面(ログイン後)

ログイン後の画面です。右上がadminになっています。Django REST frameworkだとログアウトできないので、Django Adminからログアウトすれば、Djang REST frameworkからもログアウトされます。

User List

User Listへのアクセスした様子。resultsキーが配列で返ってきていることがわかります。

User Instance

User Listへのアクセスした様子。User IDとして指定したデータだけ返ってきています。

付録

ここまでターミナル1で構築し、ターミナル2で docker commit を行うという方法でやってきましたが、毎回こういうことは実施しません。これまでの手順をDockerfileにまとめてすぐ実行できるようにしました。また今後の拡張性を考慮し、docker composeコマンドで起動できるようにしております。やり方はREADME.mdに書かれておりますのでその通りに実行してください。

Files · v0.1.0 · Tadashi Inagaki / drf-on-docker · GitLab
GitLab.com

まとめ

PythonのオフィシャルDockerイメージを使って、一気にDjango Rest frameworkを動かすところまで見てきました。基本的にはコピペで構築できるようになっているはずです。今回は開発環境としての環境構築手順になります。本番環境ではアプリケーションサーバをuWSGIとGunicornなどにする必要がありますし、静的コンテンツなどを抜き出してWebサーバに配置したりなどすること盛りだくさんです。なのでこの手順を本番環境で使うのはやめましょう。

GunicornでDjangoアプリを動かす方法については以下記事を参照ください。

DjangoのデータベースをPostgreSQLに変更する方法は以下記事を参照ください。

DjangoのデータベースをPostgreSQLに変更する方法

コメント

タイトルとURLをコピーしました