既存のDjangoプロジェクトを使ってDjango+Nginx+MySQL環境をDockerで構築する

# 目標
既存のDjangoプロジェクトをdocker-composeで起動する。
# 筆者の環境
| 項目 | バージョン |
|--|--|
|wsl2|Ubuntu 20.04 LTS|
|Docker|version 20.10.17, build 100c701|
|docker-compose|version 1.29.2, build 5becea4c|
# 対象
1. 既にDjangoのプロジェクトを持っていてGitHubにあげている。（GitHub専用ではないのでGitさえ使えれば良いです。）
1. Dockerが使える
1. docker-composeが使える
# 対象かどうかをチェック
<b>Docker</b>が使えるかどうか
```bash
$ docker --version
Docker version ~.~.~, build ~~
```
<b>docker-dompose</b>が使えるかどうか
```bash
$ docker-compose --version
docker-compose version ~.~.~, build ~~
```
# ディレクトリ構成
```
.
├── django
│   ├── Dockerfile
│   ├── requirements.txt
├── docker-compose.yml
├── nginx
│   ├── conf
│   │   └── app_nginx.conf
│   └── uwsgi_params
├── sql
    └── init.sql
```
# Dockerfileの準備
```Dockerfile:django/Dockerfile
# alpineだとapt-getが使えない
FROM python:3.9.13-buster

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code
ADD ./requirements.txt /code/
RUN apt-get update -y

# gcc,libmariadb-dev ... mysqlclientに必用。ORMだけなら要らないかもしれないが、あると便利。
# git,vim ... 後に使う
RUN apt-get -y install gcc libmariadb-dev git vim
RUN pip install -r requirements.txt

# Gitの設定
RUN git config --global user.name "<your name>"
RUN git config --global user.email "<your email>"
```
# requirements.txtの準備
Djangoのpip環境をrequirements.txtに出力します。
pip環境、requirements.txtがわからない方は`pip3 -m venv`などで検索してください。
```bash
$ pip3 freeze > requirements.txt
```
筆者の場合
```txt:django/requirements.txt
asgiref==3.5.2
Django==4.0.3
django-cors-headers==3.13.0
djangorestframework==3.13.1
mysql-connector-python==8.0.29
mysqlclient==2.1.1
protobuf==4.21.2
pytz==2022.1
sqlparse==0.4.2
```
# django以外の環境
## nginxの準備

```conf:nginx/conf/app_nginx.conf
upstream django {
    ip_hash;
    server web:8001;
}

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

    location /static {
        alias /static;
    }

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

server_tokens off;
```
## その他
* nginx/uwsgi_params
* sql/init.sql
は<a>https://qiita.com/kenkono/items/6221ad12670d1ae8b1dd</a>を参考にしてください。
# docker-compose.ymlの準備
```dockercompose:. / docker-compose.yml
version: '3.7'

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

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

  web:
    build: ./django
    command: >
      bash -c '
      git clone "<リポジトリのURL>" &&
      mv ./<リポジトリ名>/* ./ &&
      rm -rf ./<リポジトリ名>  && 
      uwsgi --socket :8001 --module <プロジェクト名>.wsgi --chdir /code/  --py-autoreload 1 --logto /tmp/mylog.log
      '
    volumes:
      - ./src:/code
      - ./static:/static
    expose:
      - "8001"
    depends_on:
      - db
```
`bash -c '...' `を使い、commandで複数のコマンドを実行する。
# Dockerコンテナを起動
```bash
$ docker-compose build
$ docker-compose up -d
```
`docker-compose up -d`を2回以上実行するとき、`git clone ~ rm -rf ./<リポジトリ名>`があるとエラーが起こる。
筆者は2回目以降消して実行してい<strong>る。</strong>
が、`git pull origin main`に変更すると良いかも。

追記
mvでは.gitが移動しないので無理でした。
# Djangoの設定
## Djangoのコンテナに入る
```
$ docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS         PORTS
    NAMES
00933ec4d1b1   nginx:1.13      "nginx -g 'daemon of…"   7 seconds ago    Up 5 seconds   80/tcp, 0.0.0.0:80->8000/tcp        <dirname>_nginx_1
2aa3eb633b43   <dirname>_web      "bash -c ' git clone…"   9 seconds ago    Up 7 seconds   8001/tcp
    <dirname>_web_1
189616a28e1b   mysql:8.0       "docker-entrypoint.s…"   11 seconds ago   Up 9 seconds   0.0.0.0:3306->3306/tcp, 33060/tcp   <dirname>_db_1
```
でwebコンテナのコンテナIDを見つけ、中に入り。今回は`2aa3eb633b43`。
```bash
$ docker exec -it 2aa3eb633b43 bash
```
## Djangoのセッティングを変更
コンテナに入った後、settings.pyを変更する。
```
$ vim <プロジェクト名>/settings.py
```
DATABASESを変更する。既にMySQLに接続している人はNAMEやUSER,PASSWORD,HOSTを変えれば良い。
```python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': '3306',
    }
}
```
マイグレーションを実行
```bash
$ python3 manage.py makemigrations
$ python3 manage.py migrate
```
コンテナを出る
```bash
$ exit
```
# Dockerを再起動
docker-composeのgitやmvコマンドを削除しておく
```bash
$ docker-compose up -d
```
# ウェブで確認
起動後、`http://localhost`にアクセスし既存のプロジェクトが出るかを確認する。

# 参考
https://qiita.com/kenkono/items/6221ad12670d1ae8b1dd
MySQLの公式サイト