Description
Running podlet compose fails when a service uses the long-form port syntax:
ports:
- mode: ingress
target: 80
published: "8080"
protocol: tcp
Error:
Error:
0: error converting compose file
1: error converting compose file into Quadlet files
2: error converting service `whoami` into a Quadlet container
3: error converting `ports`
4: could not convert port to short syntax, port = Port {
name: None,
target: 80,
published: Some(
Range {
start: 8080,
end: None,
},
),
host_ip: None,
protocol: Some(
Tcp,
),
app_protocol: None,
mode: Some(
Ingress,
),
extensions: {},
}
Location:
src/cli/container/quadlet.rs:753
The long-form syntax is valid per the Compose spec
and commonly generated by podman compose config when expanding environment variables or
processing compose files with advanced features.
Podlet currently requires the short form:
Steps to reproduce
- Create the file:
cat > compose.yaml <<'EOF'
services:
whoami:
image: docker.io/traefik/whoami:v1.11
ports:
- mode: ingress
target: 80
published: "8080"
protocol: tcp
EOF
- Convert with podlet:
podman run --rm -v .:/app ghcr.io/containers/podlet compose /app/compose.yaml
Podlet version
$ podman run --rm ghcr.io/containers/podlet --version
podlet 0.3.1
Podman environment
$ podman --version
podman version 4.9.3
$ podman info
host:
arch: amd64
buildahVersion: 1.33.7
cgroupControllers:
- cpu
- memory
- pids
cgroupManager: systemd
cgroupVersion: v2
conmon:
package: conmon_2.1.10+ds1-1build2_amd64
path: /usr/bin/conmon
version: 'conmon version 2.1.10, commit: unknown'
cpuUtilization:
idlePercent: 98.91
systemPercent: 0.43
userPercent: 0.66
cpus: 8
databaseBackend: sqlite
distribution:
codename: noble
distribution: ubuntu
version: "24.04"
eventLogger: journald
freeLocks: 2021
hostname: DENEC1
idMappings:
gidmap:
- container_id: 0
host_id: 1000
size: 1
- container_id: 1
host_id: 100000
size: 65536
uidmap:
- container_id: 0
host_id: 1000
size: 1
- container_id: 1
host_id: 100000
size: 65536
kernel: 6.6.87.2-microsoft-standard-WSL2
linkmode: dynamic
logDriver: journald
memFree: 3947634688
memTotal: 8114102272
networkBackend: netavark
networkBackendInfo:
backend: netavark
dns:
package: aardvark-dns_1.4.0-5_amd64
path: /usr/lib/podman/aardvark-dns
version: aardvark-dns 1.4.0
package: netavark_1.4.0-4_amd64
path: /usr/lib/podman/netavark
version: netavark 1.4.0
ociRuntime:
name: crun
package: crun_1.14.1-1_amd64
path: /usr/bin/crun
version: |-
crun version 1.14.1
commit: de537a7965bfbe9992e2cfae0baeb56a08128171
rundir: /run/user/1000/crun
spec: 1.0.0
+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +WASM:wasmedge +YAJL
os: linux
pasta:
executable: /usr/bin/pasta
package: passt_0.0~git20240220.1e6f92b-1_amd64
version: |
pasta unknown version
Copyright Red Hat
GNU General Public License, version 2 or later
<https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
remoteSocket:
exists: false
path: /run/user/1000/podman/podman.sock
security:
apparmorEnabled: false
capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
rootless: true
seccompEnabled: true
seccompProfilePath: /usr/share/containers/seccomp.json
selinuxEnabled: false
serviceIsRemote: false
slirp4netns:
executable: /usr/bin/slirp4netns
package: slirp4netns_1.2.1-1build2_amd64
version: |-
slirp4netns version 1.2.1
commit: 09e31e92fa3d2a1d3ca261adaeb012c8d75a8194
libslirp: 4.7.0
SLIRP_CONFIG_VERSION_MAX: 4
libseccomp: 2.5.5
swapFree: 2147483648
swapTotal: 2147483648
uptime: 1h 46m 50.00s (Approximately 0.04 days)
variant: ""
plugins:
authorization: null
log:
- k8s-file
- none
- passthrough
- journald
network:
- bridge
- macvlan
- ipvlan
volume:
- local
registries: {}
store:
configFile: /home/karna/.config/containers/storage.conf
containerStore:
number: 1
paused: 0
running: 0
stopped: 1
graphDriverName: overlay
graphOptions: {}
graphRoot: /home/karna/.local/share/containers/storage
graphRootAllocated: 1081101176832
graphRootUsed: 17860415488
graphStatus:
Backing Filesystem: extfs
Native Overlay Diff: "true"
Supports d_type: "true"
Supports shifting: "false"
Supports volatile: "true"
Using metacopy: "false"
imageCopyTmpDir: /var/tmp
imageStore:
number: 145
runRoot: /run/user/1000/containers
transientStore: false
volumePath: /home/karna/.local/share/containers/storage/volumes
version:
APIVersion: 4.9.3
Built: 0
BuiltTime: Thu Jan 1 01:00:00 1970
GitCommit: ""
GoVersion: go1.22.2
Os: linux
OsArch: linux/amd64
Version: 4.9.3
Anything else?
Context: Several Compose features are currently not supported by podlet:
include directive
extends directive
profiles directive
- Environment variable expansion (
${VAR:-default})
To work around these limitations, I tried using podman compose config to simplify and expand my compose file before converting with podlet.
This successfully resolves the unsupported features by:
- Merging included files
- Expanding extended service configurations
- Filtering services by profile
- Resolving environment variable syntax
However, podman compose config automatically converts all port mappings to long-form syntax, which then blocks podlet conversion.
This creates a catch-22 situation where the workaround for one set of limitations introduces a new blocking issue.
Workaround (tedious): Manually convert long-form ports back to short syntax:
# FROM (podman compose config output):
ports:
- mode: ingress
target: 80
published: "8080"
protocol: tcp
# TO (podlet-compatible):
ports:
- "8080:80"
Expected behavior: Podlet should accept long-form port syntax and convert it to Quadlet's PublishPort= directive,
extracting the relevant fields (published → target) and ignoring metadata fields like mode and app_protocol.
Suggested conversion logic:
published: "8080" + target: 80 → PublishPort=8080:80
host_ip: "127.0.0.1" → PublishPort=127.0.0.1:8080:80
protocol: udp → PublishPort=8080:80/udp
- Ignore:
mode, app_protocol, name (not supported by Podman Quadlet)
Description
Running
podlet composefails when a service uses the long-form port syntax:Error:
The long-form syntax is valid per the Compose spec
and commonly generated by
podman compose configwhen expanding environment variables orprocessing compose files with advanced features.
Podlet currently requires the short form:
Steps to reproduce
Podlet version
Podman environment
Anything else?
Context: Several Compose features are currently not supported by podlet:
includedirectiveextendsdirectiveprofilesdirective${VAR:-default})To work around these limitations, I tried using
podman compose configto simplify and expand my compose file before converting with podlet.This successfully resolves the unsupported features by:
However,
podman compose configautomatically converts all port mappings to long-form syntax, which then blocks podlet conversion.This creates a catch-22 situation where the workaround for one set of limitations introduces a new blocking issue.
Workaround (tedious): Manually convert long-form ports back to short syntax:
Expected behavior: Podlet should accept long-form port syntax and convert it to Quadlet's
PublishPort=directive,extracting the relevant fields (
published→target) and ignoring metadata fields likemodeandapp_protocol.Suggested conversion logic:
published: "8080"+target: 80→PublishPort=8080:80host_ip: "127.0.0.1"→PublishPort=127.0.0.1:8080:80protocol: udp→PublishPort=8080:80/udpmode,app_protocol,name(not supported by Podman Quadlet)