Django3.0の開発環境をDocker,Docker-compose,Poetryで作ってみた 

# はじめに

Dockerとdocker-composeを使ってDjangoの開発環境を作成します。
他の人が書いた記事にすでにDockerで開発環境をつくる記事はありますが、ライブラリ管理にrequirements.txtを使用しているものも多くあり、現在のパッケージ管理はPipenvやPoetryを使うのが主流となってきている流れもあると思うので

> 引用:　[2020 年の Python パッケージ管理ベストプラクティス](https://qiita.com/sk217/items/43c994640f4843a18dbe)

Dockerを使った開発でも一目で依存関係がわかるPoetryを使ったほうが良いなと思い記事にしてみました。

また個人的に開発環境にてDockerコマンドでコンテナを起動するのが好きでない（docker-composeのほうが楽）なのでdocker-composeでコンテナを起動する方法を書いてます。


# 目次

1. [前提](#a)
2. [動作環境](#a)
3. [Dockerfileの作成](#a)
4. [Djangoプロジェクト作成](#a)
5. [docker-compose.ymlの作成](#a)
6. [コンテナの起動](#a)
7. [最後に](#a)

# 前提
基本的なdockerコマンドとpoetryのコマンドがわかる。
Dockerはインストール済み
docker-composeもインストール済み

インストール方法は他の方が書いた記事が沢山あるので割愛します。


# 動作環境

- MacOS Catalina 10.15.2
- Docker 19.03.5, build 633a0ea
- docker-compose version 1.25.4, build 8d51620a
- docker-image python:3.8
- Python 3.8.1
- Django 3.0.3


# Dockerfileの作成

空のDockerfile作成

```bash

$ touch Dockerfile
```

Docker Hub公式のPythonイメージを使用します。Dockerfileを以下のように記述します。
alpineだとビルド時間がかかるので通常のubuntuベースを使用します。
※以下は例なので適宜編集してください

```dockerfile
FROM python:3.8
WORKDIR /app

ENV PYTHONPATH /app
ENV LC_ALL=C.UTF-8 LANG=C.UTF-8

RUN apt-get update && apt-get install -y --no-install-recommends \
  git \
  vim \
  && rm -rf /var/lib/apt/lists/*

# pipのアップデート
RUN pip install --upgrade pip setuptools wheel
# Poetryをインストール
RUN pip install poetry

# コンテナ内で仮想環境の作成を無効
RUN poetry config virtualenvs.create false
RUN poetry config virtualenvs.in-project true

CMD ["bash"]
```

Poetryのデフォルト設定だとインストール時に仮想環境を作成しようとするので
poetry config virtualenvs.create false
poetry config virtualenvs.in-project true
で無効にしましょう。

作成したDockerfileをビルドします。今回は「django」という名前のイメージを作成します。

```bash
$ docker build -t django .
```

```bash

$ docker run -itd  --name django-setting django
```

コンテナの中に入り必要なライブラリのインストールと新規Djangoプロジェクトを作成します。

```bash

# django-settingコンテナに入る
$ docker exec -it django-setting bash

# Poetryがインストールされているか確認
<コンテナ>:/app# pip list | grep poetry
poetry            1.0.3 

# Poetryの初期設定
<コンテナ>:/app# poetry init
```

YesかスキップでOK

```bash:console

Package name [app]:  
Version [0.1.0]:  
Description []:  
Author [None, n to skip]:  n
License []:  
Compatible Python versions [^3.8]:  
Would you like to define your main dependencies interactively? (yes/no) [yes] 
Search for package to add (or leave blank to continue): 
Would you like to define your dev dependencies (require-dev) interactively (yes/no) [yes] 
Search for package to add (or leave blank to continue): 
Do you confirm generation? (yes/no) [yes] 
```

pyproject.tomlが/app 配下に作られていることを確認してdjangoをインストール

```bash

<コンテナ内>:/app# ls
pyproject.toml

<コンテナ内>:/app# poetry add django
```

# Djangoプロジェクト作成

```bash

# プロジェクト名はprojectにしました。
<コンテナ内>:/app# django-admin startproject project .

# 作成されていることを確認
<コンテナ内>:/app# ls
manage.py  poetry.lock  project  pyproject.toml
```

ctrl + d でコンテナから抜けます。



作成したプロジェクトをコンテナ内からホストのsrcディレクトリへコピーします

```bash

# コンテナIDを確認
$ docker ps
$ docker cp <コンテナID>:/app/ src
```

Dockerfileを更新します。
先程コンテナからホストにコピーしたpyproject.tomlをコンテナ内にコピーする記述をして
poetry installすることでpyproject.tomlに書いたライブラリが
イメージの作成と同時にpipにインストールされます。

```Dockerfile

FROM python:3.8
WORKDIR /app

ENV PYTHONPATH /app
ENV LC_ALL=C.UTF-8 LANG=C.UTF-8

RUN apt-get update && apt-get install -y --no-install-recommends \
  git \
  vim \
  && rm -rf /var/lib/apt/lists/*

RUN pip install --upgrade pip setuptools wheel
RUN pip install poetry

RUN poetry config virtualenvs.create false
RUN poetry config virtualenvs.in-project true

COPY src/pyproject.toml pyproject.toml #追加
RUN poetry install # 追加

CMD ["bash"]

```

Dockerfileを書き換えたので古いコンテナを削除しておく

```bash
$ docker ps # コンテナID確認
$ docker rm -f <コンテナID> # django-settingコンテナ削除
```

# docker-compose.ymlの作成

空のdocker-compose.yml作成

```bash

$ touch docker-compose.yml
```

Dockerfileの準備ができたのでができたのでdocker-compose.ymlの設定をしていきます。

```yaml:docker-compose.yml

version: "3"
services:
  django:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - ./src:/app
    command: "python3 manage.py runserver 0.0.0.0:8000"
    tty: true
```

最終的なディレクトリ

```bash
.
├── Dockerfile
├── docker-compose.yml
└── src
    ├── manage.py
    ├── project
    ├── pyproject.toml
    └── poetry.lock
``` 


# コンテナの起動

```bash

$ docker-compose build
$ docker-compose up
```


```bash:console

Starting django-docker_django_1 ... done
Attaching to django-docker_django_1
django_1  | Watching for file changes with StatReloader
django_1  | Performing system checks...
django_1  | 
django_1  | System check identified no issues (0 silenced).
django_1  | 
django_1  | You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
django_1  | Run 'python manage.py migrate' to apply them.
django_1  | 
django_1  | February 06, 2020 - 09:38:45
django_1  | Django version 3.0.3, using settings 'project.settings'
django_1  | Starting development server at http://0.0.0.0:8000/
django_1  | Quit the server with CONTROL-C.
```


http://localhost:8000
にアクセスすると見えているはず！

<img width="1076" alt="django-first.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299151/f48498ae-0976-38e4-e079-ac2c9e80ea89.png">


```bash

cat pyproject.toml
```

```console
[tool.poetry]
name = "app"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.8"
django = "^3.0.3"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

```

パッケージ管理できてる！


# 最後に

お疲れさまでした。

> ソース：
> https://github.com/k4ssyi/django-docker

https://twitter.com/k4ssyi