The Podman plugin runs podman build and podman push (or
podman manifest push for multi-arch builds) inside a Woodpecker
pipeline. The setting surface mirrors the podman build and
podman push flags 1:1, so anything documented for those subcommands
can be expressed as a plugin setting.
Runtime requirements
The plugin runs podman build. The pipeline container must be able
to create a new user namespace (CLONE_NEWUSER); the plugin probes
this at startup via unshare -U and aborts with a clear error if
blocked.
| Runner |
Notes |
| Codeberg public CI |
Default seccomp profile lets CLONE_NEWUSER through; works out of the box. |
| Self-hosted Woodpecker, image on the server's allowlist |
Server escalates the step automatically. |
Self-hosted Woodpecker, repo marked trusted, step uses privileged: true |
Same as above. |
Cross-arch builds (platforms covering more than the host
architecture) need qemu binfmt handlers registered on the build
host with the F (fix-binary) flag. The plugin itself does no
in-container binfmt registration; it relies on the host providing
handlers that the kernel exposes to every nested rootless user
namespace via F.
Since Linux 6.7 binfmt_misc is per-user-namespace and rootless
podman creates a fresh userns per build. Without F, the kernel
opens the interpreter lazily inside that fresh userns and fails to
find it. With F, the kernel pins the interpreter file descriptor
at registration time on the host and re-uses that open fd on every
exec, independent of the calling namespace.
On Fedora CoreOS, layer the package via rpm-ostree:
sudo rpm-ostree install qemu-user-static
sudo systemctl reboot
Fedora's qemu-user-static ships
/usr/lib/binfmt.d/qemu-*-static.conf files with F already set;
systemd-binfmt registers them on the next boot. On other distros,
install the equivalent statically-linked qemu package and verify
flags: F (or similar) is present in
/proc/sys/fs/binfmt_misc/qemu-<arch>.
The
chilly-willy-agent
reference setup ships this wiring in its Ignition config.
Settings
Output and authentication
| Setting |
Default |
Description |
repo |
none |
Target image repository (e.g. head1328/myapp). With registry and tags this forms the destination ref. |
tags |
latest |
One or more image tags. List or comma-separated. |
registry |
docker.io |
Registry hostname or hostname/path. |
username |
none |
Registry username for podman login. |
password |
none |
Registry password or access token (use a Woodpecker secret). |
auth_config |
none |
Full registry auth JSON, written verbatim to $REGISTRY_AUTH_FILE. Use for multi-registry pushes. |
dry_run |
false |
Build only, skip push. Automatically enabled when no repo is set. |
Source
| Setting |
Default |
podman build flag |
Description |
containerfile |
Containerfile |
--file |
Path to the Containerfile, relative to context. |
context |
$CI_WORKSPACE |
(positional) |
Build context directory. |
target |
none |
--target |
Multi-stage build target. |
build_args |
none |
--build-arg |
KEY=VALUE entries. List or comma-separated. |
build_args_from_env |
none |
--build-arg |
Names of env vars to forward as build args. |
env_file |
none |
(sourced) |
File whose KEY=VALUE lines are sourced into the plugin environment before the build. |
Multi-architecture
| Setting |
podman build flag |
Description |
platforms |
--platform + --manifest |
Comma-separated list. Triggers manifest-list mode: the plugin builds for every platform and pushes the resulting manifest list via podman manifest push --all. |
platform |
--platform |
Single-target build. |
arch |
--arch |
CPU architecture for the build. |
os |
--os |
Operating system for the build. |
variant |
--variant |
CPU variant (e.g. v7). |
manifest |
--manifest |
Override the internal manifest list name (default: auto-generated). |
Caching
| Setting |
podman build flag |
Description |
cache |
--layers=true |
Enable layer caching. |
cache_from |
--cache-from |
Registry path(s) to pull cache layers from. List. |
cache_to |
--cache-to |
Registry path(s) to push cache layers to. List. |
no_cache |
--no-cache=true |
Do not use any cached layers. |
Image metadata
| Setting |
podman build flag |
Description |
labels |
--label |
OCI labels (KEY=VALUE). List. |
annotations |
--annotation |
OCI annotations (KEY=VALUE). List. |
format |
--format |
Image format: oci or docker. |
squash |
--squash=true |
Squash newly built layers into one. |
squash_all |
--squash-all=true |
Squash every layer, including the base. |
omit_history |
--omit-history=true |
Do not record build history in the image. |
identity_label |
--identity-label=true |
Add a default identity label to the image. |
Build environment
| Setting |
podman build flag |
Description |
secrets |
--secret |
Build-time secrets, e.g. id=mytoken,src=/run/secrets/foo or id=mytoken,env=MY_ENV. List. |
ssh |
--ssh |
SSH agents to forward into the build (default or id=path). List. |
userns |
--userns |
User namespace mode. |
network |
--network |
Network mode during build (host, none, private, name). |
add_host |
--add-host |
Extra host-to-IP mappings (host:ip). List. |
http_proxy |
--http-proxy |
true or false. Whether the host's proxy env vars are passed in. |
unsetenv |
--unsetenv |
Environment variables to unset before building. List. |
pull |
--pull |
Pull policy: always, missing, never, newer. |
Resource limits
| Setting |
podman build flag |
Description |
memory |
--memory |
Memory limit (e.g. 512m, 2g). |
memory_swap |
--memory-swap |
Swap limit. |
cpu_shares |
--cpu-shares |
Relative CPU shares. |
cpu_period |
--cpu-period |
CFS period in microseconds. |
cpu_quota |
--cpu-quota |
CFS quota in microseconds. |
cpuset_cpus |
--cpuset-cpus |
CPUs to allow (e.g. 0-3). |
shm_size |
--shm-size |
/dev/shm size. |
ulimit |
--ulimit |
type=soft:hard entries. List. |
cgroup_parent |
--cgroup-parent |
Optional parent cgroup. |
Security, devices and mounts
| Setting |
podman build flag |
Description |
security_opt |
--security-opt |
Security options (e.g. label=disable). List. |
cap_add |
--cap-add |
Linux capabilities to add. List. |
cap_drop |
--cap-drop |
Linux capabilities to drop. List. |
device |
--device |
Devices to expose to the build (/dev/sda). List. |
volume |
--volume |
Bind-mounts during build (src:dst[:opt]). List. |
decryption_key |
--decryption-key |
Key file(s) to decrypt encrypted base images. List. |
Push
| Setting |
podman push flag |
Description |
compress |
--compression-format |
Layer compression on push (e.g. gzip, zstd, zstd:chunked). |
retry |
(plugin-side loop) |
Number of times to retry on push failure. Implemented as a shell loop because podman manifest push does not support --retry. |
retry_delay |
(plugin-side loop) |
Delay in seconds between retries (integer, no s suffix). |
sign_by |
--sign-by |
GPG key fingerprint for signing the pushed image. |
TLS, logging, escape hatch
| Setting |
Flag(s) |
Description |
tls_verify |
--tls-verify |
Default true. Set to false to disable TLS verification for login, build and push. |
skip_tls_verify |
--tls-verify=false |
Convenience alias for tls_verify: false. |
log_level |
--log-level |
Podman log level. Default info. |
extra_opts |
(passthrough) |
Free-form extra flags appended verbatim to the build command. Whitespace-split. |
Examples
Minimal build and push
steps:
- name: publish
image: head1328/woodpecker-ci-plugin-podman
settings:
repo: head1328/myapp
tags: latest
username:
from_secret: docker_hub_user
password:
from_secret: docker_hub_token
Multi-arch with labels and a cache repo
steps:
- name: publish
image: head1328/woodpecker-ci-plugin-podman
settings:
repo: head1328/myapp
tags: [latest, "1.2.3"]
platforms: linux/amd64,linux/arm64
cache: true
cache_from: [head1328/myapp:cache]
cache_to: [head1328/myapp:cache]
labels:
- org.opencontainers.image.source=https://codeberg.org/head1328/myapp
- org.opencontainers.image.revision=${CI_COMMIT_SHA}
username:
from_secret: docker_hub_user
password:
from_secret: docker_hub_token
Build-time secret and SSH forwarding
steps:
- name: build
image: head1328/woodpecker-ci-plugin-podman
settings:
repo: head1328/myapp
secrets:
- id=npmrc,env=NPM_TOKEN
ssh:
- default
dry_run: true
environment:
NPM_TOKEN:
from_secret: npm_token
Push to multiple registries
steps:
- name: docker-hub
image: head1328/woodpecker-ci-plugin-podman
settings:
repo: head1328/myapp
registry: docker.io
tags: latest
username:
from_secret: docker_hub_user
password:
from_secret: docker_hub_token
- name: codeberg
image: head1328/woodpecker-ci-plugin-podman
settings:
repo: head1328/myapp
registry: codeberg.org
tags: latest
username:
from_secret: codeberg_username
password:
from_secret: codeberg_token