Windows 10 HomeへDockerをインストールしてDjango + PostgreSQL環境作る

以前まではwindows 10 Proでないと`Docker`使えませんでしたが、Windows 10 Home でもDockerが簡単に使えるようになっています。MacとかWindows 10 Proの導入はたくさんあるけど、長年Homeで使えなかったので今回記事にします。
`Django(Python)`の記事をよく書いていますのでwindows homeで環境を構築しようと思います

すでにDocker使ってて、`Docker + Django + PostgreSQL`の環境構築したい人は[DockerでDjangoを動かす](#dockerでdjangoを動かす)から見れば構築できると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/a83977fe-6379-22af-a272-ae7445b05cb2.png)

# 環境

- Windows 10 Home 21H1
- Docker Desktop for Windows 4.0.0

まあ、最近のwindowsのアップデートちゃんとやってれば使えると思います


## Dockerで構築するDjango環境
ローカルで開発するときに使えるDjango構築していきます。

- Django 3.2
- PostgreSQL

こちらは、慣れてきたら変更可能なので適時変更してください。

ついでに、`Django`関係で初心者向け記事も書いてますのでよろしければ。

[:point_right_tone1: 【Python Django】初心者プログラマーのWebアプリ](https://qiita.com/Bashi50/items/c686d30fa4fdba4582ad)


[:point_right_tone1: 【丁寧解説】秒速でもDjango 3アプリをAWS EC2で公開【Nginx, gunicorn, postgresqlデプロイ】](https://qiita.com/Bashi50/items/d5bc47eeb9668304aaa2)


# ソースコード
この章の完成時コードは以下です。確認やコピペでどうぞ

https://github.com/kohishibashi/django_docker/tree/docker-django-init

# ダウンロードとインストール
`Docker Desktop Installer.exe`をダウンロードしてください。

https://www.docker.com/products/docker-desktop

実行する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/b2efe5e0-f5cf-f65c-217c-c0eaf84d150c.png)
結構時間かかるかも。ポチポチ進めていけばOK

`Close and restart`とか`Close`とか出るので押してください。

これでOKかと思ったらWSL2のインストール必要みたいです。
まあ面倒なのがここだけですので頑張りましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/74914682-e510-d5d0-3300-7cd5891996ca.png)


ダウンロード先

https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package

`x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ`
みたいなリンクあるのでダウンロードしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/28c639f4-4b6d-1e2b-1604-285a97d26bab.png)

ダウンロードできたら実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/3a404d13-94cd-2576-44df-a3a1e33731cf.png)

Next押して行ってFinish押せば完了しました。
再起動したらインストール作業は完了です。

Dockerを起動して右下のクジラが白いのが正常です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/b9ab5086-79bc-9a5b-a215-dbdfa7957135.png)

windows 10 homeでDocker使いたいだけの人ならこれで終了です。

# DockerでDjangoを動かす
これ以降はDjango環境をローカルに構築します。
最初に起動したらDockerのチュートリアルも表示されたと思いますが、今回は`Django`の環境を構築してみましょう。


## フォルダ作って`Dockerfile`を作成
好きなところにフォルダ作ってその中に`Dockerfile`を作成します。
`Dockerfile`がよくわからない方は環境の作る手順書かれたファイルみたいに思っておけばいいかと。


```Dockerfile
# syntax=docker/dockerfile:1
FROM python:3
ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY requirements.txt /app/
RUN pip install -r requirements.txt
COPY . /app/
```

### 細かく内容説明
使いたいだけなら次にいってOK

- `FROM python:3`: Python 3 の最新イメージを使用
- `ENV PYTHONUNBUFFERED=1`: 「ENV」は環境変数の設定。Python使うときの環境変数
- `WORKDIR /app`: これ以降どこのディレクトリで作業するか
- `COPY requirements.txt /app/`: ファイルコピー`requirements.txt`を作りましたよね。- - `/app`にディレクトリにコピーしてる。仮想環境なのでコンテナの中には今のところファイル存在ないのでコピー必要
- `RUN pip install -r requirements.txt`: RUNがコマンド実行ということ。`pip install`して必要パッケージをテキストで記述してまとめてインストールするために使う
- `COPY . /app/`: この時点で` requirements.txt`しかファイル存在してない。これではアプリ動きようがないのでDjangoアプリのファイル全部コピーしてる

## requirements.txt作成してインストールするパッケージを記述
先ほど`Dockerfile`でも触れましたがDokcerの環境で使用するパッケージをまとめてインストールしてもらうために`requirements.txt`に記述します。


```requirements.txt
Django>=3.2,<3.3
psycopg2-binary>=2.8
```

インストールする`Django`と`PostgreSQL`をDjango使うために必要なパッケージを記述します。

メジャーバージョンだけ上がらないようにしており、かなりバージョンが雑に指定しているので、`Django>=3.2,<3.3`とか絞ったほうが本来はいいと思います。

## `docker-compose.yml`作成
とりあえず動けばいいかくらいの設定です。

```docker-compose.yml
version: "3.9"
   
services:
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
      environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    depends_on:
      - db
```

### 細かく内容説明
使いたいだけなら次にいってOK

