Porable Docker環境でCode-Serverを使う

## とりあえずdocker-compose.yml

```yaml
version: "2.1"
services:
  coder:
    image: codercom/code-server
    container_name: Code-Server
    user: 0:0
    volumes:
      - /root/project:/root/project
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - 8000:8000
    entrypoint: "code-server --auth none --user-data-dir /root/project --bind-addr 0.0.0.0:8000"
    restart: unless-stopped
```
## まともに使えるようにする

code-serverはなぜか[この環境](https://qiita.com/riafeed/items/c7729dc84191e93f0f3d)では結構な頻度でエラーダイアログが出てコネクションが切断され動かなくなるのでまったく使い物にならない。

どうもPC環境が遅くて処理が追い付かないなどの理由(?)で拡張機能ホスト(?)とのhandshakeに10秒以上かかるとタイムアウトで切断する模様…

しかもハードコーディングされているのでタイムアウト時間を伸ばそう思ったら直接スクリプト(Minify済み)を修正するしかないようだ(えぇ…)

2020年10月時点の最新版3.6.1の場合は

```sh
docker exec -it Code-Server bash
```

でコンテナに入り、

```sh
vi /usr/lib/code-server/lib/vscode/out/vs/workbench/workbench.web.api.js
```

でworkbench.web.api.jsをエディタ(上記の場合はvi)で開いてhandshakeで検索(viの場合は/を押して検索ワードを入力)すると1番目に以下のような部分がヒットするはずなので

```workbench.web.api.js:
//こんな感じの部分(実際は周囲に未整形のコードがずらっと表示されている)
return new Promise((i,l)=>{const c=setTimeout(()=>{const t=new Error("handshake timeout");t.code="ETIMEDOUT",t.syscall="connect",e.logService.error(`${o} the handshake took longer than 10 seconds. Error:`),e.logService.error(t),a&&D(r),l(t)},1e4)

//上記を整形したもの
return new Promise((i,l)=>{
    const c = setTimeout(()=>{
        const t = new Error("handshake timeout");
        t.code = "ETIMEDOUT",
        t.syscall = "connect",
        e.logService.error(`${o} the handshake took longer than 10 seconds. Error:`),
        e.logService.error(t),
        a && D(r),
        l(t)
    }
, 1e4) //←この1e4を書き換える
```

目を凝らしてその付近から頑張って1e4(10000ミリ秒=10秒)となっている部分を探して1e5(1分40秒)や1e6(16分40秒)や1e7(2時間46分40秒)や1e8(27時間46分40秒)あたりに書き換えることでタイムアウト時間を延ばせる。

詳しくは不明だが(おそらくターミナル関係?)、12e4(2分)のタイムアウトがありたまにこのタイムアウトで切断されるので12e4で検索して12e5(20分)や12e6(3時間20分)や12e7(33時間20分)あたりに延ばす。

自分はこれでエラーで切断されることが基本的にはなくなったがエラーになるときはなるようなので頻発するならもうちょっと検証したい。

## タイムゾーン

codercom/code-serverイメージのベースは(多分)Debianの模様。そのままだとタイムゾーンがUTCになっているのでJSTに直すには以下のようにする。

参考:[Debian9のタイムゾーン設定に関するメモ](https://qiita.com/pioka/items/e6a7a2ecdf356675d49d)

```shell
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

## 別のコンテナの開発環境でアプリを開発したい場合

code-serverではvs-codeのremote系拡張機能は無理やりインストールしようと思えばできるが結局動作しない模様。

code-serverのコンテナと開発環境が入っているコンテナでホストのフォルダをそれぞれバインドマウントすることでcode-serverで編集したコードが開発環境コンテナ側でも反映されるようにした上でコマンドはssh経由で実行する(要sshdインストール)。

sshdを立てるのが面倒なら、```/var/run/docker.sock```をバインドマウントしたうえでdockerをインストールして開発環境コンテナのシェルを起動して実行という手も。

code-serverにdockerをインストールしておいて。

```sh
apt update && apt install -y docker docker-compose
```

下のような感じのnodeコンテナを作っていたとしたら(code-server、nodeどちらのコンテナのもホストの/root/projectディレクトリをバインドマウントしている)

```yml
version: "2.1"
services:
  coder:
    image: node:current
    container_name: node
    user: 0:0
    volumes:
      - /root/project:/root/project
    ports:
      - 8080:8080
    tty: true
    stdin_open: true
    restart: always
```

下のコマンドでnodeコンテナのシェルを実行できる。

```sh
docker exec -it node bash
```



## node.jsインストール

ぶっちゃけcode-serverコンテナに開発環境までインストールしたらせっかくdocker環境で動かしているのにもったいないが、ほかのコンテナで使う予定はないのでどうしても1つのコンテナに収めたい場合はaptでインストールできる。これ動かしたら猛烈に時間がかかるので注意。

```sh
apt update && apt install -y npm && npm install -g n && n stable && apt remove -y --autoremove npm
```

Dockerfileに書くならこれも必要。

```sh
ENV DEBIAN_FRONTEND=noninteractive
```