yNagaokaのブログ

このブログはNGS解析者が環境整備をするにあたりつまずいた部分と解決方法をまとめた覚書のようなものです。

VSCodeで「ウィンドウを読み込めませんでした」が頻発する原因を調べた時の覚書-アップデート版

はじめに

この記事は以下の記事のアップデート版です。 ynagaoka.hatenablog.com

最近(2026年5月頃から?)、VSCodeをスリープから復帰させると、

「拡張機能がディスク上で変更されています。ウィンドウを再読み込みしてください。」や、「ウィンドウを読み込めませんでした」が頻発し、再起動を余儀なくされていました。 さすがに不便だったので原因の調査を行った(GitHub CopilotとCodexが)ので、その時の覚書を残しておきます。 基本的に自分が忘れないために書き残していますが、誰かの役に立てば幸いです。

その後も同じ環境を使いながらログを追っていたところ、最初に記事を書いた時点では分かっていなかった原因や設定箇所もいくつか見つかりました。 特にVSCode + Remote-WSLでは、

  • Windows側のUser settings
  • WSL側のRemote User settings
  • Remote-WSL Server側のMachine settings
  • Workspace settings
  • VSCode起動時のargv.json

など設定ファイルが複数存在します。

今回の問題では、「どの設定を書くか」だけでなく「その設定をどのファイルに書くか」もかなり重要でした。

そのため、当初の記事の内容にその後分かった内容を加えて更新しています。

以下の記事と重複することも書いてます。 ynagaoka.hatenablog.com


原因の調査

まず、自分の環境にはPythonやR関係、Remote - SSH、Dev Containers、Docker、GitHub Copilot、Codexなど様々な拡張機能がインストールされています。

直近ではCodexを導入し、その頃から頻発するようになったので、

「原因はこいつか?」

と睨んで思い切ってアンインストールしました。

がしかし、事態は変わらず。

自力では無理か……と思いGitHub Copilotに原因の精査と対応をお願いしました。

調査したところ、単一の原因というより、

  • 拡張機能の再配置・削除
  • 設定の保存場所の不整合
  • Extension Host起動時の拡張機能エラー

などが重なっていたようです。

具体的には以下です。

1. VSCode Serverによる拡張機能の更新・削除

VSCode Serverが再接続時に拡張機能を自動更新、または古いバージョンを削除しており、その結果として拡張ディレクトリの中身が変化していました。

ログでは例えば、

ms-ceintl.vscode-language-pack-ja
openai.chatgpt

などの古いバージョンが削除されていました。

これが、

拡張機能がディスク上で変更されています。
ウィンドウを再読み込みしてください。

という通知の直接的な引き金の一つになっていたようです。

つまり、「拡張機能が完全に壊れていた」というより、

VSCodeが再接続時に拡張機能を入れ替え、その変更を検知していた

という状態です。


2. Workspace settingsに置くべきでない設定が入っていた

もう一つ問題だったのが設定ファイルです。

対象プロジェクトの、

<project>/.vscode/settings.json

に、

"extensions.autoCheckUpdates": false,
"extensions.autoUpdate": "off"

が入っていました。

Remote-WSLで例えば、

/home/<username>/work

をWorkspaceとして使用している場合、

/home/<username>/work/.vscode/settings.json

に相当します。

しかし、拡張機能全体に関係する設定をWorkspace settings側に置くことで、VSCodeが設定を書き込もうとした際にエラーが発生していました。

さらにPython Environments側でも、

python-envs.terminal.autoActivationType

をWorkspace設定へ書き込もうとして失敗していました。

つまり、

拡張機能の更新処理と設定書き込み失敗が同時に発生し、復帰時にエラーや通知が連続していた

という状態でした。


3. Extension Host起動時にも複数のエラーが出ていた

さらにExtension Host起動直後には、

Roo Code:
PendingMigrationError: navigator is now a global in nodejs

openai.chatgpt:
PendingMigrationError: navigator is now a global in nodejs

GitHub.copilot-chat:
No bundle location found for extension GitHub.copilot-chat

なども記録されていました。

このあたりもExtension Hostの再初期化時の不安定化要因になっていたと考えられます。


実施した対応

原因が見えてきたので修正を行いました。

ここで重要だったのが、

VSCode + Remote-WSLではsettings.jsonが一つではない

という点です。

今回使用した主な設定場所は以下です。

種類 設定ファイル
Windows User settings C:\Users\<username>\AppData\Roaming\Code\User\settings.json
WSL Remote User settings /home/<username>/.vscode-server/data/User/settings.json
WSL Machine settings /home/<username>/.vscode-server/data/Machine/settings.json
Workspace settings <project>/.vscode/settings.json
VSCode起動設定 C:\Users\<username>\AppData\Roaming\Code\argv.json

以下、それぞれ何を変更したか記載します。


1. Workspace settings

まず対象プロジェクトの、

<project>/.vscode/settings.json

です。

例えばWorkspaceが、

/home/<username>/work

であれば、

/home/<username>/work/.vscode/settings.json

になります。

ここから、

"extensions.autoCheckUpdates": false,
"extensions.autoUpdate": "off"

を削除しました。

Workspace settingsには、基本的にそのプロジェクトだけに必要な設定を残します。

今回の環境では最終的に、

{
    "r.lsp.promptToInstall": false,
    "python.terminal.activateEnvironment": false
}

のようなプロジェクト固有の設定のみを残しました。

つまり、

VSCode全体や拡張機能全体の挙動を変更する設定を、何でも.vscode/settings.jsonへ書かない

ということです。


2. Windows側のUser settings

Windows上で動いているVSCode本体のUser settingsは、

C:\Users\<username>\AppData\Roaming\Code\User\settings.json

です。

環境変数を使えば、

%APPDATA%\Code\User\settings.json

です。

拡張機能の自動更新については、こちらに設定しました。

VSCode 1.129.1を使用している現在の環境では、

{
    "extensions.autoCheckUpdates": false,
    "extensions.autoUpdate": "off"
}

としています。

これによって、VSCode起動・Remote再接続時に拡張機能が勝手に入れ替わる頻度を抑えています。

CodexをRemote-WSL側で使用しているため、現在の環境ではさらに、

"chatgpt.composerEnterBehavior": "cmdAlways",
"chatgpt.runCodexInWindowsSubsystemForLinux": true,
"remote.extensionKind": {
    "openai.chatgpt": [
        "workspace"
    ]
}

も設定しています。

ただし、これらは今回の「ウィンドウを読み込めませんでした」問題に対して誰でも必要な設定というわけではありません。

