VSCode Remote Containerが良い

![architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244893/e1abd40b-0cf5-d0fa-c313-53b0bfab6fe6.png)
[Visual Studio Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview)

VSCode Remote Containerは、VSCodeの拡張機能の1つです。
Dockerのコンテナ内でVSCodeを開き、開発することを可能にします。

使ってみてかなり良さげだった&当初はよく分からない部分も多かったので、2週間くらい使ってみて分かったことをまとめます。

##そもそもDockerで開発環境を作るメリット
- 開発環境が簡単に作って壊せる
- 今どういう環境で開発しているのかファイルで確認でき、バージョン管理も容易
- PCにRubyやらRubocopやら各種CLIやらをいれる必要がなくなる
- プロジェクトごとに言語等のバージョンを切り替える必要がなくなる

##VSCode Remote Containerを合わせて使うメリット
- 開発環境をDockerで作っていても、構文チェックや補完が効く
    - ローカルで開発すると、補完をするためにローカルにrubocop等をインストールする必要がある
    - 結局ローカルの環境に強く依存してしまい、Dockerのメリットの一部が享受できなかった問題を解決
- `rails generate ◯◯`、`bin/rspec`などのコマンドを叩く時、いちいち`docker-compose exec < appname> /bin/bash`などを叩く必要がなくなる
- コンテナ内のシェルをカスタマイズして使いやすくできる

##導入方法
- VSCodeで`Dockerfile`や`docker-compose.yml`があるプロジェクトを開く
- 拡張機能(Remote-Containers)をインストール
- VSCodeの画面の一番左下の部分にアイコンが出てくるので、クリック
- `Reopen in Container`をクリック
- `From docker-compose.yml`をクリック
- `web`をクリック
- プロジェクトのルートディレクトリに`.devcontaner/devcontainer.json`と`.devcontaner/docker-compose.yml`が作成される
- もう一度左下のアイコンをクリック
- `Reopen in Container`をクリック
- コンテナ内でVSCodeが開けば成功。初回はビルドがあるので時間がかかります。

##当初の疑問点とその答え
###VSCode Remote Developmentとの違いは？
VSCode Remote Developmentの機能を削り、Dockerコンテナに接続する関連の機能だけを残したのがRemote Container、という理解で合ってるはず。

(202010/26 追記)
以下、コメントにて教えていただきました。
> Remote Development自体はカテゴリ的には拡張機能ではなく、拡張機能パックです。
Remote - WSLと、Remote - Containers、Remote - SSHを1まとまりで入れてくれるいわばセット商品のようなものですね。




###VSCodeの拡張機能は全部使える？
デフォルトでは使えるものと使えないものがあるようです。
`devcontainer.json`に記述することでほぼ何でも使えるようになります。

```..devcontaner/devcontainer.json
"extensions": [
  "rebornix.ruby",
  "kaiwood.endwise",
  "sibiraj-s.vscode-scss-formatter"
]
```

###シェルはローカルと同じように使える？
設定次第で使えます。`.devcontaner/docker-compose.yml`を編集してマウントしましょう。

```..devcontaner/docker-compose.yml
volumes:
  - .:/workspace:cached
  - ~/.bashrc:/root/.bashrc #bashの設定
  - ~/.ssh:/root/.ssh #sshキー
  - ~/.gitconfig:/root/.gitconfig #gitの設定
  - ~/.vimrc:/root/.vimrc #vimの設定
  - ~/.vim/colors/iceberg.vim:/root/.vim/colors/iceberg.vim #vimのカラーテーマ
```

###Railsのサーバーにアクセスできない
```..devcontainer/docker-compose.yml
#command: /bin/sh -c "while sleep 1000; do :; done"
command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0' ; while sleep 1000; do :; done"
```

###どこまでgitで管理する？
VSCode Remote Container用の設定は全て`.devcontainer`以下に保存し、`.devcontainer`ディレクトリを丸ごとgit管理から外します。

コンテナ内で叩きたいコマンドが入っていない場合に限り、Dockerfileを編集する必要があるので、周りの人と相談して決めましょう。

※2020/5/22追記
`.devcontainer`はgitで管理することも普通にあるっぽいです。
東京都のコロナ対策サイトのGitHubで管理されてました。
https://github.com/tokyo-metropolitan-gov/covid19

※2020/12/19追記
コメントより以下の方法を教えていただきました。この方法だと、チームで相談せずに自分の使いたいシェル等が使えそうです。
>devcontainer.json の　postCreateCommand　で初回build後の処理が設定できるので、そこでやると良いと思います。

```.devcontainer/devcontainer.json
"postCreateCommand": "bundle install solargraph readapt; apt-get install -y zsh",
```
###`.devcontainer`をgit管理から外せない
一度コミットしてしまうと、`.gitignore`に記載するだけではgit管理から外すことはできません。以下のコマンドを叩いて解決。

```terminal
$ git rm -r --cached .devcontainer
```

###ローカルで使っていたCLI等が使えない
Dockerfileを編集してインストールしましょう。

```Dockerfile:Dockerfile
# Heroku CLI
RUN curl https://cli-assets.heroku.com/install-ubuntu.sh | sh

# Vim、Zsh
RUN apt-get update -qq && apt-get install -y vim zsh
```

###コンテナ内でPreztoを使いたい
Preztoが好きなので

```Dockerfile:Dockerfile
RUN apt-get update -qq && apt-get install -y zsh #zshをインストール
.
.
RUN chsh -s /bin/zsh #デフォルトのシェルをzshに変更
```
```..devcontainer/docker-compose.yml
volumes:
  - .:/workspace:cached
  #zsh関連の設定ファイルをマウント
  - ~/.zshrc:/root/.zshrc
  - ~/.zlogin:/root/.zlogin
  - ~/.zprofile:/root/.zprofile
  - ~/.zenv:/root/.zenv
  # prezto関連のファイルをマウント
  - ~/.zpreztorc:/root/.zpreztorc
  - ~/.zprezto:/root/.zprezto
```

*2020/12/19追記
以下のコメントをいただきました。
> VS Codeで起動するshellは
設定項目の`Terminal > Integrated > Shell : Linux`という項目があるので、それを`devcontainer.json`に貼り付けると良いです。

```.devcontainer/devcontainer.json
"settings": {
    "terminal.integrated.shell.linux": "/bin/zsh"
},
```
> でもって antigenでもoh-my-zshでもprezto でもdotfileはgitリポジトリで管理して、vs code でpullする設定にすると良いです。
この記事が参考になると思います。
https://banatech.net/blog/view/33

###pryでデバッグしたい
ローカルからアタッチする。

処理をとめたい箇所に`binding.pry`を挿入後

```zsh
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
3bc533887532        sample_web         "/bin/sh -c 'rm -f t…"   2 weeks ago         Up 18 seconds       0.0.0.0:3000->3000/tcp    sample_web_1
$ docker attach sample_web_1
[1] pry(#<HogesController>)> 
```

[docker-compose上のRailsのデバッグを行う - My External Storage](https://budougumi0617.github.io/2017/09/02/debug-rails-on-docker/)

##参考
- [vscode remote container利用時、railsの開発環境にアクセスできない](https://teratail.com/questions/246630)