OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 123

Quadlet 的 Pod 与多服务配置

补充 Pod、数据库、API 和代理资源的完整依赖模板。

所在专题Podman 容器工作流 ↗
约 10 分钟阅读开始阅读

先阅读 Quadlet 服务生命周期,了解生成、加载、启动、日志、持久化与开机条件。本篇保留 Pod 和完整多服务配置的深入示例。

环境变量与敏感信息#

[Container]
Image=docker.io/library/mariadb:11
ContainerName=mariadb

EnvironmentFile=%h/.config/private/mariadb.env
Environment=MYSQL_DATABASE=myapp
Environment=MYSQL_USER=user
# 每行一个环境变量,等于 podman run -e KEY=VALUE

# 安全做法:从文件加载敏感信息
# 受限文件提供 MYSQL_ROOT_PASSWORD 与 MYSQL_PASSWORD,避免明文写进资源源文件
# %h = 用户家目录

网络与端口

[Container]
Image=docker.io/library/nginx:alpine

# 映射到宿主机指定 IP(只本机可访问)
PublishPort=127.0.0.1:8080:80

# 替代示例:省略宿主IP会发布所有接口,需要明确的访问与防火墙政策
# PublishPort=8080:80

# 加入自定义网络
Network=mynet.network

# 或加入 Pod
Pod=myapp.pod

.pod 文件:Pod 声明式定义#

~/.config/containers/systemd/myapp.pod:

[Pod]
PodName=myapp
PublishPort=127.0.0.1:8080:80
# Pod 暴露的端口,里面所有容器共享

.container 文件中引用 Pod:

[Container]
Image=docker.io/library/nginx:alpine
ContainerName=web
Pod=myapp.pod
# 这个容器加入 myapp Pod,共享网络

多容器应用:数据库、API 与代理#

以 Nginx 反向代理 + Python API + PostgreSQL 为例。

文件结构

~/.config/containers/systemd/
├── appnet.network       # 共享网络
├── pgdata.volume        # PostgreSQL 数据卷
├── app-pg.container     # PostgreSQL 容器
├── app-api.container    # Python API 容器
└── app-web.container    # Nginx 反向代理

appnet.network

[Network]
Driver=bridge

pgdata.volume

[Volume]

app-pg.container

[Unit]
Description=App PostgreSQL
# After= 和 Requires= 是 systemd 依赖声明
# After=   → 启动顺序(xx 先启动)
# Requires= → 强依赖(xx 启动失败则本服务不会启动)

[Container]
ContainerName=app-pg
Image=docker.io/library/postgres:16-alpine
Network=appnet.network
Volume=pgdata.volume:/var/lib/postgresql/data:Z

EnvironmentFile=%h/.config/private/postgres.env
Environment=POSTGRES_DB=appdb

# 健康检查:用 pg_isready 确认数据库就绪
HealthCmd=pg_isready -U postgres || exit 1
Notify=healthy
HealthInterval=10s
HealthStartPeriod=30s
# HealthStartPeriod — 早期失败通常不计入重试阈值,不是完全停止检查

[Service]
Restart=on-failure
# on-failure — 只在异常退出时重启(exit code ≠ 0 时)

[Install]
WantedBy=default.target

app-api.container

[Unit]
Description=App API Server
After=app-pg.service
Requires=app-pg.service
# After 只按 unit 状态排序;这里配合 PG 的 Notify=healthy 等待有效检查
# Requires 与 After 组合拉起依赖并约束启动失败;不等于持续应用健康依赖

[Container]
ContainerName=app-api
Image=registry.example.com/demo/myapi:latest
Network=appnet.network
PublishPort=127.0.0.1:3000:3000

EnvironmentFile=%h/.config/private/api.env
# 文件中提供与数据库匹配的 DATABASE_URL;示例主机字段为 app-pg
# 用容器名 app-pg 连接 PG,因为它们在同一个自定义网络中

HealthCmd=curl -f http://localhost:3000/health || exit 1
HealthInterval=15s

[Service]
Restart=on-failure

[Install]
WantedBy=default.target

app-web.container

[Unit]
Description=App Nginx Proxy
After=app-api.service
Requires=app-api.service

[Container]
ContainerName=app-web
Image=docker.io/library/nginx:alpine
Network=appnet.network
PublishPort=127.0.0.1:8080:80

Volume=%h/.config/nginx/app.conf:/etc/nginx/conf.d/default.conf:ro,Z
# %h = 用户家目录,ro = 只读挂载

[Service]
Restart=on-failure

[Install]
WantedBy=default.target

部署

# 把所有文件放入目录
ls ~/.config/containers/systemd/

# 一键加载并启动
systemctl --user daemon-reload
systemctl --user start app-web   # 启动最外层
# systemd 自动按依赖顺序:先启动 PG → 再 API → 最后 Nginx

# 各源文件通过 [Install] 声明目标关联;未登录启动另需管理员linger政策
# 不 enable 生成 unit;各源文件 [Install] 的 WantedBy 由 generator 处理

# 查看整体状态
systemctl --user status app-pg app-api app-web

模板的前置条件与边界#

这些代码块分别表示独立文件;镜像 registry.example.com/demo/myapi:latest 是需替换的无效示例,API 镜像必须提供 curl、健康端点与数据库连接重试。Nginx 配置文件需要自行准备,将 upstream 指向 app-api:3000;示例没有把未定义的应用称为可直接部署成品。EnvironmentFile 需存在、权限受限,且只按应用格式存放变量,不进入 git/Nix store;环境变量本身也可被有权限的进程检查者读取。

.volume 引用提供独立数据生命周期,.network 提供名称解析;SELinux 的 Z 仅对专用目录使用。Pod 文件可用于需要共享 localhost 的容器,不应与已有 bridge 多服务方案机械混搭;同 Pod 端口共用且可能冲突。HealthCmd 在容器内执行,Notify=healthy 需要所安装版本支持;应用就绪与持续健康恢复需分别设计。

自动更新、linger、generator 检查与撤销服务流程统一见生命周期文章;不要对生成的 service 执行 enable。

参考与延伸

  1. Podman 官方 run 手册 ↗
  2. Podman 官方总览与 rootless ↗
  3. Quadlet 官方语法 ↗
  4. Quadlet 容器健康与通知 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

Podman 容器工作流

  1. 01Podman 基础原理
  2. 02Podman 基本使用指南
  3. 03Rootless 容器,文件权限到底算谁的?
  4. 04Rootless 配置:映射、ICMP 与注册表
  5. 05Pod 体系与 Kubernetes 清单
  6. 06Quadlet 如何把容器声明变成服务?
  7. 07Quadlet 的 Pod 与多服务配置
  8. 08Compose provider 与 Docker 工具互操作
  9. 09NixOS 上的 Podman 管理
  10. 10Podman 高级运维与调优
  11. 11Docker 与 Podman:架构、兼容与共存
CONTINUE READING / 下一篇Compose provider 与 Docker 工具互操作

分开 Compose 实现、Podman wrapper 和兼容 API socket 的职责。