Remote-WSL + Codexを使用している今回の環境固有の設定です。

特に、

remote.extensionKind

は拡張機能をLocal側またはRemote側のどちらのExtension Hostで実行するかに関係するため、必要がなければ無理に設定しない方がよいと思います。


3. WSL側のRemote User settings

Remote-WSLでVSCodeを使用すると、WSL側にもRemote専用のUser settingsがあります。

場所は、

/home/<username>/.vscode-server/data/User/settings.json

です。

今回、Python Environmentsが、

python-envs.terminal.autoActivationType

をWorkspace settingsへ書き込もうとして失敗していました。

そこで、

/home/<username>/.vscode-server/data/User/settings.json

側に、

{
    "python-envs.terminal.autoActivationType": "off"
}

を設定しました。

つまり、

<project>/.vscode/settings.json

ではなく、

/home/<username>/.vscode-server/data/User/settings.json

に設定しています。

今回のトラブルでは、この

Workspace settingsとRemote User settingsの区別

がかなり重要でした。


4. Remote-WSL Server側のMachine settings

その後もOpenAI/Codex拡張で、

PendingMigrationError: navigator is now a global in nodejs

が発生したため、さらに調査しました。

extensions.supportNodeGlobalNavigator=true自体はUser settingsに入っていたのですが、実際に起動しているRemote Extension Hostには設定が反映されておらず、起動引数に

--supportGlobalNavigator

が付いていませんでした。

そこで、Remote-WSL ServerのMachine settingsとして、

/home/<username>/.vscode-server/data/Machine/settings.json

を作成しました。

内容は、

{
    "extensions.supportNodeGlobalNavigator": true
}

です。

今回の環境ではmicromambaも使用しているため、実際のファイルには、

{
    "extensions.supportNodeGlobalNavigator": true,
    "python.condaPath": "/home/<username>/.local/bin/micromamba"
}

と記載しています。

ただし、

"python.condaPath": "/home/<username>/.local/bin/micromamba"

は今回のVSCode読み込み問題とは直接関係なく、Python環境固有の設定です。

設定後にRemote Extension Hostを再生成し、Linux側で実際のプロセスを確認したところ、

--supportGlobalNavigator

が起動引数に追加されていることを確認できました。

その後のログでは、OpenAI拡張で発生していたPendingMigrationErrorは再発していません。


5. Windows側のargv.json

スリープ復帰時にはElectron rendererやGPU周辺の問題も疑ったため、補助的な対策として、

C:\Users\<username>\AppData\Roaming\Code\argv.json

も作成しました。

内容は、

{
    "disable-hardware-acceleration": true
}

です。

これはVSCodeのハードウェアアクセラレーションを無効化する設定です。

ただし、ログから、

ハードウェアアクセラレーションが今回の直接原因だったと断定できたわけではありません。

あくまでスリープ復帰時のElectron renderer / GPU周辺を疑って追加した補助的な対策です。

そのため、この設定は全員に必要なものではないと思います。

また、argv.jsonはVSCode起動時に反映されるので、変更した場合はVSCodeを完全終了してから再起動する必要があります。


VSCode Server側に残っていた拡張機能も整理

設定ファイル以外に、Windows側とWSL側の拡張機能ディレクトリも確認しました。

WSL側では、

/home/<username>/.vscode-server/extensions/

Windows側では、

C:\Users\<username>\.vscode\extensions\

です。

調査時には、

  • Roo Code
  • OpenAI / Codex
  • Python Environments
  • Jupyter

などについて、旧バージョンや一時的に展開されたと思われるディレクトリが残っていました。

最初の調査では例えば、

rooveterinaryinc.roo-cline-3.54.0
openai.chatgpt-26.623.70822-linux-x64
ms-python.vscode-python-envs-1.36.0-linux-x64

などについて重複や退避用ディレクトリを整理しました。

後日の調査ではWindows側のJupyter拡張が複数バージョン登録されていたり、Windows / WSL双方に.uuid形式のstaging directoryが残っていることも確認できました。

ただし、ここは注意が必要です。

拡張機能ディレクトリに複数のフォルダがあるからといって、いきなり全部削除するのはおすすめしません。

今回は、

  1. extensions.jsonに登録されている拡張機能を確認
  2. 実際のextension directoryと比較
  3. 古いバージョンや未登録directoryを確認
  4. いきなり削除せずバックアップへ退避
  5. VSCodeを完全再起動
  6. 問題なく起動することを確認

という順番で整理しました。


なぜこの対策が効くのか

今回の対策を整理すると、

Workspace settingsから不適切な設定を外す

Workspace設定からVSCode全体に関係する設定を外すことで、設定の書き込みエラーを減らすことができます。

User settingsへ設定を集約する

User settings側に置くべき設定をUser settingsへ集約することで、

WorkspaceではA
RemoteではB
WindowsではC

という設定の矛盾を減らせます。

拡張機能の自動的な入れ替えを抑える

拡張機能の自動更新・自動削除がRemote再接続時に走ると、extension directoryの内容が変更されます。

そのため、

拡張機能がディスク上で変更されています

という通知につながる可能性があります。

自動更新の影響を抑え、古い拡張機能の残骸を整理することで、この状態を起こりにくくしました。

LocalとRemoteのExtension Hostを区別する

Remote-WSLでは、

Windows側で動いているVSCode

と、

WSL側で動いているVSCode Server

があります。

さらに拡張機能によって、Local Extension Hostで動くものとRemote Extension Hostで動くものがあります。

今回のCodexのように、

設定自体は存在しているのに、実際に動いているRemote Extension Hostには反映されていない

ということもありました。

そのため設定ファイルを見るだけではなく、「実際にどのExtension Hostで拡張機能が動いているのか」まで確認する必要がありました。


settings.jsonを修正しても残っていたPython interpreter

さらに後日の検証で、少し別の問題も見つかりました。

以前使用していたPython interpreterを削除した後も、VSCodeがそのパスを参照し続けていました。

例として、

/home/<username>/<old-environment>/bin/python

のような、すでに存在しないPython環境です。

調べてみると、この情報はsettings.jsonではなく、VSCode内部のstate DBに保存されていました。

Python拡張の状態として、

wsl_WORKSPACE_FOLDER_INTERPRETER_PATH_/home/<username>/work

のようなキーに古いinterpreter情報が残っていました。 つまり、settings.jsonを全部確認しても見つからない設定がVSCode内部に残っている場合があります。

