suborbital/subo

Subo should support systems with docker compose (v2)

Closed this issue · 8 comments

flaki commented

I installed Docker from the repository on Ubuntu, side-stepping Docker Desktop, and so I only have docker-compose-plugin which is the new docker compose (note the space).

The docker compose (with a space) is a newer project to migrate compose to Go with the rest of the docker project. This is the v2 branch of the docker/compose repo. It's been first introduced to Docker Desktop users, so docker users on Linux didn't see the command. In addition to migrating to Go, it uses the compose-spec, and part of the rewrite may result in behavior differences.

Apparently this is the way of the future, and subo compute deploy core --local currently fails with an error, not being able to find the old docker-compose command:

⏩ START: preparing deployment
ℹ️  using cached environment token
✅ DONE: ready to start installation
⏩ START: installing...
sh: 1: docker-compose: not found
Error: 🚫 failed to docker-compose up: failed to Run command: exit status 127
Usage:
  subo compute deploy core [flags]

Because alias-es don't work with subo, one actually needs to create a shell shim that re-maps docker-compose to docker compose (and that works because up is the same in both CLI-s), but this is a hassle and is undocumented, so we should at least document it, but it would be better fixing it in subo itself.

To be decided: In the absence of docker compose, fall back to docker-compose or just fail?

All Docker Desktop installations (including on Linux) bundle the compose plugin. All Docker Engine CLI installation instructions include the compose plugin in the install step. So we should be able to expect it to be there, or give clear instructions for how to add it. Things might get rougher for users of tools like podman which does not directly support the compose subcommand.

Notably nerdctl (a Docker CLI compatible frontend for containerd) does support compose as a subcommand

DECISION: Prefer docker compose but fall back to docker-compose.

RATIONALE: New Docker installs may not have docker-compose, old Docker installs may not have docker compose. We're not doing anything too exotic, so falling back offers maximum compatibility. It also eases support for alternative runtimes like Podman which do not support the compose tertiary command, but do provide a docker-compose workalike.

ALTERNATIVE RUNTIMES: We care about Podman and Nerdctl.

  • Podman is important because it replaces Docker (and is aliased to docker) in modern RHEL / Fedora releases.

  • Nerdctl is important because containerd is a common runtime choice in Docker Desktop alternatives (Rancher Desktop, Colima, Lima). Containerd also replaces dockerd in recent Kubernetes releases.

CHALLENGES:

  1. Detecting support for the compose subcommand is tricky.

    The Docker docs suggest checking the exit code of docker compose version but this only works on the official Docker runtime.

    Nerdctl works fine with compose up -d, but does not support the version tertiary command to detect that support. We'd need to find an alternative command that is safe to invoke.

  2. Podman has no support for the compose subcommand command, but does provide a podman-compose program which works fine with subo when aliased to docker-compose.

    So long as we fall back to docker-compose from docker compose, Podman will easily Just Work for most of its users.

ALTERNATIVES CONSIDERED:

  1. Only supporting docker compose.

    • Not available on older Docker versions (but we could tell them to upgrade).
    • Not mandatory in modern Docker versions (but we could tell them to install it).
    • No easy solution for Podman users (would require shimming with a slightly complex shell script).
  2. Only supporting docker-compose.

    • Deprecated upstream.
    • Not mandatory in modern Docker versions.
    • Annoying for Nerdctl users (but solvable with a simple shim script).

We still need to figure out how to detect support for docker compose when actually running nerdctl. This may not be possible.

As of nerdctl 0.22.2, only the following tertiary commands are supported: build, config, down, kill, logs, ps, pull, push, up.

All requires a valid docker-compose.yml file in current working directory, and could thus fail if the file is missing or malformed, even if adequate compose support is present.

The only command without side-effects is compose config --quiet, but given the requirement for a valid YAML file, this command could fail for myriad reasons.

I don't see a reasonable way out, here.

@flaki Thoughts? I'm inclined to revert back to "We only support docker compose. If docker compose up -d fails, tell people to check that the compose plugin is installed." Podman users are a tiny minority and can figure it out for themselves.

FWIW, looks like Podman is unlikely to support the compose subcommand any time soon (see: containers/podman#11780). Not sure about nerdctl but have asked (containerd/nerdctl#1368)

flaki commented

@flaki Thoughts? I'm inclined to revert back to "We only support docker compose. If docker compose up -d fails, tell people to check that the compose plugin is installed." Podman users are a tiny minority and can figure it out for themselves.

Sorry, I seem to have missed this but as mentioned in #354 I strongly prefer defaulting to to docker compose and doing a reasonable fallback, like we currently do. Since we don't use any exotic switches of the command we can get away with just the "dumb" switching between the command forms (=swapping out/in the dash).

In terms of alternative frontends/podman support, I think we need to be very strategic and explicit about wanting to support them, I have seen it in too many places that

In short, alias podman=docker is a lie (for us).

If we want to support this we need to explicitly invest and commit to maintaining it (that said, we could still improve things through something like #342)