Skip to content

Add libpod API support for Podman via LIBPOD_* environment variables#47

Merged
thespad merged 1 commit into
linuxserver:mainfrom
poupryc:main
Jun 13, 2026
Merged

Add libpod API support for Podman via LIBPOD_* environment variables#47
thespad merged 1 commit into
linuxserver:mainfrom
poupryc:main

Conversation

@poupryc

@poupryc poupryc commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

linuxserver.io

Podman exposes two HTTP API groups on the same socket:

  • Docker-compatible API, the same endpoints as Docker (/containers, /images, etc.), already handled by this proxy 👍
  • libpod-native API, podman-specific endpoints prefixed with /libpod/ (/libpod/pods, /libpod/containers, etc.). This group is required by tools that target Podman directly rather than the Docker compat layer.

Projects like prometheus-podman-exporter cannot be placed behind this proxy because the libpod endpoints are not supported.

This PR adds support for libpod endpoints.


  • I have read the contributing guideline and understand that I have made the correct modifications

Description:

Adds LIBPOD_* environment variables mirroring the existing Docker compat variables, one per libpod endpoint group (LIBPOD_CONTAINERS, LIBPOD_PODS, LIBPOD_IMAGES, LIBPOD_VOLUMES, LIBPOD_NETWORKS, LIBPOD_INFO, LIBPOD_EVENTS, LIBPOD_EXEC, LIBPOD_GENERATE, LIBPOD_MANIFESTS, LIBPOD_PLAY, LIBPOD_SECRETS, LIBPOD_SYSTEM).

LIBPOD_PING=1 and LIBPOD_VERSION=1 are enabled by default, consistent with their Docker compat counterparts.

Adds lifecycle action overrides for libpod containers (LIBPOD_ALLOW_START, LIBPOD_ALLOW_STOP, LIBPOD_ALLOW_RESTARTS, LIBPOD_ALLOW_PAUSE, LIBPOD_ALLOW_UNPAUSE) and Podman-specific pod lifecycle (LIBPOD_ALLOW_POD_START, LIBPOD_ALLOW_POD_STOP, LIBPOD_ALLOW_POD_RESTARTS, LIBPOD_ALLOW_POD_PAUSE, LIBPOD_ALLOW_POD_UNPAUSE), all of which bypass POST=0 just like the Docker compat ALLOW_* vars.

All new variables default to 0 (deny), preserving the existing security posture for Docker-only users.

The current implementation uses one independent env var per libpod endpoint. This is the most conservative and consistent approach (matches the existing Docker compat model).

I also thought about coupled flags via a global LIBPOD=1 — a single LIBPOD flag that, when set to 1, automatically enables the libpod counterpart of any already-enabled Docker compat endpoint. So IMAGES=1 + LIBPOD=1 would implicitly allow /libpod/images. This reduces configuration verbosity for operators who want symmetric access across both API groups, but makes the permission model less explicit.

Benefits of this PR and context:

Add podman compatibility to docker-socket-proxy.

How Has This Been Tested?

This has been tested with prometheus-podman-exporter running under docker-socket-proxy.

Before this PR
[socket-proxy]    | 
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | 
[socket-proxy]    |       ██╗     ███████╗██╗ ██████╗
[socket-proxy]    |       ██║     ██╔════╝██║██╔═══██╗
[socket-proxy]    |       ██║     ███████╗██║██║   ██║
[socket-proxy]    |       ██║     ╚════██║██║██║   ██║
[socket-proxy]    |       ███████╗███████║██║╚██████╔╝
[socket-proxy]    |       ╚══════╝╚══════╝╚═╝ ╚═════╝
[socket-proxy]    | 
[socket-proxy]    |     Brought to you by linuxserver.io
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | 
[socket-proxy]    | To support LSIO projects visit:
[socket-proxy]    | https://www.linuxserver.io/donate/
[socket-proxy]    | 
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | Linuxserver.io version: 3.2.19-r0-ls83
[socket-proxy]    | Build-date: 2026-05-31T10:10:41+00:00
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    |     
[socket-proxy]    | [ls.io-init] done.
[socket-proxy]    | [NOTICE]   (1) : Initializing new worker (6)
[socket-proxy]    | [NOTICE]   (1) : Loading success.
[podman-exporter] | time=2026-06-13T08:35:15.350Z level=INFO source=exporter.go:69 msg="starting podman-prometheus-exporter" version="(version=1.21.0, branch=HEAD, revision=1)"
[podman-exporter] | time=2026-06-13T08:35:15.351Z level=INFO source=exporter.go:70 msg=metrics enhanced=false
[podman-exporter] | time=2026-06-13T08:35:15.352Z level=INFO source=handler.go:96 msg="enabled collectors"
[podman-exporter] | time=2026-06-13T08:35:15.352Z level=INFO source=handler.go:107 msg=collector name=container
[podman-exporter] | time=2026-06-13T08:35:15.352Z level=INFO source=handler.go:107 msg=collector name=image
[podman-exporter] | time=2026-06-13T08:35:15.352Z level=INFO source=handler.go:107 msg=collector name=network
[podman-exporter] | time=2026-06-13T08:35:15.352Z level=INFO source=handler.go:107 msg=collector name=pod
[podman-exporter] | time=2026-06-13T08:35:15.352Z level=INFO source=handler.go:107 msg=collector name=system
[podman-exporter] | time=2026-06-13T08:35:15.352Z level=INFO source=handler.go:107 msg=collector name=volume
[socket-proxy]    | ::ffff:10.89.0.3:40908 [13/Jun/2026:08:35:15.374] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[podman-exporter] | 2026/06/13 08:35:15 unable to connect to Podman socket: ping response was 403
[socket-proxy]    | ::ffff:10.89.0.4:33000 [13/Jun/2026:08:35:16.356] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.5:41234 [13/Jun/2026:08:35:17.349] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.6:33822 [13/Jun/2026:08:35:18.352] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.7:45104 [13/Jun/2026:08:35:19.345] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.8:58992 [13/Jun/2026:08:35:20.332] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.9:48566 [13/Jun/2026:08:35:21.340] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.10:39112 [13/Jun/2026:08:35:22.313] proxy proxy/<NOSRV> 0/-1/-1/-1/0 403 192 - - PR-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"