最終的には、

  1. VSCodeを完全終了
  2. state DBをバックアップ
  3. 該当するPython interpreterのstateのみ削除
  4. SQLiteのPRAGMA integrity_checkを実行
  5. VSCodeを再起動
  6. 古いinterpreterが再度参照されないことを確認

という処理を行いました。

ここで重要だったのが、Windows側のVSCode本体を完全終了することでした。 Remote Extension Hostだけを終了した状態では、Windows側VSCodeがメモリ上に持っていた古い情報が再度書き戻されることがありました。 ただし、state.vscdbはVSCode内部状態を保存しているSQLite DBなので、通常は直接触らない方がよいと思います。

「settings.jsonに何も残っていないのに古い設定が復活する」

ような場合に、こういう保存場所もあるという程度に覚えておくのがよいと思います。


今回の対応のデメリット

今回の対応にもデメリットがあります。

拡張機能の自動更新をOFFにする

extensions.autoCheckUpdates
extensions.autoUpdate

をOFFにすると、拡張機能の新しいバージョンや修正版が出ても自動では反映されにくくなります。

セキュリティ修正や不具合修正への追従も遅くなるので、定期的に手動で更新を確認する必要があります。

自分の場合は、勝手に更新されてVSCodeが不安定になる方が困るので、

必要な拡張機能だけ定期的に手動更新する

という運用にしています。

Python EnvironmentsのautoActivationをOFFにする

python-envs.terminal.autoActivationType

をOFFにすると、ターミナルを作成した際のPython環境の自動有効化が止まります。

そのため必要に応じて、

source .venv/bin/activate

や、

micromamba activate <environment>

などを手動で実行する必要があります。

このあたりは利便性とのトレードオフですね。


その後の再検証

最初にこの記事を書いた時点では、「とりあえず症状が消えた」というところまでの確認でした。 その後もログを確認しながら修正を続け、Windows側のVSCodeを完全終了して再起動した状態でも改めて検証しました。

最終的にはRemote Extension Hostが、

--supportGlobalNavigator

付きで起動していることを確認できました。

また、以前発生していた、

PendingMigrationError

やWindows / WSL間のパス混在に関連したエラーも再発していません。

OpenAI / Codex拡張についても、

activation
app-server起動
画面のmount

まで正常に完了しています。

Pythonについても、削除済みinterpreterの参照は再発せず、

/home/<username>/work/.venv/bin/python
/usr/bin/python3
/home/<username>/work/micromamba/envs/<environment>

などの環境を正常に検出できています。


まだ残っている問題

最初の記事では、

openai.chatgpt:
PendingMigrationError

も残存問題としていました。

しかし、その後Remote-WSL側のMachine settingsを修正し、Remote Extension Hostに、

--supportGlobalNavigator

が実際に付いていることを確認した後は、このエラーは再発していません。

一方でGitHub Copilotについては現在も、

No bundle location found for extension GitHub.copilot-chat

chatParticipant must be declared in package.json: claude-code

TypeError: e is not iterable

などのログが残っています。

ただし、これらのエラーが出た後も、

  • GitHub token取得
  • Copilot contributionのactivation
  • context keyの設定

などには成功しています。

そのため現時点では、今回の「ウィンドウを読み込めませんでした」の直接原因とは別問題として考えています。 拡張機能側やVSCode側の更新によって今後解決する可能性があるため、現時点では無理に内部ファイルを変更することはしていません。


今回分かったこと

今回一番勉強になったのは、VSCode + Remote-WSLでは、settings.jsonを直せば終わりではないということです。 少なくとも今回の環境では、

Windows User settings
WSL Remote User settings
Remote Machine settings
Workspace settings
argv.json
extension directory
VSCode内部のstate DB

という複数の設定・状態保存先が関係していました。

特にRemote-WSLの場合、

Windows側のVSCode
        ↓
Remote-WSL
        ↓
WSL側のVSCode Server
        ↓
Extension Host
        ↓
各Extension

という構成になるため、

「その設定をどこに書いたか」だけでなく、「その設定を実際にどのExtension Hostへ反映させたいのか」まで考える必要があります。

今回のような症状が発生した場合は、Workspaceの、

.vscode/settings.json

だけを確認するのではなく、

Windows User settings
Remote User settings
Machine settings

が矛盾していないか確認してみるとよいと思います。


おわりに

当初の対策後、一旦は「ウィンドウを読み込めませんでした」が頻発することはなくなりました。

その後もCodex、Python Environments、GitHub Copilotなどのログを追って追加修正を行いましたが、Windows側VSCodeを完全終了・再起動した後も、現在は同じ症状が頻発する状態には戻っていません。

今回の件では、最初は、「Codexを入れたから壊れたのでは?」、「拡張機能を入れすぎた?」くらいに考えていました。 しかし実際には、単一の拡張機能だけが原因というより、

拡張機能の更新、設定スコープの混在、Remote Extension Hostへの設定反映、VSCode内部に残った古い状態

などが重なっていたようです。

特に今回の収穫は、

VSCode + Remote-WSLでは「何を設定するか」と同じくらい「どの設定ファイルに書くか」が重要

ということでした。

今後も様々な拡張機能を導入していくことになると思うので、不具合が出たら逐一ログを確認しないといけないですね。 長々と書きましたが誰かの役に立てば幸いです。

VS Codeで修正したはずのCodexのエラー対策設定が反映されなかった理由を調べた時の覚書

はじめに

前回の記事では、VS Codeで発生した拡張機能関連のエラーを調査し、設定や古い拡張機能を整理しました。

その後、VS Code自体は正常に起動するようになり、「ウィンドウを読み込めませんでした」という問題もほとんど発生しなくなりました。

一方、VS Code上で使用しているCodexのログには、次のエラーが残っていました。

PendingMigrationError: navigator is now a global in nodejs

このエラーへの対策として、まずWindows側のUser設定に次の項目を追加しました。

{
    "extensions.supportNodeGlobalNavigator": true
}

ここでいうWindows側のUser設定は、通常、次のsettings.jsonです。

%APPDATA%\Code\User\settings.json

実際のパスは、次のようになります。

C:\Users\<ユーザー名>\AppData\Roaming\Code\User\settings.json

VS Code上では、コマンドパレットから次のコマンドを実行して開けます。

Preferences: Open User Settings (JSON)

しかし、Windows側のUser設定を変更してVS Codeを再起動しても、Codexのエラーは解消しませんでした。

調査して分かったのは、Remote-WSLではVS Codeの処理がWindows側とWSL側に分かれており、拡張機能もWindows側またはWSL側のどちらかで動作しているということです。さらに、VS Codeの設定にはUser、Workspace、Remoteという適用範囲があり、今回の設定はRemote側へ明示的に追加する必要がありました。

