VS Code Dev Container で Docker credsStore が自動設定されてエラーになる問題とその対処法

VS Code の Dev Container 拡張機能を使っているときに、`docker pull` や `az acr login`、`helm show chart`あるいは KCL などの CLI ツールからレジストリにアクセスしようとすると、以下のような「credentials」関連のエラーに遭遇することがあります。

```
error getting credentials - err: exit status 255, out: ``
```

あるいは、`kcl mod add` や `az acr login` が失敗する、403 エラーが出るなど、認証まわりの問題が起こる場合があります。本記事では、この原因と対処法をまとめます。

> **この記事で言う「ホストマシン」について**  
> Dev Container では、**VS Code を起動しているマシン**を「ホストマシン」として扱っています。  
> Docker Daemon がクラウドやリモートサーバ上にあり、VS Code だけ手元の Mac や PC で動かしているケースでも、ここでは **VS Code 側(ローカル PC) = ホストマシン** と呼ぶのでご注意ください。

## 現象

- **VS Code** のターミナルからコンテナ内で `kcl mod add` や `docker pull` を実行すると成功するのに、**SSH や `docker exec`** でコンテナに入った場合にだけ、`error getting credentials` のエラーが出る。
- **コンテナ内の** `~/.docker/config.json` を覗くと、`credsStore` が `dev-containers-xxxxxx...` のように設定されている。
- この `credsStore` を削除すると一時的にエラーが直るが、VS Code で Dev Container を再接続すると `credsStore` がまた復活する。

## 原因

### Docker Credential Helper と VS Code Dev Containers 拡張の仕組み

VS Code の Dev Container 拡張には、「**Docker Credential Helper**」を自動セットアップする機能があります。  
これは **コンテナ内ではなく、VS Code が起動しているホストマシンの `~/.docker/config.json` と credsStore** を使って、レジストリ認証情報をコンテナに共有しようとする仕組みです。

1. Dev Container を起動するとき、**コンテナ内の** `~/.docker/config.json` に `credsStore` が **指定されていない** 場合、かつ Dev Container の設定がデフォルト (または `dev.containers.dockerCredentialHelper` が有効) になっていると、VS Code Dev Containers 拡張が自動で `credsStore` を挿入します。  
2. すると、**コンテナ内の** `~/.docker/config.json` は、以下のようになります。

