OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 120

A basic Podman usage guide

Learn commands for installation, images, containers, volumes, networks, and everyday maintenance.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSPodman container workflows ↗
About 5 min readStart reading

From installation to everyday operations, every command is explained. If you have used Docker, most commands only require changing the name.


Installing Podman#

Installation commands by distribution

# Fedora / RHEL / AlmaLinux(是否预装取决于镜像与版本)
sudo dnf install podman

# Ubuntu(22.04 及以上)
sudo apt update && sudo apt install -y podman

# Arch Linux
sudo pacman -Syu podman

# openSUSE
sudo zypper install podman

# macOS
brew install podman
podman machine init    # 首次需要创建 Linux VM
podman machine start   # 启动 VM 后才能用 podman 命令

Verify after installation:

podman version     # 显示版本信息
podman info        # 显示完整系统信息(内核版本、存储驱动、rootless 状态等)
podman system df   # 查看磁盘使用情况

If you use NixOS: see Part 7: NixOS Management in Practice.


Working with images#

An "image" is a blueprint for a container, much like an application’s installation package.

Searching for and pulling images

# 搜索镜像(列出可用的 nginx 镜像)
podman search nginx

# 搜索镜像并限制结果数量
podman search nginx --limit 10

# 搜索符合特定条件的镜像(只看官方镜像)
podman search nginx --filter=is-official=true

# 从 Docker Hub 拉取镜像(这里使用完整名称,避免短名解析歧义)
podman pull docker.io/library/nginx:alpine
#           │     └─ 标签(版本),alpine 表示基于 Alpine Linux 的精简版
#           └─────── 镜像名

# 从指定仓库拉取
podman pull docker.io/library/nginx:latest
#           └────────────────────┘ └──┘ └─────┘
#                  仓库地址          镜像   标签
#                                   名

# 一次性拉取并运行
podman run docker.io/library/nginx:alpine

Inspecting and managing images

# 列出本机所有镜像
podman images
# 输出列:REPOSITORY(来源) TAG(版本) IMAGE ID(唯一标识) CREATED SIZE

# 只列出指定镜像
podman images nginx

# 查看镜像的详细信息和各层
podman inspect docker.io/library/nginx:alpine

# 查看镜像的修改历史(每一层做了什么)
podman history docker.io/library/nginx:alpine

# 删除镜像
podman rmi docker.io/library/nginx:alpine
# 如果镜像正被某个容器使用,需要加 -f 强制删除
podman rmi -f docker.io/library/nginx:alpine

# 清理所有未使用的镜像(释放磁盘空间)
podman image prune -a
# -a 表示删除所有未使用的镜像;不加 -a 只删除"悬空"镜像(标签为 <none> 的)

Building your own image

# 从当前目录的 Dockerfile 构建镜像
podman build -t myapp:1.0 .
#           └─┘ └─────┘ └─┘
#      给镜像打标签  镜像名:版本  构建上下文路径

# 构建时指定 Dockerfile 路径
podman build -t myapp:1.0 -f ./docker/Dockerfile .

A minimal Dockerfile example (to help explain what the commands above do):

# 以哪个镜像为基础
FROM docker.io/library/alpine:latest
# 在基础镜像上做什么改动
RUN apk add --no-cache python3
# 把本地文件复制进去
COPY app.py /app/
# 容器启动时执行什么程序
CMD ["python3", "/app/app.py"]

Working with containers#

Running containers (the core command)

# 最简运行
podman run docker.io/library/nginx:alpine

# 后台运行 + 端口映射 + 指定名称
podman run -d --name myweb -p 127.0.0.1:8080:80 docker.io/library/nginx:alpine
#         └┘ └────────┘ └───────┘
#    后台运行  给容器取名   把宿主机的 8080 端口映射到容器的 80 端口
#    (detach)

# 运行后自动删除(一次性任务)
podman run --rm docker.io/library/alpine echo "hello, 我只跑一次就消失"

# 交互式运行(进入容器内 shell)
podman run -it docker.io/library/ubuntu bash
#         └┘└┘
#   交互模式  分配虚拟终端,这样才能看到提示符
# (interactive) (tty)

Quick reference for common run options:

Option Purpose Example
-d Run in the background podman run -d ...
--name Name the container --name myweb
-p Port mapping -p 8080:80 or -p 127.0.0.1:8080:80
-v Mount a directory -v /host/path:/container/path
--rm Automatically remove the container on exit --rm
-e Set an environment variable -e DATABASE_URL=postgres://...
-it Interactive mode + terminal -it
--restart Restart policy --restart=always

Checking container status

# 列出正在运行的容器
podman ps

# 列出所有容器(包括已停止的)
podman ps -a

# 输出含义:
# CONTAINER ID  — 容器唯一 ID(可以用前几位缩写)
# IMAGE         — 从哪个镜像启动的
# COMMAND       — 容器里执行的命令
# CREATED       — 什么时候创建的
# STATUS        — 当前状态(Up X minutes / Exited / Created)
# PORTS         — 端口映射情况
# NAMES         — 容器名称(--name 指定的)

Managing the container lifecycle

# 停止容器(默认停止信号通常是 SIGTERM,也可由镜像/配置指定,超时后强杀)
podman stop myweb

# 立即强杀(发送 SIGKILL,不等待)
podman kill myweb

# 启动已存在的容器(不是新建,是重启之前创建过的)
podman start myweb