自分はWindows版VS Codeをインストールし、マニュアルを参照しながら使用していただけだったため、拡張機能がLocal側とRemote側のどちらで動いているかを意識していませんでした。

今回は、設定を変更してもCodexへ反映されなかった経験を基に、Remote-WSLにおける拡張機能の実行場所と設定の適用範囲について、覚書としてまとめます。

1. VS CodeがLocalかRemote-WSLか

VS Codeを使い慣れている方にとっては基本的な内容だと思いますが、自分はLocal環境とRemote-WSL環境の違いをあまり意識していませんでした。

何気なくVS Codeをインストールして使い始めたため、どの操作をきっかけにRemote-WSLを使うようになったのかも、すぐには思い出せませんでした。改めて調べるうちに、WSLのターミナルからcode .を実行していたことを思い出しました。

WindowsにVS Codeをインストールして起動し、Windows側のフォルダを開いている場合は、通常、Windows上のローカル環境として動作します。

例えば、次のようなフォルダです。

C:\Users\<ユーザー名>\project

一方、次のような操作をすると、VS CodeはRemote-WSLとして起動します。

  • WSLのUbuntuターミナルからcode .を実行する
  • WSL: Connect to WSLを実行する
  • Reopen Folder in WSLを選択する
  • 最近使用した項目からWSL側のWorkspaceを開く

例えば、WSLのターミナルで次を実行した場合は、Remote-WSLとして起動します。

cd ~/project
code .

起動するアプリケーション自体はWindows版VS Codeですが、開かれるWorkspaceはWSL側にあります。

表示される画面は通常のWindows版VS Codeとほとんど変わらないため、Remote-WSLを使用していることに気付かないまま作業している場合があります。

現在Remote-WSLで開いているかどうかは、VS Codeの左下にある表示から確認できます。

WSL: Ubuntu

タイトルバーに次のように表示される場合もあります。

project [WSL: Ubuntu] - Visual Studio Code

なお、Windows側のローカルVS Codeで、統合ターミナルとしてUbuntuを開いているだけの場合はRemote-WSLではありません。

ターミナルがUbuntuかどうかではなく、VS Codeのウィンドウ自体がWSLへ接続しているかを確認する必要があります。

2. Remote-WSLはWindows側とWSL側に分かれている

Remote-WSLでは、概念的に次のような構成になります。

Windows側
├─ VS Codeの画面
├─ Local Extension Host
├─ Windows側で動く拡張機能
└─ Windows側の設定

WSL側
├─ VS Code Server
├─ Remote Extension Host
├─ WSL側で動く拡張機能
└─ WSL側の設定と開発環境

VS Codeの画面はWindows側で動作します。

一方、WSL内のファイルやLinuxコマンドを扱う処理は、WSL側で動作するVS Code Serverを通して実行されます。

拡張機能も、すべてが同じ場所で動いているわけではありません。

一般に、テーマや画面表示などに関係する拡張機能はWindows側、WorkspaceのファイルやLinux上の実行環境を扱う拡張機能はWSL側で動作します。

ただし、実際の実行場所は拡張機能の種類や設定によって異なり、VS Codeが自動的に決定します。

通常はこの処理が自動化されているため、Windows側とWSL側の違いを意識しなくても利用できます。しかし、拡張機能の設定が反映されない場合には、対象の拡張機能がどちら側で動いているかを確認する必要があります。

3. 拡張機能がどちらで動いているか確認する

拡張機能の実行場所は、コマンドパレットから確認できます。

Ctrl + Shift + Pを押し、次のコマンドを実行します。

Developer: Show Running Extensions

表示された一覧から、各拡張機能がLocal側とRemote側のどちらで動作しているかを確認できます。

Local
    Windows側のExtension Hostで動作

Remote / WSL
    WSL側のRemote Extension Hostで動作

Extensions画面でも、拡張機能のインストール先が次のように分かれて表示されます。

LOCAL - INSTALLED
WSL: UBUNTU - INSTALLED

Remote-WSLで設定が反映されない場合は、設定ファイルを繰り返し編集する前に、対象の拡張機能がどちらで動作しているかを確認した方がよいでしょう。

4. 設定にも適用範囲がある

VS Codeの設定には、主に次の適用範囲があります。

  • User設定
  • Workspace設定
  • Remote設定

User設定

その環境で使用するVS Code全体に適用される設定です。

Windows版VS Codeでは、通常、次のファイルに保存されます。

%APPDATA%\Code\User\settings.json

コマンドパレットからは、次のコマンドで開けます。

Preferences: Open User Settings (JSON)

Workspace設定

現在開いているWorkspaceにだけ適用される設定です。

通常は、プロジェクト内の次のファイルに保存されます。

.vscode/settings.json

Remote設定

現在接続しているWSL環境など、Remote環境に適用される設定です。

Remote-WSLへ接続した状態で、コマンドパレットから次のコマンドを実行して開けます。

Preferences: Open Remote Settings

VS Codeのバージョンによっては、次の名前で表示される場合もあります。

Preferences: Open Remote Settings (JSON)

今回の環境は、概念的に次の状態になっていました。

最初に設定を変更した場所
    Windows側のUser設定

Codexが動作していた場所
    WSL側のRemote Extension Host

Windows側のUser設定はRemote Windowでも基本的に利用されますが、設定の種類やRemote側の状態によっては、対象のRemote Extension Hostへ期待どおり反映されない場合があります。

今回の設定については、Remote側の設定へ明示的に追加することで、Remote Extension Hostの起動引数に反映されました。

5. Codexの設定をRemote側へ追加する

Codexのログに記録されていたエラーは、Node.jsにおけるnavigatorの扱いの変更と、拡張機能側の互換性に関係するものです。 PendingMigrationErrorは、発生すれば必ずVS Code全体が停止するような致命的エラーではありませんが、エラーが発生する位置によっては、Codexの読み込みや画面表示に影響する可能性があります。

対策として、次の設定を使用しました。

{
    "extensions.supportNodeGlobalNavigator": true
}

最初はWindows側のUser設定に上記を追加しましたが、今回の環境ではエラーが解消しませんでした。

そこで、Remote-WSLへ接続した状態で次のコマンドを実行しました。

Preferences: Open Remote Settings

開いたRemote側のsettings.jsonに、上記と同じ設定を追加しました。 さらにCodex拡張を更新し、Remote Windowの再読み込みだけでなく、Windows側のVS Codeも完全に終了してから再起動しました。

6. 設定が実際に反映されたか確認する

