Resource limits, health checks, automatic updates, and the Buildah/Skopeo toolchain: move from merely running containers to keeping them under control.
Resource Limits: Memory and CPU#
Memory Limits
# 限制容器最多用 256MB 内存
podman run -d --memory=256m --name web docker.io/library/nginx:alpine
# └──────────┘
# 可加单位:b/k/m/g(字节/KB/MB/GB)
# 限制内存 + 交换分区(总共 512M,其中 256M 是 RAM + 256M swap)
podman run -d --memory=256m --memory-swap=512m docker.io/library/nginx:alpine
# 查看容器实际内存使用
podman stats web
# 输出类似:
# ID NAME CPU% MEM USAGE / LIMIT MEM% NET IO BLOCK IO
# abc web 0.2% 18.2MB / 256MB 7.1% 1.2kB / 0B 0B / 0BCPU Limits
# 限制总CPU时间配额相当于1.5个逻辑CPU,不固定在哪些核运行
podman run -d --cpus=1.5 docker.io/library/nginx:alpine
# 绑定到特定 CPU 核心(只用 CPU 0 和 CPU 1)
podman run -d --cpuset-cpus=0,1 docker.io/library/nginx:alpine
# 设置 CPU 权重(默认 1024,值越小优先级越低)
podman run -d --cpu-shares=512 docker.io/library/nginx:alpineSetting Resource Limits in Quadlet
[Container]
Image=docker.io/library/nginx:alpine
ContainerName=web
[Service]
MemoryMax=256M
CPUQuota=150%
# 150% = 1.5 个核心
[Container]
PublishPort=8080:80Health Checks#
Tell Podman "how to determine whether this container is healthy."
# 运行时指定
podman run -d \
--health-cmd="wget -q -O /dev/null http://127.0.0.1/ || exit 1" \
--health-interval=30s \
--health-timeout=5s \
--health-retries=3 \
--health-start-period=60s \
docker.io/library/nginx:alpine
# 参数含义:
# --health-cmd 检查命令,exit 0 表示健康
# --health-interval 多久检查一次
# --health-timeout 单次检查的超时时间
# --health-retries 连续失败多少次才标记为 unhealthy
# --health-start-period 启动宽限期,早期失败通常不计入阈值,不表示完全不检查View health status:
podman ps --format "table {{.Names}} {{.Status}}"
# 输出可能包含 "(healthy)" 或 "(unhealthy)"Automatic Container Updates#
Enable Automatic Updates
# 启动时加 auto-update 标签
podman run -d \
--label "io.containers.autoupdate=registry" \
--name web \
docker.io/library/nginx:alpine
# --label ... 只声明更新策略;自动更新还需systemd管理关联与timer/手动调用
# 手动触发所有有标签容器的更新
podman auto-update
# 输出类似:
# UNIT IMAGE POLICY UPDATED
# web.service docker.io/library/nginx:alpine registry false
# ↑ false 表示此次未更新;结合策略和完整结果判断,不能独立证明所有服务最新Set Up a Timer for Automatic Checks
# 启用用户级timer;实际周期由timer配置决定
systemctl --user enable --now podman-auto-update.timer
# 查看 timer 状态和下一次触发时间
systemctl --user list-timers podman-auto-update.timerQuadlet version (recommended):
[Container]
Image=docker.io/library/nginx:alpine
AutoUpdate=registry
# 自动启动的定时器会检查这个容器Buildah: The Underlying Image-Building Tool#
Buildah is Podman's "build sibling." podman build uses Buildah's build functionality/libraries; it does not invoke the buildah CLI as an additional process every time.
When to Use Buildah Directly
# 1. 需要脚本化构建(不用 Dockerfile)
buildah from docker.io/library/alpine:latest # 创建工作容器
buildah run alpine-working-container -- apk add python3 # 在里面执行命令
buildah commit alpine-working-container mypython:latest # 保存为镜像
# 2. CI/CD 中构建镜像(无 daemon 开销)
buildah bud -t myapp:latest . # bud = build using Dockerfile
# 3. 查看已存在的镜像层
buildah imagesFor most scenarios, keep using podman build. Buildah is aimed at advanced users and CI systems.
Skopeo: The Image Transfer Specialist#
Skopeo is used to copy, inspect, and sign images across registries without first pulling them locally.
# 查看远程镜像的详细信息(不下载)
skopeo inspect docker://docker.io/library/nginx:alpine
# 在不同仓库之间复制镜像(直接复制,不经过本地存储)
skopeo copy \
docker://docker.io/library/nginx:alpine \
docker://registry.example.com/library/nginx:alpine
# 复制到本地目录
skopeo copy \
docker://docker.io/library/nginx:alpine \
dir:/tmp/nginx-local
# 同步镜像(批量复制)
skopeo sync --src docker --dest dir \
docker.io/library/nginx:alpine \
/tmp/synced-imagesUse cases: move your images from Docker Hub to a private registry, or distribute images offline.
Network Debugging#
# 查看容器的 IP 地址
podman inspect web | grep IPAddress
# 查看容器的 DNS 配置
podman exec web cat /etc/resolv.conf
# 测试容器间网络连通性
podman exec web ping db
# 同一自定义网络中的容器可以用容器名互相访问
# 查看 iptables/nftables 规则(rootful 模式)
sudo nft list ruleset | grep podmanLog Management#
# journalctl 是 systemd 的日志工具
# 查看容器日志
journalctl --user -u nginx
# 最近 50 行
journalctl --user -u nginx -n 50
# 实时跟踪
journalctl --user -u nginx -f
# 只看今天的
journalctl --user -u nginx --since today
# 按时间段
journalctl --user -u nginx --since "2026-06-20 10:00" --until "2026-06-20 12:00"
Set the rate policy in the Quadlet source file's [Service] section. This is a rate limit, not a maximum log size. On NixOS, manage it through declarative configuration:
[Service]
LogRateLimitIntervalSec=0
# 0禁用此服务的速率限制,可能增加日志量;容量由journald保留策略等控制Resource Monitoring with cgroups v2#
# 查看容器的 cgroup 信息
podman inspect web --format '{{.HostConfig.CgroupParent}}'
# 查看内存使用(系统级)
systemd-cgtop
# 按 cgroup 分组显示 CPU/内存/IO,可以看到每个容器的实时资源用量
# 查看容器的 cgroup 限制是否生效
podman exec web cat /sys/fs/cgroup/memory.max
# 输出:268435456 = 256MB(和 --memory=256m 对应)Podman Machine(macOS/Windows)#
If you develop on macOS:
# 初始化一个 Podman 管理的 Linux VM
podman machine init
# 启动 VM
podman machine start
# 查看 VM 状态
podman machine list
# 进入 VM shell(调试用)
podman machine ssh
# 停止/删除 VM
podman machine stop
podman machine rmPodman Machine's VM provider varies by platform and version. Check the installed version rather than applying one provider or a fixed performance comparison to all versions 5.0 and later. machine rm deletes the VM; export any data you need to keep first.
Cleanup Strategies: Preventing a Full Disk#
# 查看存储使用
podman system df
# 删除所有未使用的镜像、容器、卷(一键清理)
podman system prune -a --volumes
# └┘ └──────┘
# 包括未使用 包括未使用的卷
# 的镜像
# 定期自动清理(加到 crontab 或 systemd timer)
podman image prune -f --filter "until=72h"
# 删除 72 小时前创建的未使用镜像Limit Total Storage Size
In ~/.config/containers/storage.conf:
[storage]
driver = "overlay"
runroot = "/run/user/EXAMPLE_UID/containers" # 示例不可直接复制,通常保留默认
graphroot = "/path/to/local-container-storage" # 受控本地路径示例,迁移需单独处理
[storage.options.overlay]
size = "50G" # 特定驱动/文件系统支持的层配额,不是整个graphroot总容量限制Troubleshooting Quick Reference#
| Symptom | Check |
|---|---|
| Container exits immediately after starting | Use podman logs <容器> to find the reason for the exit |
| Port mapping does not work | Check the starting port for unprivileged binds, then confirm the published IP/port and the application's listening address; check the firewall next |
| Volume mount permission denied | Check the application's UID mapping, directory and parent-directory permissions, ACLs, and SELinux |
| Slow image pulls | Configure registry mirrors: ~/.config/containers/registries.conf |
| Containers cannot communicate | Confirm they are on the same custom network; test with podman exec <容器> ping <另一个容器> |
| Memory usage keeps growing | Inspect with podman stats; a --memory limit may be missing |
| Container state is lost after a reboot | Check whether Quadlet/systemd is used. Distinguish persistent data, restart policy, and the user manager at boot; Quadlet/systemd require the appropriate Install and linger conditions |
Prerequisites for Operational Checks#
In rootless environments, resource limits depend on the cgroup version and delegation permissions. Even after successful creation, read the actual limits and observe the workload. Health commands run inside the image, and the example requires wget to be available. An unhealthy status does not automatically trigger systemd's Restart policy; configure a separate mechanism such as HealthOnFailure. auto-update restarts services through their systemd association; a run label alone is not a complete update solution. The registry policy should use fully qualified image names.
The cleanup examples delete unused resources, and --volumes in particular can cause database data loss. Inventory resources with system df, ps -a, and volume inspect, and back them up first. Automatic prune should not be treated as a risk-free default. The until filter for image prune uses creation time; “unused” and “old” are different conditions. Skopeo inspect does not download complete image layers, but it still contacts the registry and retrieves metadata. copy writes to the destination registry and requires authorization and authentication. Logs and inspect output may contain secrets such as environment variables; redact them before sharing.
References & further reading
- Official Podman run manual ↗
- Official Podman overview and rootless documentation ↗
- Podman automatic-update requirements ↗
- Container storage configuration ↗
- Official Buildah documentation ↗
- Official Skopeo documentation ↗
Adapted from technical notes. Examples use generic names.
Continue along a reading path
Podman container workflows
- 01Podman fundamentals
- 02A basic Podman usage guide
- 03Rootless containers: whose file permissions count?
- 04Rootless configuration: mappings, ICMP, and registries
- 05Pods and Kubernetes manifests
- 06How does Quadlet turn container declarations into services?
- 07Pods and multi-service configuration with Quadlet
- 08Compose providers and interoperability with Docker tools
- 09Managing Podman on NixOS
- 10Advanced Podman operations and tuning
- 11Docker and Podman: architecture, compatibility, and coexistence