# 重启容器
podman restart myweb

# 暂停/恢复容器(暂停期间不消耗 CPU)
podman pause myweb
podman unpause myweb

# 删除已停止的容器
podman rm myweb

# 强制删除(即使容器正在运行)
podman rm -f myweb

# 清理所有已停止的容器
podman container prune

stop vs kill: stop politely asks the program to "please exit," giving it a chance to clean up according to the configured stop signal and timeout (defaults depend on the configuration and version); kill pulls the plug.

Inspecting a container’s internals

# 查看容器内的输出(日志)
podman logs myweb

# 实时跟踪日志(类似 tail -f)
podman logs -f myweb

# 只显示最近 20 行
podman logs --tail 20 myweb

# 进入正在运行的容器内部
podman exec -it myweb sh
#          └┘└┘ └───┘ └──┘
#    交互 终端  容器名  要执行的命令

# 查看容器内运行的进程
podman top myweb

# 查看容器详细信息(JSON 格式,含 IP 地址、挂载点等)
podman inspect myweb

Volumes: persisting data#

Removing a container loses the data in its writable layer; named volumes and bind mounts have different lifecycles. Volumes store data on the host and can be shared across containers.

# 创建命名卷
podman volume create mydata

# 列出所有卷
podman volume ls

# 使用卷:把卷挂载到容器的 /data 目录
podman run -d --name db --env-file /path/to/private/postgres.env \
  -v mydata:/var/lib/postgresql/data docker.io/library/postgres:16
#                               └──┬──┘ └──────────┬──────────┘
#                            宿主机卷名      容器内路径

# 也可以直接挂载宿主机普通目录
podman run -v /path/to/project:/app docker.io/library/nginx:alpine
#           └──────┬──────┘ └─┘
#           宿主机绝对路径   容器内路径

# 查看卷详情
podman volume inspect mydata

# 清理未使用的卷
podman volume prune

Named volumes vs directory mounts (bind mounts):

  • Named volumes are managed by Podman. Rootful volumes are usually in /var/lib/containers/storage/volumes/; the rootless location depends on the user’s storage configuration. Use podman volume inspect to look it up; you do not need to know the path in advance
  • A directory mount specifies a host path directly, making it useful for live code synchronization during development

Networks: connecting containers#

# 列出所有网络
podman network ls

# 创建自定义网络
podman network create mynet

# 查看网络详情(含接入的容器和 IP)
podman network inspect mynet

# 在指定网络中运行容器
podman run -d --name web --network mynet docker.io/library/nginx:alpine
podman run -d --name db --network mynet --env-file /path/to/private/postgres.env docker.io/library/postgres:16

# 同一网络中的容器可以用容器名互相访问
# 若网络 DNS 已启用,通常可解析容器名;ping 工具/ICMP 权限与应用可达性仍需分别检查

# 删除网络
podman network rm mynet

Everyday maintenance commands#

# 查看磁盘使用情况
podman system df      # 总览
podman system df -v   # 详细(每个镜像/容器/卷分别占用多少)

# 一键清理(谨慎!会删除所有未在运行的容器和未使用的镜像)
podman system prune -a

# 查看 Podman 自身日志
podman events    # 实时显示所有容器事件(创建/启动/停止/删除)

# 复制文件:宿主机 → 容器
podman cp /host/file.txt myweb:/container/path/

# 复制文件:容器 → 宿主机
podman cp myweb:/container/path/file.txt /host/dest/

Docker command compatibility#

Common CLI forms are similar, but compatibility is not complete. You can use an alias for familiar basic commands:

# 如果你用过 Docker,直接别名
alias docker=podman

# 此后 docker ps/build 等映射到 Podman;Compose 仍需要外部 provider

Note, however, that the docker command itself may not exist on the system (if Docker is not installed), so the usual approach is:

# 安装 podman-docker 包(会创建 docker → podman 的软链接)
# Fedora
sudo dnf install podman-docker
# Ubuntu
sudo apt install podman-docker
# 之后直接敲 docker 命令,实际调用的是 podman


The installation commands above target mutable distributions; NixOS uses declarations in Nix modules, which an administrator should review and authorize before applying. The database example’s env file must be stored outside the repository with restricted access and supply required values such as POSTGRES_PASSWORD; no valid credentials are provided here. prune, rm, and rmi -f delete resources: inspect dependencies and backups first, as forcibly removing an image may also remove containers that depend on it. A typical port mapping such as -p 8080:80 usually binds to all interfaces; specify loopback explicitly when access should be local only.

References & further reading

  1. Podman Official run Manual ↗
  2. Podman Official Overview and Rootless Documentation ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

Podman container workflows

  1. 01Podman fundamentals
  2. 02A basic Podman usage guide
  3. 03Rootless containers: whose file permissions count?
  4. 04Rootless configuration: mappings, ICMP, and registries
  5. 05Pods and Kubernetes manifests
  6. 06How does Quadlet turn container declarations into services?
  7. 07Pods and multi-service configuration with Quadlet
  8. 08Compose providers and interoperability with Docker tools
  9. 09Managing Podman on NixOS
  10. 10Advanced Podman operations and tuning
  11. 11Docker and Podman: architecture, compatibility, and coexistence
CONTINUE READING / NEXT ARTICLERootless configuration: mappings, ICMP, and registries

Build on the existing permission-boundaries article with administrator configuration and rootless environment requirements.