修正後は、settings.jsonに値が書かれていることだけでなく、Remote Extension Hostの実際の起動状態を確認しました。

修正後のRemote Extension Hostには、次の起動引数が追加されていました。

--supportGlobalNavigator

Windows側のVS Codeを完全に再起動した後、新しく生成されたログを確認し、エラーが修正できていることも確認できました。 今回の場合は、設定が間違っていたのではなく、設定を記載した場所とCodexが動作している環境の関係を正しく理解できていなかったことが問題でした。

重要なのは、次の2つは必ずしも同じではないという点でした。

settings.jsonに設定が書かれている
対象のExtension Hostに設定が反映されている

おわりに

Windows版VS Codeをただ単に使用していたため、拡張機能がどこで動いているかなんて意識していませんでした。 実際にはWorkspaceをRemote-WSLで開いており、CodexはWSL側のRemote Extension Hostで動作していることを理解するのが重要でした。 Remote-WSLで拡張機能の設定が反映されない場合は、設定を書きこむ場所が違っていて届いていないという可能性を考えるべきですね。

Remote-WSLでは、設定内容だけでなく、対象の拡張機能がWindows側とWSL側のどちらで動いているかを確認することが重要だったということを学びました。

VSCodeで「ウィンドウを読み込めませんでした」が頻発する原因を調べた時の覚書

はじめに

最近(2026年5月頃から?)、VSCodeをスリープから復帰させると、「拡張機能がディスク上で変更されています。ウィンドウを再読み込みしてください。」や「ウィンドウを読み込めませんでした」が頻発し再起動を余儀なくされていました。さすがに不便だったので原因の調査を行った(GitHub Copilotが)ので、その時の覚書を残しておきます。 基本的に自分が忘れないために書き残してますが、誰かの役に立てば幸いです。

原因の調査

まず、自分の環境にはPythonやR関係, Remote - SSH, Dev Containers, Docker, GitHub CopilotにCodexなど様々な拡張機能がインストールされています。直近ではCodexを導入し、その頃から頻発するようになったので原因はこいつか?と睨んで思い切ってアンインストールしました。がしかし、事態は変わらず。自力では無理か...と思いGitHub Copilotに原因の精査と対応をお願いしました。
GitHub Copilot曰く、

・拡張の再配置・削除・設定反映失敗が重なっていた。  
・VSCode Server が再接続時に拡張機能を自動更新または古い版の自動削除処理を行っており、その結果として拡張ディレクトリの中身が変わっていた。  
・ログでは ms-ceintl.vscode-language-pack-ja と openai.chatgpt の古い版が削除されており、これが「ディスク上で変更されています」の直接の引き金になっていた。  
・python-envsがワークスペース設定へ autoActivationType を書こうとして失敗している。  
・拡張ホスト起動直後に以下のエラーが連続していた。  
 - Roo Code: PendingMigrationError (navigator is now a global in nodejs)  
 - openai.chatgpt: PendingMigrationError (navigator is now a global in nodejs)  
 - GitHub.copilot-chat: No bundle location found for extension GitHub.copilot-chat  
・ワークスペース設定側に user-only の設定が入っていた。  
 具体的には、`.vscode/settings.json` に `extensions.autoCheckUpdates` と `extensions.autoUpdate` が入っており、VSCode が復帰のたびに「ワークスペース設定に書き込めません」とエラーを出していた。  
・Python Environments の python-envs.terminal.autoActivationType も、ワークスペース設定へ書き込もうとして失敗していた。

ということでした。拡張の更新処理と設定書き込み失敗が同時に起きて、通知が頻発して見えていたということです。

実施した対応

原因が見えてきたので以下の対策を行いました。

・.vscode/settings.json から extensions.autoCheckUpdates と extensions.autoUpdate を削除した。  
・.vscode-server/data/User/settings.json に python-envs.terminal.autoActivationType = "off" を設定した。  
・Windows ローカル側のユーザー設定 (/mnt/c/Users/<username>/AppData/Roaming/Code/User/settings.json) にも以下を設定した。  
(WSL 側だけでなく、実際に拡張管理を行うクライアント側にも同じ制御を適用するのが目的)  
 - aextensions.autoCheckUpdates=false  
 - extensions.autoUpdate=false  
 - python-envs.terminal.autoActivationType="off"  
・VSCode Server 側に残っていた不要な重複ディレクトリを整理した。具体的には以下  
 - rooveterinaryinc.roo-cline-3.54.0  
 - openai.chatgpt-26.623.70822-linux-x64  
 - ms-python.vscode-python-envs-1.36.0-linux-x64  

なぜこの対策が効くのか

・ワークスペース設定から user-only の設定を外すことで、毎回出ていた書き込みエラーを止められる。
・User settings 側にしか置けない設定は User settings に集約することで、設定の保存先の矛盾をなくせる。
・拡張の自動更新・自動削除が走り続けると、復帰のたびに拡張ディレクトリが変わるため、関連通知が続く。そのため、ユーザー設定側で自動更新の影響を抑え、不要な残骸を整理しておくことが再発防止になる。
ということです。

今回の対応のデメリット

extensions.autoCheckUpdatesextensions.autoUpdate を OFF にすると、拡張の更新通知を自動では受けにくくなる。そのため、拡張の新しい版や修正版が出ても、手動で更新確認をしないと反映が遅れる。
・セキュリティ修正や不具合修正も自動追従しにくくなるので、定期的に必要な拡張だけ手動で更新する運用が必要になる。
・Python Environments の autoActivationType を OFF にすると、ターミナル作成時の自動有効化が止まり、必要に応じて手動で環境を有効化する手間が増える。
今後別の不具合が発生したり他の解決策があるかもしれないので、このあたりのデメリットは甘んじて受け入れようと思います。定期的に状態を確認すればいい話ですね。

まだ残っている問題

・Roo Code と openai.chatgpt の PendingMigrationError は継続している(Node.js 側の互換性問題)。
・GitHub.copilot-chat の bundle 解決エラーも継続している。
これらは設定だけでは完全に消せない可能性があり、拡張の更新版適用が必要になる可能性が高い。

おわりに

これらの対策のおかげか一旦は「ウィンドウを読み込めませんでした」が頻発することはなくなりました。PC自体とVScodeを再起動しても問題なしです。
VSCodeにCodexを再インストールしましたがこちらも問題ありませんでした。
今後も様々な拡張機能を導入していくことになると思うので逐一ログを確認しないといけないですね。

2026/7/23追記

内容をアップデートしました。 ynagaoka.hatenablog.com

