DockerコンテナをVSCodeで開発 gitでバージョン管理する（忘備録）

# はじめに 🐋
Docker初学者です。Dockerをどのように開発の現場に取り入れられるかを考えました。
不備や誤りなどお気づきのことがあれば、ご指摘いただけると幸いです。

## 概要
コンテナ内部にgitをインストールしVSCodeでリモート接続します。開発、バージョン管理を容易に行えるため実際の開発にDockerコンテナを取り入れやすくなったと思います。

## この記事の読者
プログラミングの基礎的な知識があることが前提です。
Dockerに興味がある方、Dockerは触ったけれど使いどころがピンとこない方などを対象に書いています。
※この記事ではDockerの概要やインストールの方法については詳しく説明しません。

# デモ

## コードテンプレート
[こちら](https://github.com/workshop-msano/sampleTodo)にテンプレートを用意していますので自由にお使いください。本記事の説明はこのテンプレートをもとに行います。

## 使用するツール
私の環境ではUbuntuにDockerをインストールしています。
VSCodeでGithubにSSH接続できることが前提です。

__※検証に協力いただいた方からDockerをVSCodeで使用するにあたり[Rootlessモード](https://docs.docker.com/engine/security/rootless/)が必要だったと報告を頂きました。__ これについて追加情報があればアップデートします


| ツール | バージョン | 備考 | 
|:-----------|:------------|:------------|
| Docker     | 20.10.21    |             |
| docker-compose | 1.29.2  |             |
| Dev Containers | 0.266.1 | VSCode 拡張機能     |


## フォルダ構成 

```
root/
  ├ .devcontainer/
  │  └ devcontainer.json
  ├ templates/
  │  └ index.html
  ├ .dockerignore
  ├ Dockerfile　
  ├ docker-compose.yml
  ├ .gitignore
  ├ app.py
  └ requirements.txt
```

## コードの説明
アプリはPythonを使い Todoリストを作成しました。アプリの詳細は[こちら](https://github.com/workshop-msano/sampleTodo)にテンプレートを用意しています。本記事では Docker の設定を中心に説明します。

### Dockerfile
Dockerイメージを作成するための設定を記載します。
```Docker:Dockerfile
FROM python:3.10 // PythonのイメージをDockerhubからプル

COPY ./requirements.txt /app/requirements.txt // Pythonの依存関係やパッケージ情報をイメージにコピー

WORKDIR /app //作業ディレクトリを イメージ先の/appに切り替える

RUN pip install -r requirements.txt　// 依存関係やパッケージをイメージ内でダウンロード

COPY . /app　//ローカルのファイルやフォルダをイメージ内にコピー

ENTRYPOINT [ "python" ] // コンテナを起動する際のコマンドを設定

CMD ["app.py" ]
```

### docker-compose.yml
Dockerコンテナ起動するための設定を記載します。
```docker:docker-compose.yml
version: '3.10' // docker-compose.ymlのバージョン
services:
  db:
    image: postgres:14.1-alpine // データベースイメージをDockerhubからプル
    container_name: sampletodo_db
    restart: always
    environment:　//データベース起動に必要な環境情報
          - POSTGRES_USER=postgres　
          - POSTGRES_PASSWORD=postgres
    volumes: 
      - db:/var/lib/postgresql/data //データベース内容のマウント先を指定
    networks:
      mynet:
        aliases:
          - db
      healthcheck: 
        test: ["CMD-SHELL", "pg_isready -U postgres"]
        interval: 1s
        retries: 3
  web:
    container_name: sampletodo_web
    build: .  
    depends_on:
      db: 
        condition: service_healthy # dbのコンテナが起動完了してからwebコンテナを起動させる為の設定 
    ports:
      - '127.0.0.1:8000:8080'
    environment:
      POSTGRES_URL: postgresql://postgres:postgres@db:5432/postgres
    volumes:
      - './:/src'
    networks:
      mynet:

volumes: 
  db: 
    driver: local

networks: // networksを使い 'db'と'web'という2つのコンテナを接続させる
  mynet:　//任意の名前
    driver: bridge
```

### .devcontainer/devcontainer.json
VSCodeの拡張機能、Remote Developmentを起動するための設定を記載します。
```json:.devcontainer/devcontainer.json
{
    "name": "sampletodo remote",
    "dockerComposeFile" : ["../docker-compose.yml"], 
    "service": "web",
    "extensions": ["oderwat.indent-rainbow"],  
    "workspaceFolder": "/app",
    "postCreateCommand": "apt update && apt install -y git" 

}
```

## テンプレートのクローンから開発環境を整えるまでの流れ

※[各ツール](https://qiita.com/drafts#%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%83%84%E3%83%BC%E3%83%AB)のインストールは完了しています
1. Githubリポジトリから[SampleTodo](https://github.com/workshop-msano/sampleTodo) をクローンします。
    ```
    git clone git@github.com:workshop-msano/sampleTodo.git
    ```

2. ファイルをVSCodeで開きます。VSCodeの左下にある Remote Container起動ボタンを押下します。
    <img src="https://i.ibb.co/wKywrNk/2022-12-10-104132.png" alt="2022-12-10-104132" border="0">

3. VSCodeのポップアップ画面から `Open Folder in Container`を選択します。
    <img src="https://i.ibb.co/1MLJ6kV/2022-12-10-104902.png" alt="2022-12-10-104902" border="0" width=600>

4. ポップアップ画面の`Open`を押下します。
    <img src="https://i.ibb.co/f0Z6XQf/2022-12-10-105428.png" alt="2022-12-10-105428" border="0">

5. しばらく待つと VSCodeが表示されます。ログに`Done. Press any key to close the terminal.`と表示されていれば成功です！<br>
左下の Remote Developmentボタンの隣に `Dev Container: <devcontainer.jsonで設定した名前>`と表示されます。　
    <img src="https://i.ibb.co/GWQ4zcq/2022-12-10-105935.png" alt="2022-12-10-105935" border="0">
    `http://localhost:8000`からウェブアプリにアクセス可能です。
    <img src="https://i.ibb.co/zFG6TTS/2022-12-10-214935.jpg" alt="2022-12-10-214935" border="0" width=400>

6. すでにコンテナにはgitをインストールしているので、コンテナからGithubにアクセスできるように設定します。※VSCodeでGithubにSSH接続できることが前提です。
    ターミナルを開き、以下のコマンドを実行します。
    ```
    git config --global user.email '<your setting>'
    git config --global user.name '<Your setting>'
    
    mkdir -p ~/.ssh/
    curl -s -o ~/.ssh/id_ed25519 "https://github.com/$(git config --global --get user.name).keys"
    ```
7. 次にターミナルで `ssh -v git@github.com`と入力しましょう。
    ログの中に Githubアクセス成功の表示があれば完了です！Githubにリポジトリを作成し、Dockerコンテナ内からソースコードのバージョン管理をおこなうことが出来ます。

## ボーナス
Dockerコンテナのデータベースにシェルスクリプトを使ってアクセスしてみましょう。
以下のコマンドをコンテナの外で実行します。

```
docker exec -it sampletodo_db /bin/sh
```
```
psql --username postgres
```

#### お疲れさまでした！🎉🎉🎉

# 終わりに
Dockerコンテナを使うことで依存関係やパッケージのインストール、データベースの構築を含め環境構築をとてもに楽に行えます。VSCodeというなじみのあるコードエディタを使えてgitでバージョン管理できるため実用的だと思います。私なりにDockerの利便性を学ぶことが出来ました。


最後まで読んでいただき、ありがとうございました。お気づきのことがあればコメント頂けますと幸いです。

今回の投稿に際し、検証に協力頂いた友人とパートナーに感謝いたします。


## 引用
[docker-compose.ymlの書き方について解説してみた](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)
[DockerCompose を用いて起動順序を制御する](https://zenn.dev/togana/articles/12c18869a4eb29)
[Dockerコンテナの環境でリモート開発](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/)
[DockerをRootlessモードで利用する](https://zenn.dev/nemolize/articles/3cec197e5f5ec8)