LoginSignup
13
9

More than 1 year has passed since last update.

Djangoの開発環境をdocker-composeを利用してコンテナで起動し、runserverコマンドでホスト側からアクセスする方法

Posted at

やってみたこと

  • djangoチュートリアルで制作したpolls appを、dockerで立ち上げてみようとふと思ったのでやってみました。
    • pollsアプリは、python3 manage.py runserver 8000によって、localhost:8000で起動します。それをdockerコンテナからやってみようという話です。

前提

  • 今回は敢えて、Dockerfiledocker-compose.ymlの両方を最低限レベルで使ってdjangoのアプリケーションを構築します。これらのファイルを使った方が、今後汎用的に覚えられる(いじってみれる)だろうという期待も込めて(笑)
  • dockerコンテナの中からpython manage.py runserverで開発サーバを起動してみる、という実験をします。実際にはおそらくあまりこんな使い道はないのでは、、、その辺はお気にせずお読みください笑
    • 開発用サーバーは、Django付属のWebサーバーです。開発中に便利なツールであって、運用環境では使用しないことが推奨されています。
  • djangoチュートリアルでpollsアプリケーションを制作したmysiteプロジェクトを、以下ディレクトリ構造で配置。
.
├── docker
│   ├── docker-compose.yml
│   └── Dockerfile
└── web
    ├── mysite
    │   ├── mysite
    │   ├── polls
    │   ├── db.sqlite3
    │   └── manage.py
    └── requirements.txt

手順

  • docker関連ファイルの準備
  • イメージ作成・コンテナ起動
  • コンテナの中に入ってmanage.pyを確認
  • Dockerコンテナから開発サーバを起動

docker関連ファイルの準備

  • まずはDockerfileに以下のように記載します。
# python:3.8の公式 image をベースの image として設定
FROM python:3.8

# 作業ディレクトリの作成
RUN mkdir /mysite

# 作業ディレクトリの設定(以後の RUN は WORKDIR で実行)
WORKDIR /mysite

# カレントディレクトリにある資産をコンテナ上の指定のディレクトリにコピーする
ADD web /mysite

# pipでrequirements.txtに指定されているパッケージを追加する
RUN pip install -r requirements.txt

# 起動(今回はなし)
# CMD python3 manage.py runserver 0.0.0.0:8000
  • 今回はpython3.8のイメージをベースとしています。マイナーバージョンを指定しないとビルド時点の最新python stable versionがインストールされます。
    • ちなみに、何も指定しないと以下のエラーが出てきます。
failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: no build stage in current context
  • requirements.txtには以下のように記載します。ビルド時にインストールしたいライブラリ(python package)を記述します。
    • こちらもdjangoアプリで使う必要最低限のものだけ記述します。
Django==4.1
requests
  • そしてdocker-compose.ymlには以下のように記載します。
    • 今回は必要最低限のものしか記載していません。
version: '3'
services:
  mysite:
    build:
      context: ../
      dockerfile: ./docker/Dockerfile # Dockerfileのディレクトリを指定します
    volumes:
      - '../web:/mysite'
    ports:
      - "8000:8000" # 左側が外部からのアクセス時のポート番号:右側がdockerコンテナからアクセスする時のポート番号。ホストの8000番からコンテナの8000番へポートフォワードしています
    container_name: docker_mysite
    tty: true  # ポート待受とかしていないコンテナの場合、trueに設定しておくとコンテナが起動し続けます
    working_dir: '/mysite'

イメージ作成・コンテナ起動

  • 以下のコマンドでイメージ作成&コンテナ起動します。
$ docker compose up -d
  • -dオプションはデーモンモードで起動し、プロセスをバックグラウンドで動作させることができます。
    • アクセスログの内容やエラーなどを確認したい場合は、-dを外して実行します。
  • 起動しているコンテナを以下のコマンドで確認できます。UPなので起動していますね。
