【メモ】Python/Poetry+Jupyter+VScode+Docker+SSHで開発環境を構築

# はじめに
この記事では、プログラミング初心者が初めてDocker環境を構築したときの記録を残したものになります。

Dockerをできるようになるには、自分で１から作るのが一番勉強になると思うので、他の方の記事やgithubを参考にしながら、Docker環境を作りました。

具体的には、SSHで共用のワークステーションに接続し、その先でVSCodeを開き、Dockerで作業ができる環境構築を紹介します。言語は、python使用を想定します。juliaとか他言語でも同様にできると思います。

## 環境
MacBookPro M1

## 注意
- 間違いなどありましたら、執筆者の責任です。もしありましたら、指摘していただけると幸いです。

- DockerやPoetryそのものの説明は省きますので、他の記事を参考にしていただければと思います。


# 設定の仕方
以下のstep1からstep5で構成される。

## Step1. Poetryでプロジェクトを作成
[こちらの記事](https://qiita.com/ksato9700/items/b893cf1db83605898d8a)を参考にして、Poetryでプロジェクトを新しく作る。


```
poetry new <project-name>
```


```
$ tree .
.
├── README.rst
├── pyproject.toml
├── qiita_project
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_qiita_project.py

2 directories, 5 files
```

上記の典型的なディレクトリを自動で作ってくれる。

このプロジェクト専用の仮想環境を立ち上げる。

```
poetry install
```

現在のプロジェクトがインストールされた（パソコンがこのプロジェクトを認識したという理解です。）。デフォルトでpytestなどが入っている。pytestを試しに実行してみる。実行する場合は、

```console
poetry run pytest
```

新しいパッケージを入れる場合は、

```
poetry add hogehoge
```

試しに、jupyterlabを入れてみましょう。

```
poetry add jupyterlab
```

パッケージを消したい場合は、


```
poetry remove hogehoge
```



## Step2. Docker環境を作る。

Dockerfileとdocker-compose.ymlを以下のように作成します。

- DockerfileはDocker imageを作る元です。作成されたimageはローカルの何処かに保存されます。(Dockerfileがpythonでいうクラスみたいな感じ)

- docker-compose.ymlには、コンテナを立ち上げる命令が書かれています。ここでは、コンテナの中で、jupyterlab or shell　を使える環境を整えるための命令が書かれています。

さて、READMEなどがあるのと同じ階層にDockerfileを追加してください。


Dockerfileには以下を記入


```docker
FROM python:3.9-slim

ENV PYTHONUNBUFFERED=1

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y \
    build-essential \
    curl \
    ca-certificates \
    git \
    zip \
    vim \
    && \
    apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* # clean up

WORKDIR /app

COPY pyproject.toml ./

RUN pip install poetry

RUN poetry config virtualenvs.create false \
    && poetry install
```

docker-compose.yml　もDockerfileと同じ階層に以下を記入


```yml
version: '3'
services:
  lab:
    build: ./
    container_name: qiita_project_lab
    user: root
    volumes:
      - ./:/app
    working_dir: /workspaces/qiita_project
    ports:
      - "8882:8882"
    command: jupyter lab --ip=0.0.0.0 --allow-root --NotebookApp.token='' --port=8882

  shell:
    build: ./
    container_name: qiita_project_shell
    volumes:
      - ./:/workspaces/qiita_project
    working_dir: /workspaces/qiita_project
    command: /bin/bash


```


まずDockerfileからDocker imageを作るためにビルドします。

```
docker compose build
```

作成したimageからコンテナを構築し、コンテナの中に入ってみます。

```
docker compose up run shell
```

このときに何かインストールしたいパッケージを環境に加えることができます。例えば、numpyをインストールしたいときは、続けてコンテナの中で

```
poetry add numpy
```

コンテナから出るときは、

```
exit
```

## Step3. VSCode上でDockerを使う

Dockerfileがあるディレクトリでdevcontainerというディレクトリを作成し、その下に、devecontainer.jsonというファイルを作り、以下を記述します。



```json
{
    "name": "Existing Dockerfile",
    // Sets the run context to one level up instead of the .devcontainer folder.
    "context": "..",
    // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
    "dockerFile": "../Dockerfile",
    // The optional 'runArgs' property can be used to specify additional runtime arguments.
    "runArgs": [],
    // Use 'settings' to set *default* container specific settings.json values on container create.
    // You can edit these settings after create using File > Preferences > Settings > Remote.
    // Uncomment the next line if you want to publish any ports.
    // "appPort": [],
    // Uncomment the next line to run commands after the container is created - for example installing git.
    // "postCreateCommand": "apt-get update && apt-get install -y git",
    // Add the IDs of extensions you want installed when the container is created in the array below.
    "extensions": [
        "ms-azuretools.vscode-docker",
        "julialang.language-julia",
        "colinfang.markdown-julia",
        "mutantdino.resourcemonitor",
        "shardulm94.trailing-spaces",
        "cliffordfajardo.hightlight-selections-vscode",
        "wdawson.better-kill-ring",
        "oderwat.indent-rainbow",
        "github.vscode-pull-request-github",
        "mhutchie.git-graph",
        "donjayamanne.githistory",
        "eamodio.gitlens",
        "bungcip.better-toml",
        "usernamehw.errorlens",
        "ms-vscode.live-server",
        "christian-kohler.path-intellisense",
        "ms-python.python",
    ]
}

```

作成は、こちらを参考にしました。

https://github.com/terasakisatoshi/jldev_poetry

https://code.visualstudio.com/docs/remote/devcontainerjson-reference

https://github.com/microsoft/vscode-dev-containers/tree/main/containers/docker-existing-dockerfile



続けて、VSCodeのExtenstionsのRemote Containerをインストールし、VSCodeを開いてください。すると、コンテナを開きますかと聞かれるのでYESと答えてください。

すると、コンテナの中に入った状態でVSCodeが使える状態になっていると思います。
この中で作成されたファイルなどはコンテナから出ても消えない（ローカルのプロジェクトがあるディレクトリとコンテナが通信してローカルのディレクトリに保存されている）ので安心して開発を進めることができます。

## Step4. Github

ここまでで作成したローカルディレクトリをGithubに登録して、リモートレポジトリーとしてクラウド上にも上げておきます。Githubに上げておくと、過去の履歴が辿れるので便利です。例えば、間違って重要なファイルを消してしまった場合でも、過去の履歴を辿ってファイルを元通りにすることが可能になります。

(Githubを使ったことがない人は、ssh鍵を作成するところからスタートしてください。参考：[お前らのSSH Keysの作り方は間違っている](https://qiita.com/suthio/items/2760e4cff0e185fe2db9))

鍵を作成したら、メールアドレスとユーザー名を登録します。

```
git config --global user.name <username>

git config --global user.email <emailaddress>
```

先ほど作ったレポジトリーと同じ階層のところで、


```
git init
```

git add/commitをします。

```
git add file
git commit -m "ここは適当な名前"
```

次に、githubでレポジトリを作成します。このレポジトリーの名前とURLを用いて、


```
git remote add <RemoteRipositoryName> <RemoteRipositoryURL>
```

(<>いらないです)

```
git push --set-upstream <RemoteRipositoryName> master
```

これでgithubにリモートレポジトリを作成できました。これで最低限の開発環境は整ったことになるかとと思います。


## Step5. SSHでワークステーションの中でDockerを開発をする

最後に、研究室などで、共用のワークステーションの中で作業や開発を進める人も多いでしょう。Dockerを使わない通常のSSH接続はできると仮定して話を進めます。

SSH先のワークステーションで先ほど作ったレポジトリをクローンしてきます。

VSCodeを使って、SSHでワークステーション先でクローンしてきたレポジトリを開くと、コンテナの中で開きますかと聞かれるのでYESと答えます。

### コンテナが開けない場合

共用のワークステーションを使っている場合、既に誰かが`/tmp/.vsch-#########.`を使っているからかもしれません。その場合はWSの.bashrcに

```
mkdir -p /tmp/$USER
export TMPDIR=/tmp/$USER
```
を記入すれば一時的なディレクトリを作られて問題が回避できるみたいです。

詳細はこちらを参考：
https://github.com/microsoft/vscode-remote-release/issues/2347




# まとめ
Dockerを使った開発環境を整えました。みなさんの快適な環境づくりにお役に立てれば幸いです。


# 参考にしたもの
- Poetry関連

https://qiita.com/termoshtt/items/64a01541145167a5a9cc

https://qiita.com/ksato9700/items/b893cf1db83605898d8a



- Docker関連

https://github.com/terasakisatoshi/jldev_poetry

https://github.com/terasakisatoshi/MyWorkflow.jl