Dockerを用いたDjangoプロジェクト構築

この記事はDockerを用いてDjangoプロジェクトの構築をすることを紹介する．共同開発時に開発環境を揃えたり，リソース管理をDockerで行いたい人向けである．
>Djangoの説明や仮想環境を用いて構築する場合はこちらを参照
https://qiita.com/tarakokko3233/items/46c567fb32a26a69269a

## はじめに　〜Dockerとは〜
Dockerは，アプリケーションを環境に依存せず一貫した方法で開発，デプロイ，実行するためのプラットフォームである．コンテナ化技術を使用することで，環境の一貫性，移植性，スケーラビリティ，リソース効率，開発効率が向上し，マイクロサービスアーキテクチャの実装やCI/CDパイプラインの強化にも役立つ．

**環境の一貫性**
Dockerはアプリケーションとその依存関係をコンテナ内にパッケージ化するため異なる環境間で一貫した動作を保証する．
開発，テスト，ステージング，本番環境で同じDockerイメージを使用することで，環境差異によるバグを防ぐことができる．

**移植性**
Dockerコンテナは，LinuxやWindowsなどの異なるオペレーティングシステム上で実行できる．
アプリケーションをDockerイメージとしてパッケージ化することで，異なるインフラストラクチャ間で簡単に移行できる．

**スケーラビリティ**
Dockerを使用すると，アプリケーションを複数のコンテナに分割し，必要に応じてスケールアップ・ダウンすることができる．
コンテナオーケストレーションツール（Kubernetes、Docker Swarmなど）と組み合わせることで，大規模なアプリケーションを効率的に管理できる．

**リソース効率**
Dockerコンテナは，仮想マシンと比較してオーバーヘッドが小さく，リソースを効率的に使用できる．
複数のコンテナを1台のホストマシン上で実行することで，ハードウェアコストを削減できる．

**開発効率**
Dockerを使用することで，開発者は自分のローカル環境でアプリケーションの依存関係を簡単に管理できる．
新しい開発者がプロジェクトに参加する際，Dockerを使用することで環境セットアップの時間を大幅に短縮できる．

**マイクロサービスアーキテクチャ**
Dockerは，マイクロサービスアーキテクチャの実装に適している．
各マイクロサービスをDockerコンテナとして分離することで，サービス間の結合を低く保ち，独立したデプロイと拡張が可能になる．

**CI/CDの強化**
Dockerを継続的インテグレーション・継続的デリバリー（CI/CD）パイプラインに組み込むことで，アプリケーションの構築，テスト，デプロイを自動化できる．
これにより，リリースプロセスの信頼性と速度が向上する．

>事前準備としてCLIを使わずにDockerコンテナを実行するためにDocker Desktopをインストールすると良い
https://www.docker.com/products/docker-desktop/

## 1.プロジェクトディレクトリの作成
プロジェクトを作成し，カレントディレクトリを作成したディレクトリに移動する．
```
$ mkdir yourprojectname
$ cd yourprojectname
```

## 2.Dockerイメージ用ファイル作成
**requirements.txtの作成**
Pythonプロジェクトの依存関係を記述するためのテキストファイル．このファイルには，プロジェクトが正常に機能するために必要なPythonパッケージとそのバージョンが列挙されている．
```requirements.txt
Django==4.1.7
//その他使用するパッケージとそのバージョンを記述
```

**Dockerfileの作成**
Dockerイメージをビルドするための命令を含むテキストファイル．Dockerfileには，ベースイメージの指定，必要なパッケージのインストール，ファイルのコピー，環境変数の設定，コンテナ起動時に実行するコマンドなどの手順が記述されている．

```Dockerfile
FROM python:3.9

ENV PYTHONUNBUFFERED=1

WORKDIR /yourprojectname

COPY requirements.txt /yourprojectname/

RUN pip install -r requirements.txt

COPY . /yourprojectname/
```
**docker-compose.ymlの作成**
docker-compose.ymlは，複数のDockerコンテナを定義し，それらの間の関係を設定するために使用されるYAML形式のファイル．
```docker-compose.yml
version: '3'

services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/yourprojectname
    ports:
      - "8000:8000"
```

## 3.Djangoプロジェクトとアプリケーションの作成
Docker Composeを使用してDjangoプロジェクトを作成する．
>`docker-compose run`はDocker Compose経由で新しいコンテナを起動し，指定されたコマンドを実行する．
>`web`はdocker-compose.ymlファイルで定義されているサービス名を指定する．
>>django-admin startprojectに関しては[こちら](https://qiita.com/tarakokko3233/items/46c567fb32a26a69269a)を参照．
```
$ docker-compose run web django-admin startproject yourprojectname .
```
このコマンドを実行すると，Docker Composeはwebサービス用の新しいコンテナを起動し，その中で実行する．これにより，現在のディレクトリにyourprojectnameという名前の新しいDjangoプロジェクトが作成される．

同様にdjangoアプリケーションを作成する．
```
$ docker-compose run web python manage.py startapp yourappname
```
>python manage.py startappに関しては[こちら](https://qiita.com/tarakokko3233/items/46c567fb32a26a69269a)を参照．

これでこのようなディレクトリ構造になっているはずである．
```
yourprojectname
├── docker-compose.yml
├── Dockerfile
├── manage.py
├── requirements.txt
├── yourprojectname
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└──yourappname
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations/
    │   └──  __init__.py
    ├── models.py
    ├── tests.py
    └── views.py
```
Dockerfileやdocker-compose.ymlやrequirements.txtをgitなどで共有し各々のデバイスで実行すれば同じ環境を構築できる．
>djangoプロジェクトの階層説明は[こちら](https://qiita.com/tarakokko3233/items/8787692aaf9b1d943205)を参照．


## 4.settings.pyの設定
`yourprojectname/yourprojectname/settings.py`を開き，
`INSTALLED_APPS`の中に
```yourprojectname/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'yourappname', #これを追加
]
```
を追加する．これはDjangoにアプリケーションyourappnameを認識させるために必要である．

さらに
`ALLOWED_HOSTS`の中に
```yourprojectname/settings.py
ALLOWED_HOSTS = [
    'localhost',
    '0.0.0.0',
]
```
を追加する．これは後ほどローカルサーバを立ち上げることを許可するために必要である．

## 5.Dockerコンテナを起動
Dockerコンテナを起動してローカルサーバを起動．①または②を行う．


①CLIで以下のコマンドを実行
```
$ docker-compose up
```


②Docker DesktopでContainersを選び，
![スクリーンショット 2024-04-16 23.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/83a640ea-40be-137a-da18-bee5f35968a0.png)
実行ボタンを押す．
![スクリーンショット 2024-04-16 23.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/90ab287b-7523-7ddd-3918-702c68f2de4e.png)


いずれかを実行したら，

http://0.0.0.0:8000
にアクセスして以下の画像が表示されたら構築完了である．
![スクリーンショット 2024-04-16 23.39.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/6dde9003-9eb4-8224-3ccc-b80c54090f95.png)