事象
goなdevcontainerをPodmanで動かそうとしたら 次のようなエラーが出て失敗する。
[6760 ms] Command in container failed: mkdir -p '/root/.vscode-server/bin' && ln -snf '/vscode/vscode-server/bin/linux-x64/f1e16e1e6214d7c44d078b1f0607b2388f29d729' '/root/.vscode-server/bin/f1e16e1e6214d7c44d078b1f0607b2388f29d729' [6760 ms] mkdir: cannot create directory '/root': Permission denied
対応
次のIssueをみたらいくつか回避方法があるようだった。
devcontainer.jsonに次を追記してdevcontainerをリビルドしたら解消した。
"runArgs": [ "--userns=keep-id" ], "containerUser": "vscode"
containerUserはコンテナによって合わせる必要があるかもしれない。
以上。
おまけ: オプションを調べた
なんでこの2つが必要なのかよくわかってなかった。今もよくわかってない。
"--userns=keep-id"
はpodmanのオプションらしい。
https://docs.podman.io/en/latest/markdown/podman-kube-play.1.html#userns-mode
"containerUser":"vscode"
だけだと、コンテナ起動まではできるようになるが、以下のようになってしまう。
vscode ➜ /workspaces/docker-bind-build $ id uid=1002(vscode) gid=1002(vscode) groups=1002(vscode),998(nvm),999(golang) vscode ➜ /workspaces/docker-bind-build $ ls -l total 16 drwxr-xr-x 4 root root 4096 Jul 29 21:39 cmd -rw-r--r-- 1 root root 722 Jul 29 21:50 Dockerfile -rw-r--r-- 1 root root 74 Jul 29 21:54 go.mod -rw-r--r-- 1 root root 84 Jul 29 21:47 go.sum
(docker-bind-buildっていうプロジェクト名は特に何の意味もありません。)
ファイルの所有者がrootに見える。実行ユーザはvscodeなので一致しない。編集できない。開発できない。
そこで"--userns=keep-id"
を追記してdevcontainerをリビルドするとこうなった。
vscode ➜ /workspaces/docker-bind-build $ id uid=1002(vscode) gid=1002(vscode) groups=1002(vscode),998(nvm),999(golang) vscode ➜ /workspaces/docker-bind-build $ ls -l total 16 drwxr-xr-x 4 vscode vscode 4096 Jul 29 21:39 cmd -rw-r--r-- 1 vscode vscode 722 Jul 29 21:50 Dockerfile -rw-r--r-- 1 vscode vscode 74 Jul 29 21:54 go.mod -rw-r--r-- 1 vscode vscode 84 Jul 29 21:47 go.sum
編集できる。いい感じ。
"--userns=keep-id"
だけだとおおもとのエラーになってしまった。
containerUserを"myuser"とか適当なユーザにすると、リビルドが失敗するようになってしまった。ログを見る感じ、podman run
のオプションに -u myuser
という感じでつけようとするので少なくともコンテナで扱えるユーザである必要がありそうだ。
うーん、コンテナ内のrootをコンテナ実行ユーザにするだけでいいはずなんじゃないんかな。devcontainerのお作法との兼ね合いがあるんだろうか。
ともかく、なぜこうなるかはよくわからないけど、動くのでヨシ!
でもこれ毎回忘れそうだな。devcontainer.jsonを作るときに勝手に追記してくれないし。
おまけ: devcontainerでpodmanを使うとは?
https://code.visualstudio.com/remote/advancedcontainers/docker-options#_podman
まず、Podmanでdevcontainerを動かすだけなら以下をsettings.jsonに足せばdockerの代わりにpodmanを使ってくれるようになる。
{ "dev.containers.dockerComposePath": "podman-compose", "dev.containers.dockerPath": "podman" }
また、上記リンクの通り、podmanに関する問題がいくつかあり、そのワークアラウンドでdevcontainer.jsonも修正が必要とあるが、その通りにやってもうまくいかなかった。