「Django REST Framework(DRF)を Ubuntu で動かしたいけれど、開発サーバーから先の本番デプロイの手順がよく分からない」——そんな疑問に、実際に Docker コンテナで全コマンドを実行した結果をもとにお答えします。
結論から言うと、pip install django djangorestframework gunicorn の一発で API サーバーの土台はそろいます。本記事では python:3.12-slim 公式イメージで実際にプロジェクトを構築し、ブラウザブル API をブラウザで表示するところまで Playwright で撮影しました。実測したバージョンは Django 6.0.6 / DRF 3.17.1 / Gunicorn 26.0.0 です(2026-06-14 実測)。
本番運用の定番である Gunicorn + Nginx + systemd の構成も、実際に Gunicorn を起動した実ログを交えて解説します。最後まで読めば、VPS 上で自分の API を常駐させるまでの流れがひと通りつかめます。
この記事のポイント
pip install django djangorestframework gunicornで Django 6.0.6 / DRF 3.17.1 / Gunicorn 26.0.0 が入る(python:3.12-slim で実測)- DRF のブラウザブル APIは追加設定なしで使える。ログイン認証画面も標準搭載
- 本番は Gunicorn(
--workers 3)+ Nginx リバースプロキシ + systemd の3段構成が定番 - Python のバージョンで入る Django が変わる:3.12 → Django 6.0、3.10 → Django 5.2 LTS(2028年まで延長サポート)
- venv でパッケージをプロジェクト単位に隔離し、システムの Python を汚さないのが鉄則
目次
- 前提環境と全体構成
- Python 仮想環境と DRF のインストール
- Django プロジェクトの作成と DRF 設定
- ブラウザブル API を起動して確認する
- Gunicorn で本番モード起動
- Nginx リバースプロキシの設定
- systemd でサービス化する
- VPS 接続用の SSH 鍵を作る
- バージョン比較と互換性
- よくあるエラーと解決策
- まとめ
前提環境と全体構成
本記事は VPS の Ubuntu 24.04 LTS をそのままターゲットにしています。Ubuntu 24.04 の標準 Python は 3.12 系なので、検証も python:3.12-slim(Python 3.12.13)公式イメージで行いました。
| 項目 | バージョン / 内容 | 備考 |
|---|---|---|
| OS | Ubuntu 24.04 LTS | VPS・ローカル VM・WSL2 すべて対応 |
| Python | 3.12.13 | python:3.12-slim で実測(24.04 の標準も 3.12 系) |
| Django | 6.0.6 | 最新安定版。pip install django で実際に入ったバージョン |
| DRF | 3.17.1 | Python 3.10 / 3.12 どちらでも同じバージョンが入った |
| Gunicorn | 26.0.0 | WSGI サーバー。本番では必須 |
| Nginx | 1.24.0(Ubuntu 24.04 apt 版) | リバースプロキシ担当 |
デプロイ全体の構成は次の図のとおりです。クライアントからの HTTP を Nginx が受け取り、Gunicorn 経由で Django/DRF に渡す2段構成が定番です。Gunicorn のプロセスは systemd が管理します。

Python 仮想環境と DRF のインストール
まず python3-venv をインストールして仮想環境を作ります。システムの Python を汚さないのが鉄則です。venv に入った状態で pip install すれば、パッケージがプロジェクト配下に隔離されます。
$ mkdir -p /opt/myapi && cd /opt/myapi
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $
仮想環境に入ったら、Django・DRF・Gunicorn を一括インストールします。実際に python:3.12-slim コンテナで実行したインストール結果が以下です(バージョン確認まで含めた実出力です)。

