CodeSandbox の podman で docker-compose
Codesandbox は podman はインスールされているが podman-compose はインスールされていない。
Dev Container で dockerComposeFile
を使いたいので、その辺を試す。
なお、
- CodeSandbox では docker は rootless なので Dev Container で使うのは難しい
- podman なら設定を少し変更するといける。
- Nix で podman-compose をインストールできるが podman-compose ではエラーになる(原因は不明)。
ということはわかっているので、試すのは docker-compose から podman を使う方法となる。
通常のリポジトリ(サンドボックス)
まずは docker-compose の挙動を確認してみる。
テスト用のリポジトリを作って確認。
初期状態
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ podman container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker-compose up -d
をしてみる。
Docker 側にコンテナが作成される。
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a32f106f3991 alpine:latest "/bin/sh" 17 seconds ago Up 16 seconds test-compose_srv2_1
3cd8b8f109ae alpine:latest "/bin/sh" 17 seconds ago Up 16 seconds test-compose_srv1_1
$ podman container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ということで podmand を使うなら何かしらトリックが必要。ソケットを差し替えてしまえばよいらしいが、リポジトリ(サンドボックス)だと root
でないのでちょっと難しい。
下記に docker-compose
をコンテナで動かす方法があった。
これで動作する。なお、ユーザー id は変更してある(リポジトリだと 1002
でよさそうだけど、サンドボックスだと動的に変更されると思われる)。が、これだと docker-compose.yml
を PATH で指定されたりするとダメかな?
$ alias docker-compose='podman run --rm \
-v /run/user/1002/podman/podman.sock:/var/run/docker.sock:z \
-v "$PWD:/$PWD:z" \
-w "/$PWD" \
docker/compose:1.29.2'
$ docker-compose up -d
スクリプトだと下記のような感じ。docker-compose exec
で使う場合、ちょっと不便だったので -it
をつけてある。
podman でコンテナが作成される。
$ ../scripts/podman-docker-compose up -d
Creating network "test-compose_default" with the default driver
Creating test-compose_srv2_1 ... done
Creating test-compose_srv1_1 ... done
$ podman container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9079ee255c61 docker.io/library/alpine:latest /bin/sh 12 seconds ago Up 11 seconds ago test-compose_srv2_1
a25dce967f90 docker.io/library/alpine:latest /bin/sh 12 seconds ago Up 11 seconds ago test-compose_srv1_1
Docker インテグレーションのコンテナ内
サンドボックスを Docker インテグレーションのテンプレートから作成する。
コンテナ内で docker-compose でコンテナを作成した後、docker container ls -a
でコンテナを確認すると下記のようになる。
devcontainer
は Docker インテグレーションで作成されたコンテナと思われる。
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4352a79e7478 alpine:latest "/bin/sh" 3 minutes ago Up 3 minutes tesst-compose_srv1_1
c6b19f75fe2e alpine:latest "/bin/sh" 3 minutes ago Up 3 minutes tesst-compose_srv2_1
ece856a3f774 localhost/codesandbox/dev-image:latest "bash" 4 minutes ago Up 4 minutes devcontainer
コンテナ内から ID を確認してみると、やはりそのように思われる。
$ cat /proc/self/mountinfo | grep overlay
249 214 0:48 / / rw,nodev,noatime - fuse.fuse-overlayfs fuse-overlayfs rw,user_id=0,group_id=0,default_permissions,allow_other269 249 0:19 /tmp/containers-user-1002/containers/overlay-containers/ece856a3f7740c26440c128deb3859a67c98f0682b895a29df91e0a61592a7d9/userdata/resolv.conf /etc/resolv.conf rw,relatime - overlay overlay rw,lowerdir=/lower,upperdir=/upper/upper,workdir=/upper/work
272 249 0:19 /tmp/containers-user-1002/containers/overlay-containers/ece856a3f7740c26440c128deb3859a67c98f0682b895a29df91e0a61592a7d9/userdata/hostname /etc/hostname rw,relatime - overlay overlay rw,lowerdir=/lower,upperdir=/upper/upper,workdir=/upper/work
277 249 0:19 /tmp/containers-user-1002/containers/overlay-containers/ece856a3f7740c26440c128deb3859a67c98f0682b895a29df91e0a61592a7d9/userdata/.containerenv /run/.containerenv rw,relatime - overlay overlay rw,lowerdir=/lower,upperdir=/upper/upper,workdir=/upper/work
279 249 0:19 /tmp/containers-user-1002/containers/overlay-containers/ece856a3f7740c26440c128deb3859a67c98f0682b895a29df91e0a61592a7d9/userdata/hosts /etc/hosts rw,relatime - overlay overlay rw,lowerdir=/lower,upperdir=/upper/upper,workdir=/upper/work
282 249 0:19 /usr/local/bin/lsp /usr/local/bin/lsp ro,relatime - overlay overlay rw,lowerdir=/lower,upperdir=/upper/upper,workdir=/upper/work
また、Docker インテグレーションは rootless podman を使っている。
While we call this a Docker integration, we use rootless Podman to run the containers.
よって、コンテナ内の docker-compose は ホスト側の podman を使っていると思われる(上のコメントでやった docker-compose
をコンテナ化したコンテナ内にいるような状態になっている)。
Dev Contaners で使えるのか?
現状では厳しい。
素のリポジトリ(サンドボックス) で docker-compose をコンテナで動かした場合は、-f
による .yml
ファイルの指定を処理できない。
Docker インテグレーションのコンテナ内の場合は、(docker-compose.yml
の内容によるかもしれないが)下記のエラーになる。
Building pubsub
Sending build context to Docker daemon 4.608kB
request returned Bad Request for API route and version http://%2Fvar%2Frun%2Fpodman%2Fpodman.sock/v1.41/build?buildargs=%7B%22PUBSUB_EMULATOR_HOST%22%3A%22pubsub%3A8043%22%2C%22PUBSUB_PROJECT_ID%22%3A%22abc%22%7D&cachefrom=%5B%5D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&labels=%7B%7D&memory=0&memswap=0&networkmode=default&rm=1&shmsize=0&t=workspace_devcontainer_pubsub&target=&ulimits=null&version=1, check if the server supports the requested API version
ERROR: Service 'pubsub' failed to build : Build failed
Error: Command failed: docker-compose --project-name workspace_devcontainer -f /workspace/.devcontainer/docker-compose.yml -f /tmp/devcontainercli-root/docker-compose/docker-compose.devcontainer.build-1675272569757.yml build