docker-composeでDjangoの開発環境を最速構築

docker-composeを利用して「Django+nginx+uwsgi+mysql」の環境を簡単に構築するためのリポジトリを公開しました。

[公開リポジトリ](https://github.com/mofumofutips/django-docker)

git cloneしていただいてコンテナを立ち上げるだけで簡単に構築できます。

プロジェクト名を変更したい場合は各設定ファイルを変更し再度コンテナを立ち上げなおしてください。

cloneした段階でDBへの初期migrateが終わっている状態です。

毎回docker-compose.ymlを書くのがめんどくさかったのでリポジトリにおいて、せっかくなら公開しておこうかなということで公開してみました。

基本的な構造は以下のファイルですので、自分で構築してみたい方は参考にしてみてください。

（もっといい方法あるよ的なコメント待ってます）

基本的にコピペで動きますが、ファイル名などを変更したい場合は適宜変更してください。

# ファイル構成

```
django-docker
 ├django
（├djangoのファイル群）
 ├mysql
  ├sql
   ├init.sql
（├mysqlのファイル群）
 ├nginx
  ├conf
   ├app_nginx.conf
  ├uwsgi_params
 ├python
  ├Dockerfile
  ├requirements.txt
 ├docker-compose.yml
```
（）内のファイルは気にしなくて大丈夫です。

## docker-compose.yml
まずは中身を見ていきます

``` 
version: '3'

services:
  nginx:
      image: nginx:1.13
      ports:
        - "8000:8000"
      volumes:
        - ./nginx/conf:/etc/nginx/conf.d
        - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
        - ./static:/static
      depends_on:
        - python

  db:
      image: mysql:5.7
      command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
      ports:
        - "3306:3306"
      environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_DATABASE: django_docker
        MYSQL_USER: user
        MYSQL_PASSWORD: password
        TZ: 'Asia/Tokyo'
      volumes:
        - ./mysql:/var/lib/mysql
        - ./mysql/sql:/docker-entrypoint-initdb.d

  python:
      build: ./python
      command: uwsgi --socket :8001 --module django_docker.wsgi --py-autoreload 1 --logto /tmp/mylog.log
      volumes:
        - ./django:/code
        - ./static:/static
      expose:
        - "8001"
      depends_on:
        - db
```

WebseverとDB、アプリをそれぞれコンテナを分けてビルドします。

※Webseverのポート（今回は8000番）は開けておいてください。

## nginx

「nginx」のフォルダ内はuwsgiのパラメータ用ファイル「uwsgi_params」とnginxのコンフィグファイル「conf/app_nginx.conf」を用意します

### uwsgi_params

```
uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
```

### conf/app_nginx.conf

```
upstream django {
    ip_hash;
    server python:8001;
}

server {
    listen      8000;
    server_name 127.0.0.1;
    charset     utf-8;

    location /static {
        alias /static;
    }

    location / {
        uwsgi_pass  django;
        include     /etc/nginx/uwsgi_params;
    }
}

server_tokens off;
```

## mysql
「mysql」フォルダではDBユーザーに権限を与えるSQLだけ最初に走らせます。

### sql/init.sql
```
GRANT ALL PRIVILEGES ON django_docker.* TO 'user'@'%';

FLUSH PRIVILEGES;
```
SQLの意味が分からなくても問題ありませんが、気になる方はググってみてください。

## python
「python」フォルダではpythonコンテナをビルドする時に走らせるスクリプトと必要なpythonのライブラリをインストールするスクリプトを記述しておきます。

### Dockerfile
pythonのバージョンは好きに変えていただいて大丈夫です。

最新だと3.9かな？（間違ってたらすみません）

```
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
```

### requirements.txt
pythonコンテナにインストールしておきたいライブラリを記述します。

ライブラリのバージョンは指定しなくても問題ありませんが、開発環境で各ライブラリのバージョンを指定できることがDockerの良さでもありますので指定してあげるといいと思います。

```
Django==3.1
uwsgi==2.0.18
mysqlclient==2.0.3
```

## ファイルの用意ができたら
ファイルの用意ができましたらコンテナを起動してみましょう

```
docker-compose up
```

これでコンテナ自体は立ち上がると思いますが、まだdjangoのプロジェクトが存在しないので作ってあげましょう。

※git cloneした場合はここから下の作業は既に行われていますのですぐに開発が可能です。

```
docker-compose exec python django-admin startproject プロジェクト名
```

djangoとDBの疎通が行われているかの確認を含めてmigrateもしておきましょう

```
docker-compose exec python python manage.py migrate
```

## さいごに

走り書きになってしまったので説明不足な部分が多いと思いますのがご了承ください。

Webアプリのフレームワークって最初に同じ作業するのでめんどくさいですよね。

自動化できる部分は自動化していくとより、自分に合った開発環境が簡単に構築できると思います！

少しでも誰かの参考になったら嬉しいです。