VSCodeとDockerで開発環境構築 (Python + PostgreSQL + Git)

# はじめに
　Python（Django）とPostgreSQLが動作するDocker コンテナを構築し、
　VSCodeを使ってコンテナ上のソースコードを修正するまでの手順を説明します。
　※ 本投稿は、Mac OSを前提としています。
　　投稿時点のバージョン：macOS Monterey 12.4
|No.|項目|説明|
|:---|:---|:---|
|1|VSCode|コードエディタです。本投稿のメインとなります。<br/>コンテナ上で開発が行えるようになります。|
|2|Docker Compose|複数のDocker コンテナを一元管理するツールです。<br/>本投稿では、Python、PostgreSQLのコンテナを構築します。|
|3|Django|PythonのWebフレームワークです。|
|4|PostgreSQL|DBサーバです。<br/>Webアプリケーションで利用するデータを保持します。|
|5|Git|ソースをGitHubで管理します。|

[開発環境のイメージ]
　VScodeのRemote Containersプラグインによって、
　VSCode Serverがコンテナにインストールされ、ローカルのVSCodeと連携可能になります。
　これにより、ローカルにはPythonなどのインストールは必要なく、
　コンテナ上の開発環境でローカルマシンのように開発ができるようになります。
![FireShot Capture 010 - Developing inside a Container using Visual Studio Code Remote Develop_ - code.visualstudio.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/d94053d0-fe14-ea7b-ef19-16432777f523.png)
[Developing inside a Container - Visual Studio Code](https://code.visualstudio.com/docs/remote/containers) より引用

# 作業手順
　以下の順で説明していきます。
　　1. Docker for Macのインストール
　　2. VSCodeのインストール
　　3. Docker コンテナの設定
　　4. VSCodeでコンテナに接続
　　5. Djangoプロジェクトの作成
　　6. PostgreSQLの設定
　　7. 動作確認
　　8. Gitとの連携

# 1. Docker for Macのインストール
　既にインストール済みの場合は、1.はスキップし、
　「2. VSCodeのインストール」の作業から始めて下さい。
## 1-1. ダウンロード
　(1) 以下のサイトにアクセスします。
　　https://docs.docker.com/desktop/mac/install/
　(2) Mac with Apple siliconを押下します。
　　Docker.dmgがダウンロードされます。
## 1-2.インストール
　(1) Docker.dmgを実行します。
　(2) Docker.appをApplicationsに移動します。
　(3) Dockerを実行します。
　　Docker デーモンが起動されます。
## 1-3. インストール確認
　以下のコマンドをターミナルで実行します。
　正常に実行できればインストール確認はOKです。
```php
docker version
```

# 2. VSCodeのインストール
## 2-1. ダウンロード
　(1) 以下のサイトにアクセスします。
　　https://code.visualstudio.com/download
　(2) MacのApple Siliconを押下します。
　　![qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/d4a33793-510b-5361-0fe2-341cfeb6d056.png)
　　VSCode-darwin-arm64.zipがダウンロードされます。
## 2-2.インストール
　(1) VSCode-darwin-arm64.zipを解凍します。
　　Visual Studio Code.appが作成されます。
　(2) Visual Studio Code.appをApplicationsに移動します。
　(3) Visual Studio Codeを実行します。
![スクリーンショット 2022-10-28 16.40.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/a7ff08bc-7eb6-c397-76e4-c2d6cd0a04ad.png)
## 2-3. 拡張機能の設定
　(1) 左パネルのExtensionsボタンを押下します。
　(2) 検索ボックスに"dev containers"と入力します。
　(3) Dev Containersをインストールします。
![qiita4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/5300d86f-d736-792f-190a-63df324d3823.png)
　上記と同じ手順で「Japanese Language Pack for Visual Studio Code」も
　インストールしておくと日本語で表示されるようになります。

# 3. Docker コンテナの設定
## 3-1. 作業ディレクトリの作成
　任意のパスに作業ディレクトリを作成します。
　例：django-sample01
```php
mkdir django-sample01
```
## 3-2. 「Docker」ディレクトリの作成
　作業ディレクトリ直下に「Docker」を作成します。
　※ Docker関連のファイルを格納します。
```php
mkdir Docker
```
## 3-3. 「docker-compose.yml」ファイルの作成
　Docker直下に「docker-compose.yml」を作成します。
```php
vi docker-compose.yml
```
　以下の内容を記載します。
```php
version: '3'

services:
  web:
    build: .
    tty: true
    volumes:
      - ../:/workspace
    depends_on:
      - db

  db:
    image: postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: django_sample

volumes:
  postgres_data:
```
[docker-compose.ymlの説明]
　①"web"は、Pythonのコンテナとなります。
　②"build"に、「.」を指定しているので同階層のDockerfileをベースに
　　コンテナが作成されます。
　③"tty"は、指定するとコンテナが正常終了するのを防ぎます。
　④../:/workspaceの指定により、コンテナ内の「/workspace」ディレクトリに、
　　ホスト側のDjangoプロジェクトを配置しています。
　⑤"db"は、PostgreSQLのコンテナとなります。
　⑥postgres_data:の指定により、PostgresSQLのデータを永続化しています。
## 3-4. 「Dockerfile」ファイルの作成
　「docker-compose.yml」の"build"に、「.」を指定しているので
　「docker-compose.yml」と同一の階層に「Dockerfile」を作成します。
```php
vi Dockerfile
```
　以下の内容を記載します。
```php
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN pip install django
RUN pip install psycopg2
```
[Dockerfileの説明]
　①django
　　Pythonのフレームワーク（Django）を利用するためのライブラリ
　②psycopg2
　　PythonからPostgreSQLを操作するためのライブラリ
## 3-5. 「.devcontainer」ディレクトリの作成
　作業ディレクトリ直下に「.devcontainer」を作成します。
　※ VSCode関連（リモート接続関連）のファイルを格納します。
```php
mkdir .devcontainer
```
## 3-6. 「devcontainer.json」ファイルの作成
　.devcontainer直下に「devcontainer.json」を作成します。
```php
vi devcontainer.json
```
　以下の内容を記載します。
```php
{
  // 表示名
  "name": "Django Sample",
  // docker-compose.ymlでイメージ・コンテナを作成
  "dockerComposeFile": "../Docker/docker-compose.yml",
  // VSCodeのワークスペースフォルダ
  "workspaceFolder": "/workspace",
  // 使用するサービス
  "service": "web",
  // リモート先のVSCodeにインストールする拡張機能
  "extensions": [
    "ms-python.python"
  ],
  // VSCodeを閉じた時、コンテナが自動停止するように指定
  "shutdownAction": "stopCompose"
}
```
[devcontainer.jsonの説明]
　①"name"は、VSCodeに表示される名前となります。（好きな名前を設定して下さい。）
　②"dockerComposeFile"は、実行するdocker-compose.ymlを指定します。複数指定が可能。
　③"service"は、開発環境として利用するサービス（コンテナ）となります、
　　docker-compose.ymlに定義した名前と一致させます。
　　※ 本投稿では、Pythonのコンテナ"web"を指定しています。
　④"workspaceFolder"は、VSCodeで開くワークスペースの作業ディレクトリとなります。
　⑤"extensions"は、コンテナにインストールする拡張機能を指定します。
　　後から手動でインストールも可能です。
　⑥"settings"は、コンテナのデフォルト設定をあらかじめ追加できます。
　　本投稿では設定していません。
　⑦"shutdownAction"は、VSCodeを閉じた時の挙動です。
　　デフォルトは、"stopCompose"でコンテナが自動的に停止します。
　　"none"を指定するとコンテナは起動したままとなります。
## 3-7. 「src」ディレクトリの作成
　作業ディレクトリ直下に「src」を作成します。
　※ Pythonのファイルを格納します。
```php
mkdir src
```
## 3-8. ディレクトリ構成の確認
　以下のコマンドを実行し、作業ディレクトリの内容を確認します。
```php
tree -a .
```
　以下のように表示されます。
```php
.
├── .devcontainer
│   └── devcontainer.json
├── Docker
│   ├── Dockerfile
│   └── docker-compose.yml
└── src

3 directories, 3 files
```

# 4. VSCodeでコンテナに接続
## 4-1. コンテナへの初回接続
　(1) VSCodeの左下の緑のアイコンをクリックし、
　　「Open Folder in Container…」を選択します。
![qiita5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/93c00cd2-3bda-dc8d-f232-a943ea3bfcd1.png)
　(2) 作業ディレクトリを選択します。
　　「3-1. 作業ディレクトリの作成」で作成した作業ディレクトリを指定します。
　　django-sample01
## 4-2. リモート環境の確認
　(1) WORKSPACEに作業ディレクトリ内のディレクトリ/ファイルがマウントされています。
![スクリーンショット 2022-10-30 16.08.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/9a781146-9f4e-1a7b-715f-25474396b19d.png)
　(2) リモート先のVSCodeに拡張機能が追加されているのが確認できます。
![スクリーンショット 2022-10-30 16.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/fac127d9-6189-919e-728a-0391c170d95e.png)
　(3) ツールからターミナルを選択し、「新しいターミナル」を開きます。
　　① 以下のコマンドを実行し、Pythonのバージョンを確認します。
```php
python -V
```
　　② 以下のコマンドを実行し、Djangoのバージョンを確認します。
```php
python -m django --version
```
　　Python、Djangoともにリモート環境にインストールされていることが確認できます。
　　そのため、ローカル環境にPythonなどのアプリケーションを用意する必要がありません。
## 4-3. コンテナの確認
　作成されたコンテナを確認します。
　ローカルのターミナルで以下のコマンドを実行します。
```php
docker ps -a
```
　以下の内容が表示されます。
```php
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS                    PORTS                    NAMES
96a14cfbdc91   docker_web            "/bin/sh -c 'echo Co…"   13 seconds ago   Up 12 seconds                                      docker_web_1
8955ce46f565   postgres              "docker-entrypoint.s…"   13 seconds ago   Up 12 seconds             0.0.0.0:5432->5432/tcp   docker_db_1
```

# 5. Djangoプロジェクトの作成
## 5-1. プロジェクトの作成
　(1) VSCodeのターミナルでsrcディレクトリに移動します。
```php
cd src
```
　(2) Djangoプロジェクトを作成します。
　　VSCodeのターミナルで以下のコマンドを実行します。
```php
django-admin startproject djangoSampleApp .
```
## 5-2. 作業ディレクトリを確認します。
　ローカル、リモートの両方のsrcディレクトリ内にDjangoプロジェクトが
　作成されていることが確認できます。
　ローカルのターミナルで以下のコマンドを実行します。
```php
tree -a .
```
　以下のように表示されます。
```php
.
├── .devcontainer
│   └── devcontainer.json
├── Docker
│   ├── Dockerfile
│   └── docker-compose.yml
└── src
    ├── djangoSampleApp
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py

4 directories, 9 files
```

# 6. PostgreSQLの設定
## 6-1. Djangoのデータベースの設定を変更
　デフォルトのsqlite3をPostgreSQLに変更します。
　VSCode上で”/workspace/djangoSampleApp/settings.py”の
　DATABASES属性を以下のように修正します。
　　変更前
```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
```
　　変更後
```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'django_sample',
        'USER': 'postgres',
        'PASSWORD': 'password',
        'HOST': 'db',
        'PORT': 5432,
    }
}
```
## 6-2. テーブルの作成
　VSCodeのターミナルで以下のコマンドを実行します。
```python
python manage.py migrate
```
　以下のように表示されます。
```php
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
```

# 7. 動作確認
## 7-1. サーバの起動
　VSCodeのターミナルで以下のコマンドを実行し、サーバを起動します。
```php
python manage.py runserver
```
## 7-2. 画面の確認
　[http://127.0.0.1:8000/](http://127.0.0.1:8000/)にアクセスすると
　Djangoの画面が表示されます。
![FireShot Capture 014 - The install worked successfully! Congratulations! - 127.0.0.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/f535f135-9183-fcd5-f9d8-1f7fc3f16e9a.png)
## 7-3. データベースの確認
　本投稿では、SQLクライアントツールとしてDBeaverを利用しますが
　どのSQLクライアントツールでも構いません。
　※ DBeaverについては、[DBeaverのインストールとPostgreSQLへの接続](https://qiita.com/Ryooota/items/755e249f5241d2c964e6)に
　　記載していますので参考にして下さい。
　(1) DBeaverを起動します。
　(2) ログイン
　　① データベースから新しい接続を選択します。
　　② PostgreSQLを選択し、次へボタンを押下します。
　　③ 接続情報を入力し、終了ボタンを押下します。
　　　Host：localhost
　　　Database：django_sample
　　　ユーザ名：postgres
　　　パスワード：password
　　　※ docker-compose.ymlの「db」の部分でport指定をすることで、
　　　　ローカルからDocker上のDBにアクセスが可能となります。
　(3) 下記のように作成したテーブルの確認ができます。
![スクリーンショット 2022-11-12 23.18.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/eba3add0-bd01-fb0d-ff85-f2d3b3a590d7.png)
## 7-4. Djangoの管理画面の確認
　(1) 管理画面にログインするためのユーザを作成します。
　　VSCodeのターミナルで以下のコマンドを実行します。
　　任意のUsername、Email address、Passwordを入力して下さい。
```php
python manage.py createsuperuser
```
　(2) 開発サーバの起動
　　VSCodeのターミナルで以下のコマンドを実行します。
```php
python manage.py runserver
```
　(3) 管理画面にアクセスする。
　　[http://localhost:8000/admin/](http://localhost:8000/admin/)にアクセスし、
　　(1)で作成したユーザでログインすると管理画面が表示されます。
![FireShot Capture 015 - Site administration - Django site admin - localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/005dca77-684e-cb69-d11a-6359b5e5631a.png)

以上により、Dockerを使って作成したPythonコンテナにVSCodeで接続し、
Djangoのアプリケーションを作成できること、PostgreSQLコンテナにSQLクライアントツールで接続し、DBの状態を確認することが出来ました。
本投稿のメインは以上となりますが、開発する上でソースコードをGitで管理することは必須であるため、最後に補足としてソースコードをGitHubに連携する手順を簡単に記載します。

# 8. Gitとの連携
## 8-1. GitHubにリポジトリを作成
　(1) GitHubのページを開きます。
　　アカウントを持っていない場合は、アカウントの作成をお願いします。
　(2) リポジトリを新規に作成します。
　　① Repository name（任意の名前）を指定
　　　ここでは、"django-sample01"を指定
　　② Public、Privateの選択から、Privateを選択します。
　　※あとはデフォルトのままとする。
　　　Add a README fileにはチェックを入れない。
　　③ Create repositoryボタンを押下します。
## 8-2. 初期設定
　リポジトリが作成された後、…or create a new repository on the command lineに
　以下の初期設定のコマンドが出力されています。
```php
echo "# django-sample01" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/kamedasu/django-sample01.git
git push -u origin main
```
　コピーを行い、ローカルのターミナルで実行します。
　実行は、作業ディレクトリ直下で行います。
　※ VSCode上のターミナルでも上記コマンドの実行は可能です。
　　Ptyhonコンテナにgitがインストールされているためです。
## 8-3. 初期設定の確認
　GitHubのリポジトリを確認すると、README.mdが
　first commitされていることを確認できます。
## 8-4. コンテナへの再接続
　VSCodeの左下の緑のアイコンをクリックし、「Reopen in Container」を選択します。
## 8-5. GitへのPush
　VSCodeより、任意のコミットメッセージを入力し、Commit&Pushを選択します。
　これにより、作業ディレクトリのファイルがGitにPushされます。
![スクリーンショット 2022-11-06 18.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165180/2a54f1fe-b542-5cd5-d968-a2b491b1216f.png)
## 8-6. 最終的なディレクトリ構成の確認
　ローカルのターミナルで以下のコマンドを実行し、作業ディレクトリの内容を確認します。
```php
tree -a .
```
　以下のように表示されます。
```php
.
├── .devcontainer
│   └── devcontainer.json
├── .git
│   ★★★Git配下は割愛する★★★
├── Docker
│   ├── Dockerfile
│   └── docker-compose.yml
├── README.md
└── src
    ├── djangoSampleApp
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-311.pyc
    │   │   ├── settings.cpython-311.pyc
    │   │   ├── urls.cpython-311.pyc
    │   │   └── wsgi.cpython-311.pyc
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py

24 directories, 41 files
```

以上で終了となります。
最後まで読んで頂きありがとうございました。

# 参考
　・[VSCode のリモートコンテナ機能を用いて、あるリポジトリ専用の環境を開発者間で統一する](https://zenn.dev/yuchiki/articles/vscode-remote-container)
　・[【VS Code】Dockerコンテナの環境でリモート開発【Win/Mac】](https://chigusa-web.com/blog/vs-code%e3%81%a7docker%e3%81%aepython%e7%92%b0%e5%a2%83%e3%81%a7%e3%83%aa%e3%83%a2%e3%83%bc%e3%83%88%e9%96%8b%e7%99%ba/)
　・[Visual Studio Code と Docker コンテナを使って開発する](https://tech.pepabo.com/2022/06/10/devcontainer/)
　・[VS Code Remote - Containers を Docker Compose で使うのだー！](https://bufferings.hatenablog.com/entry/2020/06/11/233201)