📗

VSCodeとDockerで「実践Django」の環境を用意してみた

2024/04/02に公開

はじめに

実践Django Pythonによる本格Webアプリケーション開発』を読み進めるにあたって、Dockerで環境を用意したので、その手順を残したいと思います。
Dev Containersを使う方法と使わない方法の2種類を試したのですが、個人的には使用する方が便利でした。若干手間が増えるものの、VSCode上でデバッグができるメリットが大きかったです。

動作環境

  • macOS Sonoma 14.3.1
  • Docker Desktop 4.27.2
    • Docker Engine 25.0.3
    • Docker Compose 2.24.5
  • Visual Studio Code 1.87.2
    • Dev Containers(拡張機能) 0.348.0
    • Docker(拡張機能) 1.29.0

Dev Containersを使う場合

構成

launch.jsonはデバッグ設定時に自動で生成されます。また、書籍内で作成するアプリケーションのディレクトリは省略しています。

.
├── .devcontainer
│   └── devcontainer.json
├── .vscode
│   └── launch.json
├── Dockerfile
├── docker-compose.yml
└── requirements.txt

Dockerfile

Dockerの公式ドキュメントにあったDjangoのクイックスタートガイドを参考にしました。親イメージにはsqlite3[1]が含まれていなかったので、追加でインストールします。

# syntax=docker/dockerfile:1
FROM python:3.9
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code
RUN apt-get update && apt-get install -y sqlite3
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

docker-compose.yml

こちらも同様ですが、コンテナ起動時に自動で開発用のサーバーが立ち上がらないようにしました。代わりにコンテナがすぐに終了しないようにtail -f /dev/nullを実行するようにします。

services:
  web:
    build: .
    command: tail -f /dev/null
    volumes:
      - .:/code
    ports:
      - "8000:8000"

requirements.txt

1章で必要なライブラリを利用できるようにしました。

Django>=3.0,<4.0
django-bootstrap5
django-pygments-renderer

devcontainer.json

extensionsにコンテナ内で利用したい拡張機能を記載します。"ms-python.python"はMicrosoftのPython拡張機能で、デバッグに必要なので必須ですが、他は好みで追加します。VSCodeの設定も追加することができますが、おそらくデフォルトだとユーザー設定が引き継がれるようです。

{
    "name": "django container",
    "dockerComposeFile": "../docker-compose.yml",
    "service": "web",
    "workspaceFolder": "/code",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-python.black-formatter",
                "ms-python.isort",
                "batisteo.vscode-django"
            ]
        }
    }
}

下記の記事を参考にさせていただきました。
https://scrawledtechblog.com/docker-python-django/

コンテナの起動と接続

左下の「><」ボタンかコマンドパレットから、Reopen in Container(コンテナーで再度開く)を選択してコンテナを起動します。

起動するとターミナルから直接シェルを利用できるようになるので、startprojectやstartappなどのコマンドが使用できるようになります。

デバッグ

サイドバーの「実行とデバッグ」からlaunch.jsonを作成します。

Python Debuggerを選択します。

Djangoを選択します。

manage.pyへのパスを指定します。

デフォルトで作成されるものから"runserver"の後に"0.0.0.0:8000"を追加しています。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python デバッガー: Django",
            "type": "debugpy",
            "request": "launch",
            "program": "${workspaceFolder}/djangosnippets/manage.py",
            "args": [
                "runserver",
                "0.0.0.0:8000"
            ],
            "django": true,
            "autoStartBrowser": false
        }
    ]
}

これでデバッグが可能になります。デバッガーを起動すると、ホストマシンからhttp://localhost:8000/でトップページにアクセスできます。

私の環境では、デバッガー起動時にImportError: Couldn't import Djangoのエラーが出てしまうことがありました。これは、イメージに含まれていた別のPythonインタープリターを使用してしまったために起こるようです。
VSCode画面右下のインタープリター表示をクリックするか、コマンドパレットからSelect Interpreter(インタープリターを選択)を表示し、usr/local/bin/pythonにあるものを使用するようにします。

Docker HubにあるPython公式イメージの説明に下記のような記載がありました。親イメージを指定する際にpython:3.9-slimとすれば、このような問題は回避できるかもしれません。

In the non-slim variants there will be an additional (distro-provided) python executable at /usr/bin/python (and/or /usr/bin/python3) while the desired image-provided /usr/local/bin/python is the default choice in the $PATH. This is an unfortunate side-effect of using the buildpack-deps image in the non-slim variants (and many distribution-provided tools being written against and likely to break with a different Python installation, so we can't safely remove/overwrite it).

下記の記事を参考にさせていただきました。
https://qiita.com/shun198/items/9e4fcb4479385217c323

Dev Containersを使わない場合

変更点

拡張機能を使用する場合と比較すると、devcontainer.jsonとlaunch.jsonは不要になります(代わりにVSCodeでのデバッグもできません)。
コンテナ起動時に自動で開発用のサーバーが立ち上がるようにしたい場合は、docker-compose.yml内のコマンドを下記のように変更します(manage.pyのパスは適宜修正してください)。これで起動時にhttp://localhost:8000/でトップページにアクセスできるようになります。

command: python djangosnippets/manage.py runserver 0.0.0.0:8000

コンテナの起動

ターミナルからコマンドを入力してもよいのですが、VSCodeの場合はフォルダを開いてdocker-compose.ymlを右クリック>Compose Upでコンテナを起動できます。

コンテナ内のシェルに接続

Docker拡張機能タブから起動中のコンテナを選び、右クリック>Attach Shellを選択すると、ターミナルでコンテナ内のシェルを利用できるようになるので、startprojectやstartappなどのコマンドが使用できるようになります。

脚注
  1. VSCode上でSQLiteを操作したい場合は、後述の手順でコンテナを起動・接続して、VSCodeのターミナルから操作するか、SQLite拡張機能を導入すると便利です。 ↩︎

Discussion