- `version`: Docker-composeのバージョン「3」とかでもいいです。
- `services`: 今回使うのはPostgreSQL、Djangoアプリなのでそれぞれ「db」「web」という名前つけてます。
  - `db`: イメージは取得してきたpostgresを使用します。既製品という感じ？
      - `volumes`: コンテナってデータ保持能力ないんです。動いてるときはいいけど、毎回消えます。それだとDBの意味ないですよね。ということでローカルの`./data/db`に保存したというか、共有したというか思っておけばとりあえずいいと思います。
      - `environment`: コンテナ内だけで使う環境変数設定できるので設定。
  - `web`: Djangoアプリ用。Linux環境にPython入ってる環境を改造して色々入れてる感じ。
      - `build: .` つまりdocker-composeにあるディレクトリでビルドしてる。`dockerfile`のディレクトリ注意
      - `command:`　コマンド実行してるサーバー立ち上げてる。ついでに起動した開発サーバー止まるとコンテナ止まる。
      - `ports:`　ポートフォワード。ホスト側8000番→コンテナ8000番に通してる。だからブラウザにlocalhost:8000で繋げることができてる。
      - `environment`: settings.pyで使う環境変数なので重要
      - `depends_on`: DB起動してからでないとDjango使えないというか、エラー出るので上で決めた「db」が起動してから「web」起動してねってこと

## Djangoのプロジェクト作成
コマンドラインにて以下を実行。今回はプロジェクト名は`app`で作ります。

```
docker-compose run web django-admin startproject app .
```

`docker-compose run`が単体で起動。`web`と定義したもので、`django-admin startproject app .`を実行してください、ということ。

Django使ったことある人ならわかると思うけど、Djangoで最初にプロジェクト始めるためのコマンド。


初めて実行すると構築に必要なイメージを勝手に取得してくれますのでしばらくかかります。


```
 => [2/5] WORKDIR /app                                                                                                                                                    36.1s 
 => [3/5] COPY requirements.txt /app/                                                                                                                                      0.2s 
 => [4/5] RUN pip install -r requirements.txt                                                                                                                             10.4s 
 => [5/5] COPY . /app/                                                                                                                                                     1.7s 
 => exporting to image                                                                                                                                                     1.2s 
 => => exporting layers                                                                                                                                                    1.2s 
 => => writing image sha256:394255b3848438c6533f150499a35141a7c2a886a143aa4e34b4c57adb5z59ac                                                                               0.0s 
 => => naming to docker.io/library/django_docker_web                                                                                                                       0.0s 

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
```
こんな感じの表示出たらOK

volumeにDBの記載したからDB関係のファイル大量にできるはず。pushするとかで気になる人は後で記述する`.gitignore`で除外するようにしてください。




# settings.pyにDBの設定を追加

DB起動できないので設定を変更。とりあえず、これでDBにつなげるからデータ保存などできる。

```django_docker/app/settings.py
...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
}

...
```

# docker-compose up でDjango起動

では、起動コマンド。

```
docker-compose up
```


これでエラーが出なければこんなふうに起動すると思います。

> http://localhost:8000/


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/e36eea8d-626d-d1e6-a5b7-d15f5795a016.png)


はい、ちゃんと起動しました！！


# その他の設定
以降は必須でないです。すでに`Docker + Docker + PostgreSQL`は使えます。
チャレンジしてもいいと思います。

## Djangoの設定いじる
日本時間の方が都合がいいと思うのでいじります。

```django_docker/app/settings.py
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
```

日本語なりました。管理画面や、時間を扱うとき地味に重要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/97593564-fa6a-ab86-72c5-6f0679451f67.png)

## DBのデータをpushするのはよくない
現状だとDBのデータや設定が書いてある大量のファイルがpushされます。差分が大量にあるのも良くないし、見せてはいけないデータあったら大変なのでgithubにpushされないようにします。

`.gitignore`を作って、`/data`を追加してください。差分が激減します。
ついでに、Python関係で一般的にpushされるとやばいファイルについても追加したものがソースコードにありますので、必要な方はコピペしてください。


```:.gitignore
data/
```

## docker-composeで環境変数を設定
まあ、必要ないけどデプロイのとき環境変数の使い方知ってるとよいので設定しておきます。


```django_docker/app/settings.py
import os
...

SECRET_KEY = os.environ.get('SECRET_KEY')

...

DEBUG = bool(int(os.environ.get('DEBUG', 0)))

...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': os.environ.get('DB_HOST'),
        'PORT': int(os.environ.get('DB_PORT')),
    }
}
```


```django_docker/docker-compose.yml
services:
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - DB_NAME=postgres
      - DB_USER=postgres
      - DB_PASSWORD=postgres
      - DB_HOST=db
      - DB_PORT=5432
      - DEBUG=1
      - SECRET_KEY=devsecretkey
    depends_on:
      - db
```
ついでに、起動するときに`--build`つけるとビルドして起動してくれるから便利。

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

問題なく起動するか確認してくださいね。


## VS Codeの拡張機能でWindows使いながらLinux使う
補足情報です。やりたい人だけで構いません。

Windowsだとコマンドプロンプト使わないといけなかったり、色々面倒なことあります。
Windows使ってるけど、Linux使いたいなーという人に役立つ機能。

VS codeの拡張機能追加で`Remote Development`と検索して追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/4dbfbb4a-d067-3b9b-9037-e58d9457834d.png)


左下の緑のボタン押してやると選択項目出るので`Open Folder in Container`
私の場合は`django_docker`を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/9f7106f2-c0d0-cb26-22de-e038966cdb20.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/ef0a8c9d-6aaf-8e10-2aa4-13a680c11587.png)

`From Dockerfile`選ぶと今回構築に使用したPythonイメージ、つまりLinux開発環境がWindowsで手に入ります。
最初は少し時間かかるかも。

終わったら、こんな感じでちゃんとコマンド使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260345/383081d7-76a9-6aa7-8ff2-ef24a106b812.png)


# ソースコード
この章のコードは以下です。確認やコピペでどうぞ

https://github.com/kohishibashi/django_docker/tree/docker-django-init