Collecting django
Downloading django-6.0.6-py3-none-any.whl
Collecting djangorestframework
Downloading djangorestframework-3.17.1-py3-none-any.whl
Collecting gunicorn
Downloading gunicorn-26.0.0-py3-none-any.whl
Successfully installed asgiref-3.11.1 django-6.0.6 djangorestframework-3.17.1 gunicorn-26.0.0 sqlparse-0.5.5
(venv) $ python -m django –version
6.0.6
(venv) $ python -c “import rest_framework; print(rest_framework.VERSION)”
3.17.1
(venv) $ gunicorn –version
gunicorn (version 26.0.0)
インストールされたのは Django 6.0.6、DRF 3.17.1、Gunicorn 26.0.0 でした(2026-06-14 時点、python:3.12-slim で実測)。依存パッケージとして asgiref と sqlparse も自動で入ります。
Django プロジェクトの作成と DRF 設定
手順1:プロジェクトを作成する
(venv) $ ls
manage.py myapi/ venv/
手順2:settings.py に DRF を追加する
myapi/settings.py の INSTALLED_APPS に 'rest_framework' を追加します。ここを忘れると DRF の機能がまったく使えないので、正直これは詰まりやすいポイントです。
‘rest_framework’, # ← 追加
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
]
合わせて ALLOWED_HOSTS にサーバーの IP アドレスまたはドメイン名を追加します。ここが空のままだと、本番で DisallowedHost エラーになってアクセスできません。
手順3:API エンドポイントを作成する
myapi/urls.py を以下のように書き換えます。DRF の DefaultRouter を使うと、GET /api/users/ などのエンドポイントが自動生成されます。今回は標準の User モデルを読み取り専用 API として公開しました。
from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import serializers, viewsets, routers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = [‘url’, ‘username’, ‘email’, ‘is_staff’]
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all().order_by(‘id’)
serializer_class = UserSerializer
router = routers.DefaultRouter()
router.register(r’users’, UserViewSet)
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(router.urls)),
path(‘api-auth/’, include(‘rest_framework.urls’, namespace=’rest_framework’)),
]
手順4:DB の初期化とスーパーユーザー作成
migrate でテーブルを作り、createsuperuser で管理ユーザーを作成します。以下は実際にコンテナ内で実行した 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 sessions.0001_initial… OK
(venv) $ python manage.py check
System check identified no issues (0 silenced).
(venv) $ python manage.py createsuperuser
Username: admin
Email address: admin@example.com
Superuser created successfully.
実測では全 18 個のマイグレーションが OK で完了し、python manage.py check も System check identified no issues (0 silenced). を返しました。動作確認用に admin のほか taro / hanako の2ユーザーも作成しています。
ブラウザブル API を起動して確認する
DRF の目玉機能の一つがブラウザブル APIです。開発サーバーを立ち上げてブラウザでアクセスするだけで、エンドポイントの一覧・テスト・認証がすべて画面上でできます。実際に動かして撮影した画面を見てください。
Django version 6.0.6, using settings ‘myapi.settings’
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
[14/Jun/2026 05:33:10] “GET /api/ HTTP/1.1” 200 44
ブラウザで http://localhost:8000/api/ を開くと、DRF ブラウザブル API のトップ(API ルート)が表示されます。DefaultRouter が users エンドポイントへのリンクを自動で並べてくれます。

http://localhost:8000/api/users/ にアクセスすると、ユーザー一覧 API を JSON とブラウザ UI の両方で確認できます。実際に admin / taro / hanako の3件が HTTP 200 OK で返ってきました。

右上の「Log in」から /api-auth/login/ に進むと、ログイン画面が表示されます。これも DRF が標準で用意してくれるものです。

スーパーユーザー admin でログインすると、右上の表示が「admin ▾」に変わり、認証済みユーザーとして API を操作できる状態になります。

Gunicorn で本番モード起動
開発サーバー(runserver)は本番では使えません。本番では必ず Gunicorn を使うのが鉄則です。実際に Gunicorn 26.0.0 を --workers 3 で起動した実ログが以下です。

[2026-06-14 05:34:04 +0000] [18] [INFO] Starting gunicorn 26.0.0
[2026-06-14 05:34:04 +0000] [18] [INFO] Listening at: http://0.0.0.0:8000 (18)
[2026-06-14 05:34:04 +0000] [18] [INFO] Using worker: sync
[2026-06-14 05:34:04 +0000] [19] [INFO] Booting worker with pid: 19
[2026-06-14 05:34:04 +0000] [20] [INFO] Booting worker with pid: 20
[2026-06-14 05:34:04 +0000] [21] [INFO] Booting worker with pid: 21
実測では master プロセス(pid 18)の下に sync ワーカーが3本(pid 19 / 20 / 21)立ち上がり、:8000 を待ち受けました。--workers はワーカープロセス数で、一般的な目安は「CPU コア数 × 2 + 1」とされています。1GB RAM の小さな VPS なら 3 でちょうどよいバランスです。
注意
本番環境で manage.py runserver を使うのは絶対に避けてください。開発サーバーは単一プロセスでリクエストを順番にさばくため、アクセスが集中するとレスポンスが詰まります。本番は必ず Gunicorn(または uWSGI)を使いましょう。
Nginx リバースプロキシの設定
Gunicorn は内部で WSGI サーバーとして動かし、外からの HTTP は Nginx が受け取って 127.0.0.1:8000 へ中継します。静的ファイルは Nginx が直接配信するのが定番です。
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
alias /opt/myapi/staticfiles/;
}
}
$ sudo ln -s /etc/nginx/sites-available/myapi /etc/nginx/sites-enabled/
$ sudo nginx -t
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl reload nginx
systemd でサービス化する
VPS を再起動しても Django サーバーが自動で立ち上がるよう、Gunicorn を systemd サービスに登録します。systemd はコンテナ内では動かせないため、以下は実際の VPS で作成するユニットファイルの記述例です。