amd64前提の解析環境とApple Silicon Macは相性が悪いと思ったときの覚書

はじめに

少し前に1細胞解析用Docker imageについて、Apple Silicon Macユーザーから動作上の問題を報告されることがあり、少し考えるところがあったので覚書を残しておこうと思います。

何が起きたか

自分は普段、WSL2上やUbuntuサーバー環境でDocker imageをbuildしています。そのため、あまり意識していませんでしたが、そこで構築されるimageは基本的にamd64前提になります。私の環境では特に問題なく動いていたこともあり、「Docker化してあるのだから、まあ大丈夫だろう」と思っていました。しかし、Apple Silicon Macでは話が少し違うようです。
今回問題になったのは、scanpyやscVeloを含む1細胞解析ツールです。WSL2やUbuntuサーバー上でこれらのツールをinstallしたDocker imageを用意していましたが、それをApple Silicon Macユーザーが利用したところ、import scanpyの段階でフリーズし、解析を進められないという現象が起きました。

なぜこうなるのか

今回の問題の前提として、まずCPUアーキテクチャの違いがあることを知りました。一般的なWSL2環境やUbuntuサーバー環境では、x86_64/amd64を前提とした実行環境が使われることが多い一方、Apple Silicon Macはarm64アーキテクチャを採用しています。そのため、自分がWSL2環境やUbuntuサーバー環境でbuildしているDocker imageはamd64前提となり、aptで導入される依存パッケージも基本的にはamd64向けになります。
この違いは、単純なCLIツールでは表面化しなくても、scanpyやscVeloのように依存関係が多く、ネイティブライブラリも絡むツールでは問題として現れやすいのだと思います。Dockerはたしかに再現性の高い実行環境を提供してくれますが、Docker化してあることと、CPUアーキテクチャの違いを吸収できることは別次元の話だったようです。もちろん、これはすべての環境で必ず起きるとは限りませんが、少なくともamd64前提でbuildしたDocker imageをApple Silicon Macにそのまま持ち込むと、一部のツールでは不安定になりうることを実感しました。
この点は、実際にApple Silicon Macユーザーに使ってもらって初めて気づくことができました。

解決策1:Apple Silicon Mac上でarm64向けにbuildする

もっとも単純な対処法は、Apple Silicon Mac上でDocker imageをbuildすることです。Apple Silicon Mac上でdocker build を実行すると、多くの場合はホスト側に合わせてimageが作られます。そのため、単にarm64版を作りたいだけなら、Dockerfileを共有してApple Silicon Mac上でbuildするのが早いでしょう。

解決策2:amd64/arm64両対応のmulti-arch imageを作る

とは言え、解決策1が現実的でない場合は次策が必要で、こちらの方が本命かもしれません。
Dockerでは buildx を使って、amd64とarm64の両方に対応したmulti-arch imageを作成できるようになっています。
まずbuilderを作成して有効化します。

docker buildx create --name multiarch --use
docker buildx inspect --bootstrap

その後、両アーキテクチャ向けにbuildしてpushします。 ここで--pushを付けているのは、この方法ではmulti-arch image をローカルの通常イメージストアにそのまま載せないことがあるためです。Docker公式でも、デフォルトのDocker Engineのイメージストアは multi-platform image の読み込みをサポートせず、multi-platform image はレジストリへ直接 push するのが基本とされています。

docker buildx build --platform linux/amd64,linux/arm64 -t yourname/imagename:tag --push .

利用者は通常どおりpull

docker pull yourname/imagename:tag

このように両プラットフォームに対応したimagesをbuildしておけば、利用者がpullした際にその環境に合ったアーキテクチャのimageを取得することができます。Apple Silicon MacユーザーとWSL/Linuxユーザーの両方を想定する場合、この方式の方が実用的です。

この場合、できればDockerfileもmulti-archを意識して書いておくと扱いやすいです。例えば、最小限の例としてはこんな感じです。

FROM --platform=$TARGETPLATFORM ubuntu:24.04

