目的
Mac上に開発環境、Dokcerに本番環境を構築し、下記URLにブラウザアクセスが可能な状態にする。
Page | URL |
---|---|
Django (Hello, world.) | http://localhost:8000 |
Django administration | http://localhost:8000/admin/ |
REST framewrk | http://localhost:8000/api/ |
Django Debug Toolbar | - |
Swagger | http://localhost:8000/api/schema/swagger-ui |
Django REST framework JWT | http://localhost:8000/api-auth/ |
環境
MacOSX: Sonoma
Python: 3.11.1
Django: 4.2.11
Django REST framework: 3.14.0
Django Debug Toolbar: 4.3.0
drf-spectacular(swagger): 0.27.1
Simple JWT: 5.3.1
Django 開発環境構築
作業ディレクトリ用意
% mkdir Django4.2-DRF && cd Django4.2-DRF
Pythonのセットアップ
% pyenv versions # インストールされているバージョンを確認
% pyenv install --list # インストール可能なバージョンを表示
% pyenv install 3.11.1 # Python3.11.1をインストール
% pyenv local 3.11.1 # このディレクトリ配下のバージョンを固定
ローカルリポジトリの作成
% git init
% echo '# Django4.2-DRF' > README.md
% cat << EOF > .gitignore
*.pyc
__pycache__
db.sqlite3
venv/*
EOF
% git add .
% git commit -m 'first commit'
↓ この作業後のディレクトリ構成
Django4.2-DRF
├── .git
├── .gitignore
└── README.md
Django用作業ディレクトリの作成
% mkdir django && cd django
% poetry init
This command will guide you through creating your pyproject.toml config.
Package name [django4.2-drf]:
Version [0.1.0]:
Description []:
Author [mykysyk, n to skip]:
License []:
Compatible Python versions [^3.11]:
Would you like to define your main dependencies interactively? (yes/no) [yes]
You can specify a package in the following forms:
- A single name (requests): this will search for matches on PyPI
- A name and a constraint (requests@^2.23.0)
- A git url (git+https://github.com/python-poetry/poetry.git)
- A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)
- A file path (../my-package/my-package.whl)
- A directory (../my-package/)
- A url (https://example.com/packages/my-package-0.1.0.tar.gz)
Package to add or search for (leave blank to skip):
Would you like to define your development dependencies interactively? (yes/no) [yes]
Package to add or search for (leave blank to skip):
Generated file
[tool.poetry]
name = "django4-2-drf"
version = "0.1.0"
description = ""
authors = ["mykysyk"]
readme = "README.md"
packages = [{include = "django"}]
[tool.poetry.dependencies]
python = "^3.11"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Do you confirm generation? (yes/no) [yes]
↓ この作業後のディレクトリ構成
Django4.2-DRF
├── .git
├── .gitignore
├── .python-version
├── README.md
└── django
└── pyproject.toml
Djangoのインストール
Django4.2-DRF
└── django ← 現在の階層
https://www.djangoproject.com/download/ より最新LTSのバージョンを調べてインストール
% poetry add Django==4.2.11
% poetry run python -m django --version
4.2.11
Djangoプロジェクト作成
% poetry run django-admin startproject config .
↓ この作業後のディレクトリ構成
Django4.2-DRF
├── .git
├── .gitignore
├── .python-version
├── README.md
└── django
├── .venv
├── config # プロジェクトが作成された
│ ├── __init__.py # プロジェクトが作成された
│ ├── asgi.py # プロジェクトが作成された
│ ├── settings.py # プロジェクトが作成された
│ ├── urls.py # プロジェクトが作成された
│ └── wsgi.py # プロジェクトが作成された
├── manage.py # プロジェクトが作成された
├── poetry.lock
└── pyproject.toml
管理画面にログインするスーパーユーザーを追加
データベース構築
% poetry run 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
↓ この作業後のディレクトリ構成
├── .git
├── .gitignore
├── .python-version
├── README.md
└── django
├── config
│ ├── __init__.py
│ ├── __pycache__
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3 # DBが新規作成される
├── manage.py
├── poetry.lock
└── pyproject.toml
スーパーユーザ作成
% poetry run python manage.py createsuperuser
動作確認で起動してみる
% poetry run python manage.py runserver
確認 1: http://localhost:8000 にアクセスし「The install worked successfully! Congratulations!」が出ればOK
確認 2: http://localhost:8000/admin/sample_app/memo/ にアクセスできるのを確認
ここまでの変更をGitでコミット
git add .
git commit -m 'Djangoプロジェクト作成'
sample_app アプリケーション作成
% poetry run python manage.py startapp sample_app
↓ この作業後のディレクトリ構成
Django4.2-DRF
├── .git
├── .gitignore
├── .python-version
├── README.md
└── django
├── .venv
├── config
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── poetry.lock
├── pyproject.toml
└── sample_app # アプリケーションが作成された
├── __init__.py # アプリケーションが作成された
├── admin.py # アプリケーションが作成された
├── apps.py # アプリケーションが作成された
├── migrations # アプリケーションが作成された
├── models.py # アプリケーションが作成された
├── tests.py # アプリケーションが作成された
└── views.py # アプリケーションが作成された
sample_app のアプリケーション登録
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── config
└── settings.py ← これ
% vi config/settings.py
既存ファイルとの差分
% git diff config/settings.py
diff --git a/django/config/settings.py b/django/config/settings.py
index be04b32..33ec9e6 100644
--- a/django/config/settings.py
+++ b/django/config/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
+ 'sample_app',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
ビュー作成
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── sample_app
└── views.py ← これ
% vi sample_app/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world.")
アプリ用URLConfの新規作成
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── sample_app
└── urls.py ← これ新規作成
% vi sample_app/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
ルート用URLConfの編集
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── config
└── urls.py ← これ
% vi config/urls.py
既存ファイルとの差分
% git diff config/urls.py
diff --git a/django/config/urls.py b/django/config/urls.py
index 5006338..d212c09 100644
--- a/django/config/urls.py
+++ b/django/config/urls.py
@@ -15,8 +15,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
-from django.urls import path
+from django.urls import path, include
urlpatterns = [
+ path('', include('sample_app.urls')),
path('admin/', admin.site.urls),
]
動作確認で起動してみる
% poetry run python manage.py runserver
確認: http://localhost:8000 にアクセスし「Hello, world.」が出ればOK
ここまでの変更をGitでコミット
% git add .
% git commit -m 'Djangoアプリケーション作成'
Django REST framework
Django REST Framework で RESTful API バックエンドを構築
Django REST framework のインストール
Django4.2-DRF
└── django ← 現在の階層
% poetry add djangorestframework django-filter
Djagno REST Framework のアプリケーション登録
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── config
└── settings.py ← これ
% vi config/settings.py
既存ファイルとの差分
% git diff django/config/settings.py
diff --git a/django/config/settings.py b/django/config/settings.py
index 75b5a5e..d23b69d 100644
--- a/django/config/settings.py
+++ b/django/config/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
+ 'rest_framework',
'sample_app',
'django.contrib.admin',
'django.contrib.auth',
Modelsの定義
データが必要とするフィールドとその動作を定義
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── sample_app
└── models.py ← これ
% vi sample_app/models.py
from django.db import models
class Memo(models.Model):
title = models.CharField(max_length=64)
memo = models.TextField(max_length=1024)
Serializerの定義
「入力データ(jsonデータ)とモデルオブジェクトの相互変換」
「入力データのバリデーション」
新規作成するファイル
Django4.2-DRF
└── django ← 現在の階層
└── sample_app
└── serializer.py ← 新規作成
% vi sample_app/serializer.py
from rest_framework import serializers
from .models import Memo
class MemoSerializer(serializers.ModelSerializer):
class Meta:
model = Memo
fields = '__all__'
↓ この作業によりできるディレクトリ構成
Django4.2-DRF
├── .git
├── .gitignore
├── .python-version
├── .venv
├── README.md
└── django
├── .venv
├── config
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
├── manage.py
├── poetry.lock
├── pyproject.toml
└── sample_app
├── __init__.py
├── __pycache__
├── admin.py
├── apps.py
├── migrations
├── models.py
├── serializer.py # 新規作成
├── tests.py
├── urls.py
└── views.py
ViewSetの追加
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── sample_app
└── views.py ← これ
% vi sample_app/views.py
from django.http import HttpResponse
from rest_framework import viewsets
from .models import Memo
from .serializer import MemoSerializer
def index(request):
return HttpResponse("Hello, world.")
class MemoViewSet(viewsets.ModelViewSet):
queryset = Memo.objects.all()
serializer_class = MemoSerializer
アプリ用URLConfの編集
REST frameworkへの設定を組み込む
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── sample_app
└── urls.py ← これ
% vi sample_app/urls.py
既存ファイルとの差分
% git diff sample_app/urls.py
diff --git a/django/sample_app/urls.py b/django/sample_app/urls.py
index 88a9cac..43c2a4d 100644
--- a/django/sample_app/urls.py
+++ b/django/sample_app/urls.py
@@ -1,7 +1,11 @@
from django.urls import path
from . import views
+from rest_framework import routers
urlpatterns = [
path('', views.index, name='index'),
]
+
+router = routers.DefaultRouter()
+router.register(r'memo', views.MemoViewSet)
ルート用URLConfの編集
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── config
└── urls.py ← これ
% vi config/urls.py
既存ファイルとの差分
% git diff config/urls.py
diff --git a/django/config/urls.py b/django/config/urls.py
index d212c09..6503349 100644
--- a/django/config/urls.py
+++ b/django/config/urls.py
@@ -16,8 +16,10 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include
+from sample_app.urls import router as sample_app_router
urlpatterns = [
path('', include('sample_app.urls')),
path('admin/', admin.site.urls),
+ path('api/', include(sample_app_router.urls)),
]
データベース再構築
マイグレーションファイル作成
% poetry run python manage.py makemigrations
Migrations for 'sample_app':
sample_app/migrations/0001_initial.py
- Create model Memo
再構築
% poetry run python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sample_app, sessions
Running migrations:
Applying sample_app.0001_initial... OK
↓ この作業後のディレクトリ構成
Django4.2-DRF
├── .git
├── .gitignore
├── .python-version
├── .venv
├── README.md
├── django
│ ├── config
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── wsgi.py
│ ├── db.sqlite3
│ ├── manage.py
│ └── sample_app
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ ├── 0001_initial.py # makemigrationsによって作成
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── poetry.lock
└── pyproject.toml
管理画面にsample_appのモデルを追加する
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── sample_app
└── admin.py ← これ
% vi sample_app/admin.py
from django.contrib import admin
from .models import Memo
@admin.register(Memo)
class MemoAdmin(admin.ModelAdmin):
pass
動作確認で起動してみる
% poetry run python manage.py runserver
確認 1: http://localhost:8000/api/memo/ にアクセスできるか確認
確認 2: http://localhost:8000/admin/sample_app/memo/ にアクセスできるか確認
ここまでの変更をGitでコミット
git add .
git commit -m 'DRF組み込み'
Django Debug Toolbar
Django Debug Toolbarでデバッグ情報を表示
Django Debug Toolbar のインストール
Django4.2-DRF
└── django ← 現在の階層
% poetry add django-debug-toolbar
Django Debug Toolbar の有効化
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── config
└── settings.py ← これ
% vi config/settings.py
% git diff config/settings.py
diff --git a/django/config/settings.py b/django/config/settings.py
index aa06725..1b42fa6 100644
--- a/django/config/settings.py
+++ b/django/config/settings.py
@@ -123,3 +123,18 @@ STATIC_URL = 'static/'
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+if DEBUG:
+ STATIC_ROOT = None
+ STATICFILES_DIRS = ['static']
+ # django-debug-toolbar
+ # https://django-debug-toolbar.readthedocs.io/en/latest/index.html
+ INSTALLED_APPS += ['debug_toolbar']
+ MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
+ DEBUG_TOOLBAR_CONFIG = {'SHOW_TOOLBAR_CALLBACK': lambda request: True}
+else:
+ import os
+ STATIC_URL = 'static/'
+ STATIC_ROOT = os.path.join(BASE_DIR, 'static')
+ STATICFILES_DIRS = []
+ ALLOWED_HOSTS = ['*']
ルート用URLConfの編集
Django4.2-DRF
└── django ← 現在の階層
└── config
└── urls.py ← これ
% vi config/urls.py
% git diff config/urls.py
diff --git a/django/config/urls.py b/django/config/urls.py
index d956986..9242764 100644
--- a/django/config/urls.py
+++ b/django/config/urls.py
@@ -18,6 +18,7 @@ from django.contrib import admin
from django.urls import path, include
from sample_app.urls import router as sample_app_router
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
+from config import settings
urlpatterns = [
path('', include('sample_app.urls')),
@@ -27,3 +28,7 @@ urlpatterns = [
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]
+
+if settings.DEBUG:
+ import debug_toolbar
+ urlpatterns += [path('__debug__/', include(debug_toolbar.urls))]
動作確認で起動してみる
% poetry run python manage.py runserver
確認: http://localhost:8000/api/memo にアクセスして確認
ここまでの変更をGitでコミット
% git add .
% git commit -m 'Django Debug Toolbar組み込み'
JWT
JWT(JSON Web Token)を利用したWebアプリケーションの認証の導入
djangorestframework-simplejwt のインストール
Django4.2-DRF
└── django ← 現在の階層
% poetry add djangorestframework-simplejwt
djangorestframework-jwt の有効化
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── config
└── settings.py ← これ
% vi config/settings.py
diff --git a/django/config/settings.py b/django/config/settings.py
index 1b42fa6..e74d123 100644
--- a/django/config/settings.py
+++ b/django/config/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
+ 'rest_framework_simplejwt',
'rest_framework',
'sample_app',
'django.contrib.admin',
@@ -124,6 +125,15 @@ STATIC_URL = 'static/'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+REST_FRAMEWORK = {
+ 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
+ 'DEFAULT_AUTHENTICATION_CLASSES': (
+ 'rest_framework_simplejwt.authentication.JWTAuthentication',
+ 'rest_framework.authentication.SessionAuthentication',
+ 'rest_framework.authentication.BasicAuthentication',
+ )
+}
+
if DEBUG:
STATIC_ROOT = None
STATICFILES_DIRS = ['static']
ルート用URLConfの編集
Django4.2-DRF
└── django ← 現在の階層
└── config
└── urls.py ← これ
% vi config/urls.py
既存ファイルとの差分
% git diff config/urls.py
diff --git a/django/config/urls.py b/django/config/urls.py
index c759bb5..f7ff5e8 100644
--- a/django/config/urls.py
+++ b/django/config/urls.py
@@ -18,11 +18,17 @@ from django.contrib import admin
from django.urls import path, include
from sample_app.urls import router as sample_app_router
from config import settings
+from rest_framework_simplejwt.views import (
+ TokenObtainPairView,
+ TokenRefreshView,
+)
urlpatterns = [
path('', include('sample_app.urls')),
path('admin/', admin.site.urls),
path('api/', include(sample_app_router.urls)),
+ path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
+ path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
if settings.DEBUG:
動作確認で起動してみる
% poetry run python manage.py runserver
トークンなしでGETリクエスト
% curl -s -XGET http://localhost:8000/api/memo/ | jq .
結果
{
"detail": "Authentication credentials were not provided."
}
アクセストークンとリフレッシュトークンを取得する
% DJANGO_USERNAME='admin'
% DJANGO_PASSWORD='userpassword'
% curl \
-s \
-X POST \
-H "Content-Type: application/json" \
-d "{\"username\": \"${DJANGO_USERNAME}\", \"password\": \"${DJANGO_PASSWORD}\"}" \
http://localhost:8000/api/token/ | jq .
結果
{
"refresh": "REFRESH_TOKEN",
"access": "ACCESS_TOKEN"
}
アクセストークンを利用して情報を取得
トークン発行
% DJANGO_USERNAME='admin'
% DJANGO_PASSWORD='userpassword'
% ACCESS_TOKEN=$(curl \
-s \
-X POST \
-H "Content-Type: application/json" \
-d "{\"username\": \"${DJANGO_USERNAME}\", \"password\": \"${DJANGO_PASSWORD}\"}" \
http://localhost:8000/api/token/ | jq -r .access)
情報を取得
% curl \
-s \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
http://localhost:8000/api/memo/ | jq .
結果
[]
POSTしてデータ登録
% curl -XPOST -H "Authorization: Bearer ${ACCESS_TOKEN}" http://127.0.0.1:8000/api/memo/ -d 'title=a&memo=a'
結果
{"id":1,"title":"a","memo":"a"}
POSTデータの確認
% curl \
-s \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
http://localhost:8000/api/memo/ | jq .
結果
[
{
"id": 1,
"title": "a",
"memo": "a"
}
]
アクセストークンの期限が切れたらリフレッシュトークンを利用して新しいアクセストークンを再取得する。
curl \
-s \
-X POST \
-H "Content-Type: application/json" \
-d "{\"refresh\":\"${REFRESH_TOKEN}\"}" \
http://localhost:8000/api/token/refresh/ | jq .
結果
{
"access": "ACCESS_TOKEN"
}
ここまでの変更をGitでコミット
% git add .
% git commit -m 'JWT組み込み'
Swagger
Django Rest Framework のコードから Swagger ドキュメントを生成
drf-spectacular のインストール
Django4.2-DRF
└── django ← 現在の階層
% poetry add drf-spectacular
Swagger の有効化
編集するファイル
Django4.2-DRF
└── django ← 現在の階層
└── config
└── settings.py ← これ
% vi config/settings.py
% git diff config/settings.py
diff --git a/django/config/settings.py b/django/config/settings.py
index e74d123..e52e56f 100644
--- a/django/config/settings.py
+++ b/django/config/settings.py
@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
+ 'drf_spectacular',
'rest_framework_simplejwt',
'rest_framework',
'sample_app',
@@ -131,7 +132,14 @@ REST_FRAMEWORK = {
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
- )
+ ),
+ 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
+}
+
+SPECTACULAR_SETTINGS = {
+ 'TITLE': 'Swagger Sample App',
+ 'DESCRIPTION': '',
+ 'VERSION': 'v2024.3.23',
}
if DEBUG:
ルート用URLConfの編集
Django4.2-DRF
└── django ← 現在の階層
└── config
└── urls.py ← これ
% vi config/urls.py
既存ファイルとの差分
% git diff config/urls.py
diff --git a/django/config/urls.py b/django/config/urls.py
index f7ff5e8..df6f3c2 100644
--- a/django/config/urls.py
+++ b/django/config/urls.py
@@ -22,6 +22,7 @@ from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
+from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
urlpatterns = [
path('', include('sample_app.urls')),
@@ -29,6 +30,9 @@ urlpatterns = [
path('api/', include(sample_app_router.urls)),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
+ path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
+ path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
+ path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]
if settings.DEBUG:
動作確認で起動してみる
% poetry run python manage.py runserver
確認: http://localhost:8000/api/schema/swagger-ui/ にアクセスしてswaggerが表示されているか確認
ここまでの変更をGitでコミット
% git add .
% git commit -m 'swagger組み込み'
本番環境の構築
Django4.2-DRF
└── django ← 現在の階層
uvicorn/gunicornインストール
% poetry add uvicorn gunicorn
動作確認で起動してみる
% # --chdir /path/to/Django4.2-DRF/django の部分は
% # Djangoのconfigディレクトリがあるディレクトリを指定
% poetry run python -m gunicorn config.asgi:application \
--worker-class uvicorn.workers.UvicornWorker \
--workers 4 \
--bind 0.0.0.0:8000 \
--max-requests 500 \
--max-requests-jitter 200 \
--timeout 300 \
--graceful-timeout 300 \
--reload \
--chdir /path/to/Django4.2-DRF/django
Django用Dockerfileの作成
新規に作成するファイル
Django4.2-DRF
└── django ← 現在の階層
└── Dockerfile ← 新規作成
% vi Dockerfile
FROM python:3.11-slim-bookworm
ENV TZ=Asia/Tokyo \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
POETRY_VIRTUALENVS_CREATE=false \
PATH="/root/.local/bin:$PATH"
# Install Packages
RUN apt-get update && apt-get install -y curl
WORKDIR /app
# Source Copy
COPY . /app/
# Poetry Install
RUN curl -sSL https://install.python-poetry.org | python3 -
RUN poetry install --no-root
# Create DB & Static file
RUN sed -i.org 's/^DEBUG\s+=\s+True$/DEBUG = False/' config/settings.py && \
poetry run python manage.py makemigrations && \
poetry run python manage.py migrate && \
poetry run python manage.py collectstatic --noinput
EXPOSE 8000
# Run Djagno
CMD ["poetry", "run", "python", "manage.py", "runserver", "0.0.0.0:8000"]
イメージが正しく作成されるかビルドしてみる
% docker build . -t django4.2:v$(date '+%Y.%-m.%-d')
% docker run --name django4.2 --rm -p8000:8000 django4.2:v$(date '+%Y.%-m.%-d')
確認: http://localhost:8000/api/memo/ にアクセスして確認
cssやjsが404でもOK
一旦イメージを削除しておく
% docker rmi django4.2:v$(date '+%Y.%-m.%-d')
Nginx用Dockerfileの作成
新規に作成するファイル
Django4.2-DRF
├── django ← 現在の階層
└── nginx ← 新規作成
└── Dockerfile ← 新規作成
% cd ../
% mkdir nginx && cd nginx
% vi Dockerfile
FROM nginx:latest
# Remove default log
RUN rm /var/log/nginx/access.log /var/log/nginx/error.log
# Create new logging pipe and point nginx logs to it
RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stdout /var/log/nginx/error.log
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 8080
Nginx用default.confの作成
Django4.2-DRF
├── django
└── nginx ← 現在の階層
└── default.conf ← 新規作成
% vi default.conf
upstream django-upstream {
server app:8000;
}
server {
listen 8080;
server_name localhost;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/error.log notice;
location /static/ {
alias /static/;
}
location / {
proxy_pass http://django-upstream/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
docker-compose
新規に作成するファイル
Django4.2-DRF
└── nginx ← 現在の階層
└── docker-compose.yml ← 新規作成
% cd ../
% vi docker-compose.yml
version: '3'
services:
app:
container_name: app
build: ./django/
working_dir: /app
volumes:
- ./django:/app
- static_volume:/app/static
ports:
- "8000:8000"
command: >
sh -c "poetry run python -m gunicorn config.asgi:application \
--worker-class uvicorn.workers.UvicornWorker \
--workers 4 \
--bind 0.0.0.0:8000 \
--max-requests 500 \
--max-requests-jitter 200 \
--timeout 300 \
--graceful-timeout 300"
web:
container_name: web
build: ./nginx/
ports:
- "8080:8080"
volumes:
- static_volume:/static
depends_on:
- app
volumes:
static_volume:
起動してみる
% docker-compose up -d
↓のURLにアクセスできるか確認
Page | URL |
---|---|
Django (Hello, world.) | http://localhost:8080 |
Django administration | http://localhost:8080/admin/ |
REST framewrk | http://localhost:8080/api/ |
Swagger | http://localhost:8080/api/schema/swagger-ui |
Django REST framework JWT | http://localhost:8080/api/token/ |
ここまでの変更をGitでコミット
% git add .
% git commit -m 'docker-compose対応'
docker-compose コマンド集
アクション | コマンド |
---|---|
起動 | docker-compose up -d |
停止 | docker-compose stop |
再起動 | docker-compose restart |
ログを見る | docker-compose logs |
コンテナ削除 | docker-compose down |
コンテナとイメージ削除 | docker-compose down --rmi all |