```jsonc
{
  "credsStore": "dev-containers-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

3. これにより、コンテナ内で `docker pull` や `az acr login` を実行すると、`docker-credential-dev-containers-xxxxxx` のようなヘルパーを呼び出す挙動になります。  
   - このヘルパーはコンテナ内に生成されたスクリプトで、**VS Code 本体 (Dev Container 拡張) と IPC (プロセス間通信)** を行い、**ホストマシンの** `~/.docker/config.json` に紐づく認証情報を問い合わせます。

### REMOTE_CONTAINERS_IPC 環境変数

この認証がうまくいくカギとなるのが、`REMOTE_CONTAINERS_IPC` という環境変数です。

- **VS Code のターミナル** でコンテナにアタッチした場合は、Dev Container 拡張が自動的に `REMOTE_CONTAINERS_IPC` をセットしてくれるため、`credsStore` を使った認証が成立し、`docker pull` などが成功します。
- ところが、**SSH や `docker exec`** などで VS Code を介さずにコンテナに入った場合は、この環境変数がセットされていないため、`docker-credential-xxx` が IPC 通信に失敗し、「`error getting credentials - err: exit status 255`」などのエラーになります。


## 対処方法

### 1. コンテナ内の `~/.docker/config.json` から `credsStore` を削除する

コンテナ内の `~/.docker/config.json` を開き、下記のように `credsStore` 行を削除すれば、一時的に `docker pull` などは成功します。  
(例)

```bash
# コンテナ内: ~/.docker/config.json
{
  // "credsStore": "dev-containers-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  "auths": { ... }
}
```

しかし、VS Code の設定がデフォルトのままだと、起動のたびに再度 `credsStore` が追記されるため、根本解決にはなりません。


### 2. `dev.containers.dockerCredentialHelper` を無効化する

Dev Container の設定ファイル (`devcontainer.json`) で、VS Code 設定として `dev.containers.dockerCredentialHelper: false` を指定すると、**コンテナ内に Docker Credential Helper を導入しない** ようにできます。

```jsonc
// devcontainer.json の例
{
  "customizations": {
    "vscode": {
      "settings": {
        // この設定を false にする
        "dev.containers.dockerCredentialHelper": false
      }
    }
  }
}
```

これにより、**コンテナ内の** `~/.docker/config.json` に `credsStore` が自動設定されなくなり、IPC エラーも起きなくなります。ただし、その場合は**ホストマシンの** Docker 認証をコンテナに引き継げなくなるため、コンテナ側で `docker login` し直すなどの手間やセキュリティリスクへの考慮が必要です。


### 3. `REMOTE_CONTAINERS_IPC` を SSH/別シェルでも使えるようにする

**VS Code を介さずコンテナに入っても IPC を活かしたい**場合は、VS Code がセットしてくれる `REMOTE_CONTAINERS_IPC` の値を、シェルごとに永続化する方法も考えられます。

たとえば Dev Container の `postAttachCommand` で、下記のように `~/.config/fish/conf.d/` (fish シェル) に環境変数を書き出すなどがあります。

```bash
if [ -n "${REMOTE_CONTAINERS_IPC+x}" ]; then
  # fish シェル用に環境変数をエクスポート
  echo "set -x REMOTE_CONTAINERS_IPC ${REMOTE_CONTAINERS_IPC}" > ~/.config/fish/conf.d/remote-containers-ipc.fish
fi
```

こうすることで、SSH 等で入った際にも `REMOTE_CONTAINERS_IPC` を認識させることができます。  
ただし、`REMOTE_CONTAINERS_IPC` が接続のたびにランダムな値になる場合もあるため、そこは運用ルールが必要です。


### 4. ホストマシンのクレデンシャル情報を整理する

**ホストマシンの** `~/.docker/config.json` およびキー管理 (Keychain Access など) に登録されている認証情報が壊れていると、`docker pull` 時に 403 エラーが出るなどの問題が起きる場合があります。

- macOS の場合は **Keychain Access** にある `ghcr.io` や `quay.io` などの資格情報を一度削除してから、再度 `docker login` しなおす。  
- あるいは `docker login` 後に得られるトークンに、パッケージ読み込み (`packages:read`) など必要な権限が付与されているか確認する。

これらを見直しておくと、**403 エラー**（“権限不足”）のような問題を回避できる可能性が上がります。


## まとめ

- VS Code の Dev Container 拡張には、ホストマシンの Docker 認証をコンテナに引き継ぐ **Docker Credential Helper** が搭載されている。
  - ここでいう「ホストマシン」とは、**Docker Daemon の実行ホストではなく、VS Code が起動しているマシン** のこと。
- この仕組みにより、**コンテナ内の** `~/.docker/config.json` に `credsStore` が自動で設定されるが、  
  **`REMOTE_CONTAINERS_IPC` が存在しない環境下 (SSH 等) で認証失敗**を起こすことがある。
- 対処としては、以下の手段が考えられる。
  1. **コンテナ内の** `~/.docker/config.json` から `credsStore` を削除 (ただし再度挿入される可能性あり)  
  2. `dev.containers.dockerCredentialHelper` を **false** にして Credential Helper 自体を無効化する  
  3. `REMOTE_CONTAINERS_IPC` を自前で外部シェルにも引き継ぐ仕組みを用意する  
  4. **ホストマシンの** Docker クレデンシャルを整理 (Keychain Access などで確認・再ログイン)


## 参考リンク

- [Devcontainer version 0.275 - auto adding ~/.docker/config.json with credsStore specified which cause az acr login to fail · Issue #7982 · microsoft/vscode-remote-release](https://github.com/microsoft/vscode-remote-release/issues/7982)