Chapter 9: Podman as a service
This chapter introduces Podman’s Linux-only service as a way for programs, Docker-based tools, and remote Podman commands to manage containers.
After this chapter you will be able to
- Purpose of the Podman service. Explain why someone might use the Podman service instead of only the command line: it lets code and remote systems interact with containers through an API. State that the service runs on Linux and supports rootless and rootful modes.
- Podman service endpoints. Describe how `podman system service` creates a listening REST API service in rootful or rootless mode, and how an optional URI selects a UNIX domain socket or TCP socket. State that the default is a UNIX domain socket under `/run`.
- Service versus centralized daemon. Distinguish the optional Podman service from Docker’s centralized daemon: Podman commands and other container tools can work with its containers, images, and storage without going through the service.
- Remote access security. Explain why exposing the Podman service on a TCP socket calls for caution: the service has no built-in authorization or additional protection against unauthorized access, so the section recommends SSH for remote access.
- On demand service lifetime. Describe how the service exits five seconds after its last connection by default, remains running while connections are active, and uses `--time` to change that timeout; `--time 0` keeps it running until stopped. Explain that most users rely on systemd services rather than starting it directly.
- On-demand Podman service lifecycle. Explain how systemd listens on a UNIX domain socket, launches the Podman service when a client connects, and hands it the socket. Describe how the service handles requests and exits after five seconds without another connection, rather than remaining a long-running daemon.
- Rootless socket startup and test. Describe enabling and starting the Podman socket with systemd's --user option for rootless mode, then checking that podman.sock appears in XDG_RUNTIME_DIR. Explain that systemd is listening even though no Podman process is yet running, and that a curl version request can trigger and test the service.
- API roles and choice. Distinguish the Docker compatibility API from the native Libpod API, and explain when to choose each: Libpod for new Podman-specific code, or compatibility for legacy Docker-based code and code intended to work with both engines.
- Endpoint behavior for images and pods. Describe how a curl request selects the Libpod API using the libpod URL field or the Docker API by omitting it. Explain why an image-list request can return the same JSON through either API, while a pod-list request works through Libpod but returns Not Found through the Docker endpoint.
- Python library API pairing. Distinguish docker-py, which works with Podman’s compatibility API, from podman-py, which supports the newer Libpod API.
- Docker-py compatibility with Podman. Explain that docker-py, originally written for the Docker daemon, can use Podman’s compatibility API to work with containers from Python. State that advanced Podman features require podman-py instead.
- Podman socket connection methods. Describe how a docker-py script can point its DockerClient URL at the Podman socket, or set DOCKER_HOST to that socket and use docker.from_env(). Explain how the environment-variable approach avoids hard-coding the socket path in the script.
- Podman-py and Libpod API. Explain that podman-py is a Python bindings library for the Podman service and, unlike the docker-py example, uses the Libpod API to support Podman’s advanced features.
- Automatic Podman socket selection. Describe how podman-py connects to the default podman.sock without the script specifying its location: non-root Python uses /run/user/$UID/podman/podman.sock, while root Python uses /run/podman/podman.sock.
- Python library choice. Explain that docker-py is the choice for an application that must work with both Docker and Podman, while podman-py is needed for advanced Podman features. Describe podman-py as modeled on docker-py to ease transition, but still under heavy development compared with docker-py's large installed base.
- Podman service compatibility. Explain that docker-compose uses docker-py and the Docker REST API, so Podman’s compat REST API lets Compose launch Podman containers, including rootless containers.
- Compose service setup and lifecycle. Describe preparing the Podman socket-activated service and DOCKER_HOST, defining the example in docker-compose.yaml, then launching, checking, stopping, and removing its resources.
- Remote service communication. Explain that `podman --remote` lets a Podman command manage containers through a socket-activated Podman service using its REST API, rather than executing containers as children of the local Podman process.
- Default local socket connection. Explain that podman --remote connects to the local podman.socket by default and can manage containers through the Podman system service. Describe how its version output reports both client and server versions, which are the same executable in this local example.
- Remote command execution path. Trace how podman --remote connects from a local client over SSH to a remote Podman service, which is reached through systemd socket activation and a REST API. Explain that the familiar Podman commands act on pods and containers on the server, although some options are unsupported in remote mode.
- Remote server service preparation. Describe the server-side requirements before issuing remote client commands: run the SSH daemon, enable the podman.sock systemd socket, and, for rootless Podman, enable user lingering so the socket remains available and listens after boot. Distinguish that the linger step is only for rootless mode, not the rootful service.
- Remote Podman SSH authentication. Explain that remote Podman uses SSH when the client and server are on separate machines, and describe how to set up key-based authentication: generate or reuse a key pair on the client and add its public key to the server's authorized_keys file.
- Remote Podman connection setup. Describe how to add a named connection with podman system connection add, supplying the full SSH URL for the remote user’s Podman socket. Explain that Podman can use the default SSH identity file or one specified with --identity.
What it builds on
- Working with containers (chapter 2) · Introduces managing containers from the Podman command line.
- Podman is daemonless (chapter 1) · Podman’s daemonless operation.
- Podman containers as systemd services (chapter 7) · The use of systemd services to manage Podman processes.
- Socket-activated Podman containers (chapter 7) · The concept of systemd socket activation.
- Generating Podman pods and containers from Kubernetes YAML (chapter 8) · Using Kubernetes YAML with podman play kube
Section by section
Introduction
This chapter introduces Podman’s Linux-only service as a way for programs, Docker-based tools, and remote Podman commands to manage containers.
- Purpose of the Podman service: Explain why someone might use the Podman service instead of only the command line: it lets code and remote systems interact with containers through an API. State that the service runs on Linux and supports rootless and rootful modes.
Why it matters: The service is the foundation for the programming and remote-management options introduced in this chapter. - Docker tool and Python integration: Describe the chapter’s plan to use docker-py and podman-py with the Podman service and to connect Docker-based tools such as docker-compose without a Docker daemon.
Why it matters: Existing code and tools are a major reason to expose Podman through a service. - Remote Podman command connections: Explain that the Podman command’s --remote option can communicate with a local or remote Podman service, and that the chapter will cover configuring connections and managing SSH communication for remote use.
Why it matters: Configured remote connections make it practical to manage a Podman service on another machine.
Key terms: Podman service, REST API, rootless, rootful, docker-py, podman-py, docker-compose, Docker daemon, --remote, Podman connections
9.1 Introducing the Podman service
This section introduces Podman’s API service, where it listens, how it differs from a centralized daemon, and how it is secured and managed.
- Podman service endpoints: Describe how `podman system service` creates a listening REST API service in rootful or rootless mode, and how an optional URI selects a UNIX domain socket or TCP socket. State that the default is a UNIX domain socket under `/run`.
Why it matters: The listening endpoint determines how clients connect to the service. - Service versus centralized daemon: Distinguish the optional Podman service from Docker’s centralized daemon: Podman commands and other container tools can work with its containers, images, and storage without going through the service.
Why it matters: Using Podman’s API does not make the API service the mandatory gateway to containers. - Remote access security: Explain why exposing the Podman service on a TCP socket calls for caution: the service has no built-in authorization or additional protection against unauthorized access, so the section recommends SSH for remote access.
Why it matters: An exposed API service can grant access to Podman operations without protecting itself from unauthorized callers. - On demand service lifetime: Describe how the service exits five seconds after its last connection by default, remains running while connections are active, and uses `--time` to change that timeout; `--time 0` keeps it running until stopped. Explain that most users rely on systemd services rather than starting it directly.
Why it matters: On-demand operation avoids consuming resources with an idle, long-running service.
Key terms: REST API, podman system service, URI, UNIX domain socket, TCP socket, rootful, Podman service, centralized daemon, datastore, authorization
9.1.1 Systemd services
This section explains how systemd socket activation runs the Podman API service on demand and how to start and test the rootless socket.
- On-demand Podman service lifecycle: Explain how systemd listens on a UNIX domain socket, launches the Podman service when a client connects, and hands it the socket. Describe how the service handles requests and exits after five seconds without another connection, rather than remaining a long-running daemon.
Why it matters: This explains how Podman offers an API service without requiring an always-running daemon. - Rootful and rootless sockets: Distinguish the two podman.socket unit files supplied by the Podman package: one for rootful service and one for rootless service. State that each directs systemd to listen on its default UNIX domain socket.
Why it matters: The choice of socket determines which mode of Podman clients reach. - Rootless socket startup and test: Describe enabling and starting the Podman socket with systemd's --user option for rootless mode, then checking that podman.sock appears in XDG_RUNTIME_DIR. Explain that systemd is listening even though no Podman process is yet running, and that a curl version request can trigger and test the service.
Why it matters: Starting and testing the socket prepares you to interact with the Podman APIs in the rest of the chapter.
Key terms: systemd socket activation, podman system service, UNIX domain socket, podman.socket, rootful Podman, rootless Podman, --user, podman.sock, XDG_RUNTIME_DIR, curl
9.2 Podman-supported APIs
This section explains Podman’s two REST APIs, when to use each, and how their endpoints behave differently over the same service socket.
- API roles and choice: Distinguish the Docker compatibility API from the native Libpod API, and explain when to choose each: Libpod for new Podman-specific code, or compatibility for legacy Docker-based code and code intended to work with both engines.
Why it matters: Choosing the right API determines whether your code can use Podman-specific features or remain compatible with Docker. - Endpoint behavior for images and pods: Describe how a curl request selects the Libpod API using the libpod URL field or the Docker API by omitting it. Explain why an image-list request can return the same JSON through either API, while a pod-list request works through Libpod but returns Not Found through the Docker endpoint.
Why it matters: The endpoint examples show where Docker compatibility ends and Podman’s native features begin.
Key terms: compatibility API, Docker API, Libpod API, Swarm APIs, curl, jq, libpod field, JSON, pods, Not Found
9.3 Python libraries for interacting with Podman
This section introduces two Python libraries for interacting with Podman and identifies the API each uses.
- Python library API pairing: Distinguish docker-py, which works with Podman’s compatibility API, from podman-py, which supports the newer Libpod API.
Why it matters: The API pairing helps you follow the examples for each library.
Key terms: docker-py, podman-py, compatibility API, Libpod API
9.3.1 Using docker-py with the Podman API
This section shows how existing docker-py scripts can use Podman’s Docker-compatible API by connecting to the Podman service socket.
- Docker-py compatibility with Podman: Explain that docker-py, originally written for the Docker daemon, can use Podman’s compatibility API to work with containers from Python. State that advanced Podman features require podman-py instead.
Why it matters: This helps you decide when an existing Docker-based Python tool can work with Podman and when you need a different library. - Podman socket connection methods: Describe how a docker-py script can point its DockerClient URL at the Podman socket, or set DOCKER_HOST to that socket and use docker.from_env(). Explain how the environment-variable approach avoids hard-coding the socket path in the script.
Why it matters: Pointing the client at the right socket lets a Python script reach the Podman service without rewriting its container operations. - Docker-py installation and socket shortcut: State that docker-py can be installed through distribution packages or PyPI, and describe the optional podman-docker package’s Docker-command redirection and rootful docker.sock-to-podman.sock link.
Why it matters: These setup options can make existing Docker commands and tools easier to use with Podman.
Key terms: docker-py, Podman compat API, podman-py, DockerClient, podman.sock, DOCKER_HOST, docker.from_env(), python-docker, podman-docker, docker.sock
9.3.2 Using podman-py with the Podman API
This section shows how podman-py connects Python programs to the Podman service and uses the Libpod API to access images and pods.
- Podman-py and Libpod API: Explain that podman-py is a Python bindings library for the Podman service and, unlike the docker-py example, uses the Libpod API to support Podman’s advanced features.
Why it matters: The API choice determines which Podman features a Python program can use. - Automatic Podman socket selection: Describe how podman-py connects to the default podman.sock without the script specifying its location: non-root Python uses /run/user/$UID/podman/podman.sock, while root Python uses /run/podman/podman.sock.
Why it matters: Automatic socket selection simplifies the script while changing which service it reaches based on who runs it. - Python image and pod examples: Describe installing podman-py through the python-podman package, running a podman-images.py script for results like the docker-py example, and using pod.lists() to iterate through pods for Podman-specific information.
Why it matters: The examples show how the bindings can grow from an image script into a Python client for Podman.
Key terms: podman-py, docker-py, Libpod API, Podman service, podman.sock, rootless socket, /run/user/$UID/podman/podman.sock, /run/podman/podman.sock, python-podman, podman-images.py
9.3.3 Which Python library should you use?
This section compares docker-py and podman-py to help readers choose a Python library for Podman, then connects those libraries to higher-level container tools.
- Python library choice: Explain that docker-py is the choice for an application that must work with both Docker and Podman, while podman-py is needed for advanced Podman features. Describe podman-py as modeled on docker-py to ease transition, but still under heavy development compared with docker-py's large installed base.
Why it matters: The library you choose determines which container engines and Podman features your application can use. - Podman service connection differences: Distinguish how the libraries connect to the Podman service: podman-py works out of the box with rootful and rootless services, while docker-py requires DOCKER_HOST to point to podman.socket.
Why it matters: The connection setup affects how readily each library can be used with a Podman service. - Libraries beneath orchestration tools: Describe docker-py and podman-py as low-level libraries for communicating with container engines, and identify docker-compose as a popular higher-level tool developed to orchestrate and manage containers.
Why it matters: This places the Python libraries in the wider tooling stack before the discussion of docker-compose.
Key terms: docker-py, podman-py, rootful, rootless, DOCKER_HOST, podman.socket, docker-compose
9.4 Using docker-compose with the Podman service
This section shows how docker-compose uses the Podman service to launch and manage containers defined in a Compose YAML file.
- Compose and Kubernetes scope: Distinguish Compose’s single-node, multi-container orchestration from Kubernetes’ multi-node orchestration, and explain why a YAML file is easier to use than complex container command lines.
Why it matters: This explains when an existing Compose file is useful and why the section uses one. - Podman service compatibility: Explain that docker-compose uses docker-py and the Docker REST API, so Podman’s compat REST API lets Compose launch Podman containers, including rootless containers.
Why it matters: API compatibility lets an existing Docker-oriented tool work with Podman. - Compose service setup and lifecycle: Describe preparing the Podman socket-activated service and DOCKER_HOST, defining the example in docker-compose.yaml, then launching, checking, stopping, and removing its resources.
Why it matters: The sequence separates connecting Compose to Podman from checking and cleaning up what Compose creates.
Key terms: docker-compose, compose, Kubernetes YAML, compose YAML, docker-py, Docker REST API, compat REST API, rootless, rootful, systemd socket-activated service
9.5 podman - -remote
This section introduces Podman’s remote client mode, which manages containers through a Podman service rather than running them directly, and explains how that mode supports non-Linux clients.
- Remote service communication: Explain that `podman --remote` lets a Podman command manage containers through a socket-activated Podman service using its REST API, rather than executing containers as children of the local Podman process.
Why it matters: This distinction explains how one client can manage container environments on other machines. - Remote client builds: Distinguish the full Linux Podman executable, which includes `--remote`, from the client-only build called `podman-remote`; describe how the latter lets Mac and Windows clients communicate with a Podman service in a VM or on another machine.
Why it matters: The client-only build makes Podman commands usable on systems that cannot run the full Linux container engine.
Key terms: podman --remote, socket-activated Podman service, REST API, podman-remote, client mode, VM
9.5.1 Local connections
This section shows how podman --remote connects to the local Podman service and explains why that mode is mainly useful for API testing.
- Default local socket connection: Explain that podman --remote connects to the local podman.socket by default and can manage containers through the Podman system service. Describe how its version output reports both client and server versions, which are the same executable in this local example.
Why it matters: The local connection establishes what --remote does before you use it with another machine. - Purpose of local connections: Justify why a local --remote connection adds little for ordinary container management but is useful for testing the API, especially in continuous integration systems.
Why it matters: This distinction helps you choose local API testing rather than treating --remote as necessary for everyday local commands.
Key terms: podman --remote, podman.socket, local connection, Podman client, Podman server, local connections, API, continuous integration (CI) systems
9.5.2 Remote connections
This section explains how podman --remote reaches a Podman service over SSH and how to prepare the remote server for rootless connections.
- Remote command execution path: Trace how podman --remote connects from a local client over SSH to a remote Podman service, which is reached through systemd socket activation and a REST API. Explain that the familiar Podman commands act on pods and containers on the server, although some options are unsupported in remote mode.
Why it matters: The commands can feel local even though the container processes run on another machine. - Remote server service preparation: Describe the server-side requirements before issuing remote client commands: run the SSH daemon, enable the podman.sock systemd socket, and, for rootless Podman, enable user lingering so the socket remains available and listens after boot. Distinguish that the linger step is only for rootless mode, not the rootful service.
Why it matters: Remote commands need both an SSH entry point and an available Podman service on the server.
Key terms: podman --remote, SSH, Podman service, systemd socket activation, REST API, SSHD daemon, podman.sock, rootless Podman, enable-linger, rootful podman service
9.5.3 Setting up SSH on the client machine
This section explains how to prepare SSH authentication on the client and server before configuring a remote Podman connection.
- Remote Podman SSH authentication: Explain that remote Podman uses SSH when the client and server are on separate machines, and describe how to set up key-based authentication: generate or reuse a key pair on the client and add its public key to the server's authorized_keys file.
Why it matters: Key-based SSH authentication avoids a login-password prompt for every remote Podman command.
Key terms: SSH, SSH key pair, ssh-copy-id, id_ed25519.pub, authorized_keys
9.5.4 Configuring a connection
This section shows how to save an SSH connection to a remote Podman socket, then select and test that connection for remote commands.
- Remote Podman connection setup: Describe how to add a named connection with podman system connection add, supplying the full SSH URL for the remote user’s Podman socket. Explain that Podman can use the default SSH identity file or one specified with --identity.
Why it matters: A saved connection lets subsequent Podman commands reach containers on a Linux server or VM over SSH. - Connection defaults and selection: Explain that the first added connection becomes the default, that podman system connection list marks the default with an asterisk, and that podman info can test the connection. Describe using --connection (-c) to choose a non-default connection when several exist.
Why it matters: Checking and selecting connections helps ensure remote commands reach the intended server.
Key terms: podman system connection add, SSH URL, Podman socket, --identity, SSH keys, podman system connection list, default connection, podman info, --connection, -c
9.6 Summary
The summary recaps how Podman’s service supports Docker-compatible and Podman-native clients, Compose, and remote management over SSH.
Concepts explained in this chapter
- podman system serviceThe Podman compatibility service is a background Podman endpoint that accepts Docker-compatible container-management requests.
- remote Podman clientA Podman client is the command-line or programmatic client component that sends container-management requests to a Podman service.
- podman-pyThe python-podman package is a distributable package that installs the podman-py Python client library.
- podman.socketpodman.socket is a systemd socket unit that listens for Podman service connections and activates the corresponding service.
- remote modeRemote mode is an operating mode in which a Podman client sends container-management requests to a Podman service running on another system or through a local service socket.
- docker-pydocker-py is a Python client library that provides bindings for the Docker API and compatible container-management APIs.
- socket activationA socket-activated service is a service that is started when a connection arrives on a listening socket and may exit while idle.
- Docker ComposeDocker Compose is a tool for defining and running multi-container applications.
- YAMLYAML is a human-readable data-serialization standard commonly used for configuration and resource manifests.
- PodmanPodman is a daemonless container engine that runs containers and builds images, including under an unprivileged user account.
- RESTA REST API is a network interface that exposes resources and operations through HTTP using representational state transfer conventions.
- rootful modeA rootful container is a container whose engine or processes run with host-level root privileges.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
