Open4

CodeSandbox の podman で docker-compose

hankei6kmhankei6km

Codesandbox は podman はインスールされているが podman-compose はインスールされていない。

Dev Container で dockerComposeFile を使いたいので、その辺を試す。

なお、

  • CodeSandbox では docker は rootless なので Dev Container で使うのは難しい
    • podman なら設定を少し変更するといける。
  • Nix で podman-compose をインストールできるが podman-compose ではエラーになる(原因は不明)。

ということはわかっているので、試すのは docker-compose から podman を使う方法となる。

hankei6kmhankei6km

通常のリポジトリ(サンドボックス)

まずは docker-compose の挙動を確認してみる。

テスト用のリポジトリを作って確認。

https://github.com/hankei6km/test-csb-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 をコンテナで動かす方法があった。

https://rheb.hatenablog.com/entry/podman3-rootless-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 をつけてある。

https://github.com/hankei6km/test-csb-podman-docker-compose/blob/main/scripts/podman-docker-compose

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
hankei6kmhankei6km

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 を使っている。

https://codesandbox.io/docs/learn/environment/docker

While we call this a Docker integration, we use rootless Podman to run the containers.

よって、コンテナ内の docker-compose は ホスト側の podman を使っていると思われる(上のコメントでやった docker-compose をコンテナ化したコンテナ内にいるような状態になっている)。

hankei6kmhankei6km

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