With this PR With the following env :
LIBPOD_CONTAINERS: 1
LIBPOD_INFO: 1
LIBPOD_NETWORKS: 1
LIBPOD_PODS: 1
LIBPOD_VOLUMES: 1
LIBPOD_IMAGES: 1
LIBPOD_EVENTS: 1
[socket-proxy]    |
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | 
[socket-proxy]    |       ██╗     ███████╗██╗ ██████╗
[socket-proxy]    |       ██║     ██╔════╝██║██╔═══██╗
[socket-proxy]    |       ██║     ███████╗██║██║   ██║
[socket-proxy]    |       ██║     ╚════██║██║██║   ██║
[socket-proxy]    |       ███████╗███████║██║╚██████╔╝
[socket-proxy]    |       ╚══════╝╚══════╝╚═╝ ╚═════╝
[socket-proxy]    | 
[socket-proxy]    |     Brought to you by linuxserver.io
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | 
[socket-proxy]    | To support LSIO projects visit:
[socket-proxy]    | https://www.linuxserver.io/donate/
[socket-proxy]    | 
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    | Linuxserver.io version: 
[socket-proxy]    | Build-date: 
[socket-proxy]    | ───────────────────────────────────────
[socket-proxy]    |     
[socket-proxy]    | [ls.io-init] done.
[socket-proxy]    | [NOTICE]   (1) : Initializing new worker (6)
[socket-proxy]    | [NOTICE]   (1) : Loading success.
[podman-exporter] | time=2026-06-13T08:09:37.984Z level=INFO source=exporter.go:69 msg="starting podman-prometheus-exporter" version="(version=1.21.0, branch=HEAD, revision=1)"
[podman-exporter] | time=2026-06-13T08:09:37.984Z level=INFO source=exporter.go:70 msg=metrics enhanced=false
[podman-exporter] | time=2026-06-13T08:09:37.990Z level=INFO source=handler.go:96 msg="enabled collectors"
[podman-exporter] | time=2026-06-13T08:09:37.990Z level=INFO source=handler.go:107 msg=collector name=container
[podman-exporter] | time=2026-06-13T08:09:37.991Z level=INFO source=handler.go:107 msg=collector name=image
[podman-exporter] | time=2026-06-13T08:09:37.991Z level=INFO source=handler.go:107 msg=collector name=network
[podman-exporter] | time=2026-06-13T08:09:37.991Z level=INFO source=handler.go:107 msg=collector name=pod
[podman-exporter] | time=2026-06-13T08:09:37.991Z level=INFO source=handler.go:107 msg=collector name=system
[podman-exporter] | time=2026-06-13T08:09:37.991Z level=INFO source=handler.go:107 msg=collector name=volume
[socket-proxy]    | ::ffff:10.89.0.3:45978 [13/Jun/2026:08:09:38.007] proxy docker/socket 0/0/0/140/140 200 339 - - ---- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/_ping HTTP/1.1"
[podman-exporter] | time=2026-06-13T08:09:38.148Z level=INFO source=container.go:241 msg="starting container size cache ticker" duration=3600
[podman-exporter] | time=2026-06-13T08:09:38.148Z level=INFO source=container.go:242 msg="update container size cache"
[podman-exporter] | time=2026-06-13T08:09:38.149Z level=INFO source=events.go:16 msg="starting podman event streamer"
[socket-proxy]    | ::ffff:10.89.0.3:45996 [13/Jun/2026:08:09:38.152] proxy docker/socket 0/0/0/23/23 200 3182 - - ---- 2/2/1/1/0 0/0 "GET /v5.8.1/libpod/containers/json?all=true&external=false&last=0&namespace=false&size=true&sync=false HTTP/1.1"
[podman-exporter] | time=2026-06-13T08:09:38.176Z level=INFO source=exporter.go:99 msg="Listening on" addresses=[:9882]
[podman-exporter] | time=2026-06-13T08:09:38.184Z level=INFO source=tls_config.go:354 msg="Listening on" address=[::]:9882
[podman-exporter] | time=2026-06-13T08:09:38.184Z level=INFO source=tls_config.go:357 msg="TLS is disabled." http2=false address=[::]:9882
[socket-proxy]    | ::ffff:10.89.0.3:45994 [13/Jun/2026:08:09:38.152] proxy docker/socket 0/0/0/57/57 200 9112 - - ---- 2/2/0/0/0 0/0 "GET /v5.8.1/libpod/images/json?all=true&filters=%7B%7D HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56828 [13/Jun/2026:08:09:53.083] proxy docker/socket 0/0/0/3/3 200 1007 - - ---- 6/6/3/3/0 0/0 "GET /v5.8.1/libpod/networks/json HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56826 [13/Jun/2026:08:09:53.085] proxy docker/socket 0/0/0/12/12 200 3114 - - ---- 6/6/4/4/0 0/0 "GET /v5.8.1/libpod/containers/json?all=true&external=false&last=0&namespace=false&size=false&sync=false HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56824 [13/Jun/2026:08:09:53.084] proxy docker/socket 0/0/0/15/15 200 767 - - ---- 6/6/3/3/0 0/0 "GET /v5.8.1/libpod/pods/json HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56854 [13/Jun/2026:08:09:53.087] proxy docker/socket 0/0/0/14/14 200 203 - - ---- 6/6/2/2/0 0/0 "GET /v5.8.1/libpod/volumes/json HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56826 [13/Jun/2026:08:09:53.101] proxy docker/socket 0/0/0/8/8 200 1348 - - ---- 5/5/2/2/0 0/0 "GET /v5.8.1/libpod/containers/stats?all=false&interval=1&stream=false HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56828 [13/Jun/2026:08:09:53.087] proxy docker/socket 0/0/0/477/477 200 3579 - - ---- 4/4/1/1/0 0/0 "GET /v5.8.1/libpod/info HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56854 [13/Jun/2026:08:09:56.267] proxy docker/socket 0/0/0/2/2 200 1007 - - ---- 5/5/3/3/0 0/0 "GET /v5.8.1/libpod/networks/json HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56868 [13/Jun/2026:08:09:56.266] proxy docker/socket 1/0/0/8/9 200 203 - - ---- 6/6/4/4/0 0/0 "GET /v5.8.1/libpod/volumes/json HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56854 [13/Jun/2026:08:09:56.271] proxy docker/socket 0/0/0/9/9 200 3114 - - ---- 6/6/3/3/0 0/0 "GET /v5.8.1/libpod/containers/json?all=true&external=false&last=0&namespace=false&size=false&sync=false HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:44818 [13/Jun/2026:08:09:56.270] proxy docker/socket 0/0/0/11/11 200 767 - - ---- 5/5/3/3/0 0/0 "GET /v5.8.1/libpod/pods/json HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:56868 [13/Jun/2026:08:09:56.281] proxy docker/socket 0/0/0/9/9 200 1354 - - ---- 5/5/2/2/0 0/0 "GET /v5.8.1/libpod/containers/stats?all=false&interval=1&stream=false HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:44802 [13/Jun/2026:08:09:56.269] proxy docker/socket 0/0/0/433/433 200 3579 - - ---- 4/4/1/1/0 0/0 "GET /v5.8.1/libpod/info HTTP/1.1"
[socket-proxy]    | ::ffff:10.89.0.3:45994 [13/Jun/2026:08:09:38.212] proxy docker/socket 0/0/0/38/645022 200 2424 - - sD-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/events?filters=%7B%7D&since=&stream=true&until= HTTP/1.1"
[podman-exporter] | time=2026-06-13T08:20:23.237Z level=ERROR source=events.go:48 msg="podman received event not ok"
[podman-exporter] | time=2026-06-13T08:30:23.286Z level=ERROR source=events.go:48 msg="podman received event not ok"
[socket-proxy]    | ::ffff:10.89.0.3:60656 [13/Jun/2026:08:20:23.249] proxy docker/socket 0/0/0/35/600035 200 209 - - sD-- 1/1/0/0/0 0/0 "GET /v5.8.1/libpod/events?filters=%7B%7D&since=&stream=true&until= HTTP/1.1"

Source / References:

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this pull request! Be sure to follow the pull request template!

@github-project-automation github-project-automation Bot moved this from PRs to PRs Approved in Issue & PR Tracker Jun 13, 2026
@thespad thespad merged commit 19bcac7 into linuxserver:main Jun 13, 2026
3 checks passed
@LinuxServer-CI LinuxServer-CI moved this from PRs Approved to Done in Issue & PR Tracker Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

3 participants