You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: refuse a null wherever docker compose refuses one (#61)
compose2pod is a drop-in replacement for docker compose on rootless runners:
the file it converts is the file the developer runs locally. That makes
accepting-what-Docker-refuses actively harmful rather than merely lax -- the
document is already broken in the real workflow, so converting it anyway means
CI goes green on a file docker compose would not run. A false green is worse
than a hard error.
So the test is not "does this null drop behavior?" but "would docker compose
run this file at all?". Eight positions failed it, accepted here and refused by
docker compose config, each emitting nothing:
healthcheck.test / .interval / .timeout / .retries / .start_period
deploy.resources / .limits / .reservations
top-level networks: / volumes: / secrets: / configs:
This reverses changes/2026-07-13.10's null-scalar ruling (a null healthcheck
timeout/retries/start_period meant "unset"). That ruling was taken on the stated
premise that it matched docker compose config. It does not -- Docker refuses all
three. The premise was wrong, so the conclusion goes with it.
A null INSIDE a value is untouched and still accepted, because Docker accepts it
too: environment: {KEY: null} is host-passthrough, labels: {KEY: null} an empty
label.
summary: A null is refused in every nested and top-level position Docker refuses one (healthcheck sub-keys, deploy's resource blocks, the top-level networks/volumes/secrets/configs blocks), so a document docker compose would not run cannot pass CI green here.
3
+
---
4
+
5
+
# Design: Refuse a null wherever Docker refuses one
6
+
7
+
## Summary
8
+
9
+
`2026-07-14.07` matched Docker's null policy for *service* keys. It stopped
10
+
there. Inside `healthcheck` and `deploy`, and in the top-level blocks, a null is
11
+
still accepted and silently emits nothing.
12
+
13
+
Carry the same rule down: **a null is refused wherever `docker compose config`
14
+
refuses one.** Measured, position by position.
15
+
16
+
## Motivation
17
+
18
+
compose2pod exists to run a Compose file on a rootless CI runner where
19
+
`docker compose` and `podman kube play` cannot. It is a **drop-in replacement**:
20
+
the file it converts is the same file the developer runs locally with
21
+
`docker compose up`.
22
+
23
+
That makes accepting-what-Docker-refuses actively harmful, not merely lax:
24
+
25
+
-**Docker refuses, compose2pod accepts** → the document is already broken in the
26
+
developer's real workflow. Converting it anyway does not rescue anything; it
27
+
means **CI goes green on a file `docker compose` would not run**. A false
28
+
green is worse than a hard error.
29
+
-**Docker accepts, compose2pod refuses** → a working file breaks. That is the
30
+
direction that must never happen.
31
+
32
+
So the test is not "does this null drop behavior?" but "**would `docker compose`
33
+
run this file at all?**" If it would not, there is no point emitting a podman
34
+
script for it.
35
+
36
+
Eight positions failed that test — accepted here, refused by
37
+
`docker compose config` (v5.1.2), each emitting nothing:
0 commit comments