Description=Django REST Framework API Server
After=network.target
[Service]
User=www-data
WorkingDirectory=/opt/myapi
Environment=DJANGO_SETTINGS_MODULE=myapi.settings
ExecStart=/opt/myapi/venv/bin/gunicorn –workers 3 –bind 0.0.0.0:8000 myapi.wsgi:application
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
$ sudo systemctl enable –now django-api
$ sudo systemctl status django-api
Active: active (running)
Restart=always を入れておくと、Gunicorn が落ちても systemd が自動で再起動してくれます。enable しておけば VPS の再起動後も自動で立ち上がるので、運用が一気にラクになります。
VPS 接続用の SSH 鍵を作る
VPS にデプロイするには、まず SSH で安全に接続できる必要があります。パスワードログインより公開鍵認証のほうが安全なので、ローカルで鍵を生成しておきましょう。Ubuntu 24.04 で実際に鍵を生成した結果が以下です。

OpenSSH_9.6p1 Ubuntu-3ubuntu13.16, OpenSSL 3.0.13 30 Jan 2024
$ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N “” -C “deploy@vps”
Generating public/private ed25519 key pair.
Your identification has been saved in /root/.ssh/id_ed25519
Your public key has been saved in /root/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:8On48qi/lMlBoypO3pMAAAhkoN2xcoENdXe9mQn8irM deploy@vps
Ubuntu 24.04 の openssh-client は 1:9.6p1-3ubuntu13.16(OpenSSH_9.6p1)でした。最近は RSA より短くて安全な ED25519 鍵が推奨です。生成した公開鍵(~/.ssh/id_ed25519.pub)を VPS の ~/.ssh/authorized_keys に登録すれば、パスワードなしで安全にログインできます。
バージョン比較と互換性
Python 3.10 と 3.12 で、それぞれ pip install django djangorestframework gunicorn を実行して入るバージョンを比べました。同じコマンドでも Python のバージョンによって入る Django のメジャーバージョンが変わるのが重要なポイントです。

実測のポイント:
- Python 3.10.20 → Django
5.2.15(LTS、2028年4月まで延長サポート)が入った - Python 3.12.13 → Django
6.0.6(最新安定版)が入った - DRF
3.17.1と Gunicorn26.0.0はどちらの Python でも同じバージョンが入った
長期運用する VPS なら、サポート期間の長い Django 5.2 LTS + Python 3.10 の組み合わせも堅実な選択肢です。新機能を積極的に使いたい、あるいは Ubuntu 24.04 の標準 Python に合わせたい場合は Django 6.0 + Python 3.12 を選びましょう。
よくあるエラーと解決策
| エラーメッセージ | 原因 | 解決策 |
|---|---|---|
ModuleNotFoundError: No module named 'rest_framework' |
INSTALLED_APPS に 'rest_framework' を追加していない、または venv を有効化していない |
settings.py に追加。source venv/bin/activate 済みか確認 |
DisallowedHost: Invalid HTTP_HOST header |
ALLOWED_HOSTS に VPS の IP やドメインが入っていない | settings.py の ALLOWED_HOSTS にサーバー IP / ドメインを追加 |
django.core.exceptions.ImproperlyConfigured |
Gunicorn 起動時に DJANGO_SETTINGS_MODULE が未設定 | systemd ユニットに Environment=DJANGO_SETTINGS_MODULE=myapi.settings を追加 |
502 Bad Gateway(Nginx) |
Gunicorn が起動していない、またはポートが Nginx 設定と不一致 | systemctl status django-api で確認。proxy_pass のポートを一致させる |
| 静的ファイルが 404 になる | python manage.py collectstatic を実行していない |
settings.py に STATIC_ROOT を設定して collectstatic を実行 |
注意:SECRET_KEY を絶対に公開しない
Django の SECRET_KEY はデフォルトで settings.py にハードコードされています。本番では環境変数(os.environ.get('SECRET_KEY'))から読み込む方式に変更し、settings.py をそのまま GitHub などにコミットしないようにしてください。あわせて本番では DEBUG = False に必ず変更します。
まとめ
Django REST Framework を Ubuntu 24.04 で本番デプロイする手順を、実際にコマンドを動かしながら解説しました。
pip install django djangorestframework gunicornで Django 6.0.6 / DRF 3.17.1 / Gunicorn 26.0.0 が入る(python:3.12-slim で実測)- DRF のブラウザブル API はインストール直後から使え、ログイン認証画面まで標準で備わっている
- 本番は Gunicorn(
--workers 3)+ Nginx リバースプロキシ + systemd の3段構成が定番 - Python のバージョンで入る Django が変わる(3.10 → Django 5.2 LTS、3.12 → Django 6.0)
- SECRET_KEY・ALLOWED_HOSTS・DEBUG=False は本番前に必ず見直す
VPS のスペックや料金を比較して選びたい方は、こちらの記事も参考にしてください。
VPS を借りて本格的に API サーバーを運用したいなら、コストパフォーマンスが高く東京リージョンも選べる Vultr がおすすめです。日本語サポートを重視するなら ConoHa VPS も選択肢になります。



コメント