ARG TARGETPLATFORM
ARG TARGETARCH
ARG TARGETOS

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    python3-venv \
    git \
    wget \
    curl \
    && rm -rf /var/lib/apt/lists/*

RUN echo TARGETPLATFORM=$TARGETPLATFORM
RUN echo TARGETARCH=$TARGETARCH
RUN echo TARGETOS=$TARGETOS

RUN python3 -m pip install --no-cache-dir --upgrade pip
RUN python3 -m pip install --no-cache-dir scanpy scvelo jupyter

WORKDIR /workspace

CMD ["python3"]

もちろん、実際の1細胞解析環境ではここにR、Micromamba、Jupyter kernel、各種依存ライブラリなどがさらに乗ってきます。そのため、単純に--platformを付ければ何でも解決するわけではありません。

これでも解説できないパターン

Dockerのmulti-arch化は、あくまでamd64版とarm64版のimageをまとめて配布しやすくする仕組みであり、imageの中で利用するツールや依存パッケージそのものが両アーキテクチャに対応していることまでは保証してくれません。たとえば、あるPythonパッケージや依存ライブラリがamd64向けには配布されていても、arm64向けのwheelやconda packageが用意されていない場合、その段階でbuildが失敗することがあります。あるいは、インストール自体は通ったとしても、内部でネイティブライブラリやアーキテクチャ依存コードを使っていると、import時や実行時にフリーズして問題が表面化することがあります。つまり、multi-arch imageを作ることは重要ですが、それだけで「中のツールが両方のCPUで正常に動く」ことまでは保証されていないので確認作業は必須ということです。

おわりに

自分はMacユーザーではありませんが、WSL2やUbuntuでbuildしたDocker imageを公開している身として、Apple Silicon Macの存在は今後ますます意識せざるを得ないなーと思っています。 少なくとも現時点では、amd64前提で構築した解析環境をそのままApple Silicon Macユーザーに渡すのは避けた方がよさそうです。必要に応じてarm64版を別途用意するか、multi-arch対応を進めるか。そのどちらかを考える必要があります。依存関係が重いツールまで含めて調整しようとすると、なかなか骨の折れる作業になりそうです。
同じようなところで引っかかった人の参考になれば幸いです。

DockerHub経由でGit Personal Access Token (PAT)が流出する問題に気が付いた時の覚書

はじめに

きっかけは2026年1月ごろにGitHubからPATが流出したから再生成してくださいという内容のメールを受けとったことです。 その時は再生成だけして、なんで流出したのかを深く考えずにいたのですが後になってまずいのでは?と思いました。反省
調べてみると以下のような記事が出ていました。どうやらDockerHub経由で流出したようです。

www.bleepingcomputer.com

PAT流出の原因を調べる

普段から自分のDocker imagesを作ってDockerHubにpushして、Singularity imageに変換するという作業を行っています。が、まだまだDocker初心者なので知らないことが多くあります。 そんな自分でも、Dockerfileに直接PATを書き込むのはNGということは理解していたので変数化して使用していました。 具体的には以下のようにARGENVを使用してGITHUB_PATを設定して、最後にENV GITHUB_PAT=とすることでコンテナ内にGITHUB_PATが残らないようにしていました。

FROM ubuntu:22.04

USER root
WORKDIR /opt
ARG GITHUB_PAT
ENV GITHUB_PAT=$GITHUB_PAT

RUN R -e ・・・
RUN git ・・・

RUN apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN micromamba clean --all --yes && pip cache purge
ENV GITHUB_PAT=

Docker imagesをbuildするときは以下のような感じで...

export GITHUB_PAT=XXXXXXX
docker build --build-arg GITHUB_PAT=$GITHUB_PAT -t user/images .

もちろん、ビルドしたコンテナを起動してGITHUB_PATが残っていないことも確認してました。残っていないので安心してpushしていましたがどうやら確認不足だったみたいです。
最終的にビルドしたimage内にGITHUB_PATが残っていなくとも、layersには残っていたみたいです。
DockerHub→Repositories→Tagsの順でアクセスしImage Layersを見るとなんと、そこにはもろにGITHUB_PATが書かれていました。 既にexpiredしたPATであってもなんとなく嫌だったので全部消去して作り直すことにしました。

解決策を検討する

自分なりに調べた結果、BuildKitの--secret optionが有用だろうという結論に至りました。

docs.docker.jp

詳細はリンク先を確認していただくとして新しいDockerfileの例を書き残しておこうと思います。 toolsの部分だったり、***の部分は適宜変更してください。

# syntax=docker/dockerfile:1.4
FROM ubuntu:22.04

USER root
WORKDIR /opt

#example for R packages
RUN --mount=type=secret,id=github_pat,target=/run/secrets/github_pat,mode=0400 \
    R -e "tok <- readLines('/run/secrets/github_pat', warn=FALSE); \
          Sys.setenv(GITHUB_PAT=tok, GITHUB_TOKEN=tok); \
          install.packages('BiocManager', repos='https://cloud.r-project.org'), \
          BiocManager::install(c('tools'))

#example for git (private rep)
RUN --mount=type=secret,id=github_pat,target=/run/secrets/github_pat,mode=0400 \
    token="$(tr -d '\n' < /run/secrets/github_pat)" \
    && auth="$(printf 'x-access-token:%s' "$token" | base64 -w0)" \
    && git -c "http.extraheader=Authorization: Basic ${auth}" \
    clone https://github.com//*** /opt/***

RUN apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Dockerfileを作ったら、任意の場所に github_pat ファイルを作成し、そこに PAT を記述します。 次にbuildのコマンドですが以下のような感じです。

DOCKER_BUILDKIT=1 docker build --secret id=github_pat, src=github_pat -t user/images:tag .

例えば、github_pat/work/Userに作った場合は、src=/work/User/github_patに変更してください。idの部分や、Dockerfile内の/run/secrets/github_patは変更する必要ありません。
この方法では、
github_patはbuild中にのみ存在する
・コンテナ内の/run/secrets/に格納される
・最終的なimageにも、Layersにも残らない
docker history にも表示されないない
ようです。

RUN --mount=type=secret,id=github_pat,target=/run/secrets/github_pat,mode=0400RUNのたびに記載しないといけない、git -c "http.extraheader=Authorization: Basic ${auth}"もcloneの前に毎回置かないといけないなど改善点はありますが、今のところ以前と同じようなPATの流出は起こっていなさそうです。

今回はこのような感じでDocker imagesのbuild方法を見直してみました。
まだまだ改善点は多いのでより良い方法を知っている方がいれば是非ご教授ください。

Permissionを変更するときの覚書

はじめに

長らく更新していませんでしたが、何度やっても忘れてしまうし忘れるたびにChatGPT先生に聞くのもなんだかなーと思ったので覚書を残しておこうと重い腰をあげました。

 : Permission denied

これ見るたびにあぁ変更しなきゃ...ええっと書き込みだけ許可したくて...あれコマンド何だっけ?ってなるのは自分だけでしょうか。
ルールも含めて簡単にまとめておこうと思います。

Permissionのルール

Linuxにおいてファイルやディレクトリーのアクセス権限(Permission)はr・w・xの3文字で表現され、それぞれの文字は数値を持ちます。 文字と意味、数字の対応関係は以下の通りです。

文字   意味       数値
r     read       4
w     write      2
x     execute    1 #ディレクトリでは x は「入れる(cd可能)」を意味します。
-     権限なし     0

これらを組み合わせてアクセス権を表現することになります。
例えば、-rw-r--r--もしくはdrwxrwx---みたいな感じで、10文字で表現されています。先頭の文字はファイル種別を表しており、通常ファイルは-、 ディレクトリーはdです。
なので、実際にアクセス権を示すのは先頭の1文字を除いた9文字の部分rw-r--r--になります。
アクセス権は必ず3文字セットで解釈され、所有者 / グループ / その他 の順で並びます。
つまり、drwxrwx---の意味は「このディレクトリー (d) は所有者 (rwx)は見れる・書き込める・移動できる、グループ (rwx)も見れる・書き込める・移動できる、その他 (---)は見れない・書き込めない・移動できない」です。

数値でPermissionを表現する

上で「それぞれの文字は数値を持ちます」と言いましたが、当然それにも意味があり、コマンドでアクセス権を変更したい場合は数値で表現する必要があります。
数値で表現する場合は、「3つ文字の加算」を使用します。
表でまとめたように、r=4, w=2, x=1なので、rwxは4+2+1で7になります。
実際には、アクセス権は3文字セットで、所有者 / グループ / その他の順で並んでいるので3桁の数字になります。drwxrwx---を例とするのであれば、所有者 (rwx)はr=4, w=2, x=1なので4+1+1=7、グループも同じなので7、その他は---で0+0+0=0であり、770となるわけです。

よく見る・使うパーミッション例

数値    表示     用途
644  -rw-r--r--   一般的なファイル
600  -rw-------   秘密ファイル
755  drwxr-xr-x   公開ディレクトリ
700  drwx------   個人用ディレクトリ
770  drwxrwx---   グループ共有ディレクトリ
777  drwxrwxrwx  全員フルアクセス

コマンドでPermissionを変更する

Linux では、ファイルやディレクトリのアクセス権(Permission)をchmod コマンドで変更できます。 基本コマンドは以下のような感じです。

chmod 数値 ファイル名

ちなみにヘルプを見ると色々なオプションがありますが実際使うことが多いのは-Rくらいかと思います。

chmod --help
使用法: chmod [OPTION]... MODE[,MODE]... FILE...
または: chmod [OPTION]... OCTAL-MODE FILE...
または: chmod [OPTION]... --reference=RFILE FILE...
各 FILE のモードを MODE に変更します。
--reference を指定した場合は、各 FILE のモードを RFILE のものに変更する。

  -c, --changes          verbose モードと同様だが、変更が行われた場合にのみ出力する
  -f, --silent, --quiet  ほとんどのエラーメッセージの出力を抑制する
  -v, --verbose          処理した各ファイルについて診断メッセージを出力する
      --no-preserve-root  '/' を特別扱いしない (デフォルト)
      --preserve-root     '/' に対する再帰的な操作を失敗させる
      --reference=RFILE  MODE の値ではなく RFILE のモードを使用する
  -R, --recursive        ファイルとディレクトリを再帰的に変更する
      --help     この使い方を表示して終了する
      --version  バージョン情報を表示して終了する

各 MODE の形式は '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+' です。

GNU coreutils のオンラインヘルプ: <https://www.gnu.org/software/coreutils/>
翻訳に関するバグは <https://translationproject.org/team/ja.html> に連絡してください。
詳細な文書 <https://www.gnu.org/software/coreutils/chmod>
(ローカルでは info '(coreutils) chmod invocation' で参照可能)。

実際の例としてはこんな感じでしょうか?

#ファイル単体を変更
chmod 644 sample.txt 

#ディレクトリー単体を変更
chmod 770 project_dir 

#ディレクトリー配下全てを変更
chmod -R 770 project_dir 

#project_dir配下にあるディレクトリー全てを変更 (ファイルは変更されない)
find project_dir -type d -exec chmod 770 {} \;

#project_dir配下にあるファイル全てを変更 (ディレクトリーは変更されない)
find project_dir -type f -exec chmod 644 {} \;

#実行可能ファイルだけにxを追加
find project_dir -type f -name "*.sh" -exec chmod 755 {} \;

また、数値ではなく、記号で指定することも可能です。(あまり使わない?)

#例
chmod g+w file.txt   #グループに書き込み権限を追加
chmod o-r file.txt   #その他の読み取り権限を削除
chmod +x script.sh #実行権限追加

あとは、基本的に親ディレクトリーのパーミッションを変更したとしても配下に作られたファイルやディレクトリーは設定を継承しません。これは少々面倒だという場合は以下が有用でしょう。

chmod 2770 project_dir

project_dir配下に作られたファイルが 親ディレクトリのグループを継承するようになるので意外と便利です。

chmodPermission denied と表示されたら、sudo が必要かもしれません。 ただし、設定ファイルを対象にしている場合には変更する前に「本当にやって大丈夫か?」を一度考えましょう。 sudo権限を持っていない場合は管理者に相談しましょう。

ここまでまとめておけば忘れないはず...

Dockerとは何か?の覚書ーその2ーインストール・アンインストール編

はじめに

今回はUbuntu上にDockerをインストール・アンインストールするコマンドをまとめようと思います。基本的にコピペで実行できると思います。

インストール

Step1 : Docker's apt repositoryのセットアップ

以下のコマンドを順に実行していきインストールに必要なものを揃えます。

# Add Docker's official GPG key:
$ sudo apt-get update

$ sudo apt-get install ca-certificates curl gnupg

$ sudo install -m 0755 -d /etc/apt/keyrings

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

続いて以下を実行します。

# Add the repository to Apt sources
$ echo \
 "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
 $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
 sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

$ sudo apt-get update

Step2 : 最新版のインストール

以下のコマンドでDockerをインストールします。

$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

エラーが出なければインストール完了です。

Step3 : インストールできているか確認

docker run hello-worldというテスト用のコマンドを実行して以下の表示が出れば問題なくDockerがインストールできています。

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:266b191e926f65542fa8daaec01a192c4d292bff79426f47300a046e1bc576fd
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

このコマンドではhello-worldというimagesをDockerレポジトリーからダウンロードして実行します。
docker imagesをいうコマンドを実行するとダウンロードされているイメージを確認できます。

$ docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    d2c94e258dcb   12 months ago   13.3kB

コマンドが実行できない場合

docker runが実行できない場合Dockerデーモンが起動していない可能性があるので以下のコマンドを実行して状態の確認と再起度をしてもう一度実行してみてください。

#check the status 
$ sudo service docker status

#boot
$ sudo service docker start

もし、パーミッションエラーが出る場合はdockerというグループにユーザーが属していない可能性があるので以下のコマンドで追加してください。

$ sudo groupadd docker
$ sudo usermod -aG docker $USER

DockerHubにログインする場合は以下のコマンドで実行できます。

$ docker login

アンインストール

DockerをUbuntuから完全にアンインストールするコマンドをまとめます。
まず以下のコマンドでdockerと名の付くものを確認します。

$ dpkg -l | grep -i docker

確認したら削除します。

$ sudo apt-get purge -y docker-engine docker docker.io docker-ce docker-ce-cli docker-compose-plugin
$ sudo apt-get autoremove -y --purge docker-engine docker docker.io docker-ce docker-compose-plugin

このコマンドはDocker imagesやコンテナ、ボリューム等は消去されません。消去するには以下を実行します。

$ sudo rm -rf /var/lib/docker /etc/docker
$ sudo rm /etc/apparmor.d/docker
$ sudo groupdel docker
$ sudo rm -rf /var/run/docker.sock
$ sudo rm -rf /var/lib/containerd
$ sudo rm -r ~/.docker

dockerコマンドを実行してエラーが出れば消去完了です。

$ docker --version
-bash: /usr/bin/docker: そのようなファイルやディレクトリはありません

これで完全に消去できたと思います。
Dockerを再度インストールする場合はdockerと名の付くファイルを完全に削除してから行わないと予期せぬ挙動をすることがあるので注意が必要です。

Dockerのリセット

アンインストールまではいかずともイメージやキャッシュをまとめてリセットしたい場合は以下のコマンドで実行できます。 このコマンドは他人がPullしたimageやBuild中のキャッシュなど全てを消し去るので、共通PCやサーバーなどで実行しないように注意してください。

$ docker system prune -af

以上でインストール・アンインストール・クリーニングができると思います。