$ docker ps
CONTAINER ID   IMAGE           COMMAND     CREATED              STATUS              PORTS                    NAMES
7f730b3c105f   docker-mysite   "python3"   About a minute ago   Up About a minute   0.0.0.0:8000->8000/tcp   docker_mysite
  • docker-compose.ymlで指定した8000ポートにつながっていることがわかります。
  • $ docker compose psでもコンテナがRUNNINGかどうか分かります。
  • また、以下のコマンドにより、requirement.txtに記述したモジュールがインストールされているかどうか確認できます。
$ docker exec -it docker_mysite pip list
Package            Version
------------------ ---------
asgiref            3.6.0
backports.zoneinfo 0.2.1
certifi            2022.12.7
charset-normalizer 3.1.0
Django             4.1
idna               3.4
pip                22.0.4
requests           2.28.2
setuptools         57.5.0
sqlparse           0.4.3
urllib3            1.26.14
wheel              0.38.4

コンテナの中に入ってmanage.pyを確認

  • 以下のコマンドでdocker_mysiteコンテナに入ります。
$ docker exec -it docker_mysite bash
  • CONTAINER IDでも入れるので、以下のコマンドでもOKです。
$ docker exec -it 7f730b3c105f bash
  • まだコンテナが立ち上がっていない場合は、以下が返ってきます。その場合は、docker compose up -dを行いましょう。
Error response from daemon: Container xxxxxxxx is not running
  • また、そもそもコンテナが存在していない時は、以下のメッセージが返ってきます。こちらの場合も、docker-compose.ymlがあるところでdocker compose up -dを行いましょう。
Error: No such container: xxxxxxxx
  • コンテナの中に入れたら、以下のようなプロンプトが出てきます。
root@7f730b3c105f:/mysite#
  • ls -aで直下を確認します。ローカル環境で作成したディレクトリがCOPYされていることがわかります。
root@7f730b3c105f:/mysite# ls -a
.  ..  .DS_Store  mysite  requirements.txt
  • manage.pyがあるディレクトリに移動します。
$ cd mysite
  • ここでls -aをすれば同じくローカルと同様の状況が確認できるはずです。

Dockerコンテナから開発サーバを起動

  • 以下のコマンド実施により、8000ポートで立ち上げることができます。
root@7f730b3c105f:/mysite# cd mysite
root@7f730b3c105f:/mysite/mysite# python3 manage.py runserver 0:8000
  • ポイントは0です。以下の参考記事に記載がありますが、0を指定することにより、ホスト側からlocalhost:8000でアクセスが可能になります。0.0.0.0でも同じです。
  • ローカル環境から普通に開発サーバを起動する場合、python manage.py runserverコマンドで可能ですので、例えば8000ポートで開きたい場合はpython3 manage.py runserver 8000とすれば以下のように出力されて開発サーバーが立ち上がると思います。
Django version 4.1.3, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[09/Mar/2023 08:51:01] "GET / HTTP/1.1" 200 145
  • ただしdockerコンテナでDjangoの開発サーバーを起動する場合は、ホスト側からアクセスする必要があるので、0:8000のようになります。
  • また、当然ですが、docker-compose.ymlで指定したポートでコンテナが立ち上がるので、python3 manage.py runserver 0:8000の8000を8001とかにしてアクセスしてもつながりません。逆に、docker-compose.ymlで8001を指定していれば、python3 manage.py runserver 0:8001としてあげる必要があります(コンテナが起動している場合は一度downして、書き換えてからupします)。
  • ということで、python3 manage.py runserver 0:8000を実行すると以下のように返ってきます。HTTPステータスコードも200なので正常です。
Django version 4.1, using settings 'mysite.settings'
Starting development server at http://0:8000/
Quit the server with CONTROL-C.
[09/Mar/2023 08:55:32] "GET / HTTP/1.1" 200 145
  • dockerコンテナが起動してある状態でhttp://localhost:8000/にアクセスすると無事に繋がったことがわかります。
    image.png

  • 「dockerからじゃなくて、普通にローカルでいじれば良いのでは?w」って感じですが、ふと「これってできるのかな?」と思ったのでやってみました(笑)。せっかく作ったので、これを色々いじってみる実験もしてみます。

参考記事

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9