跳转至

Quadlet(服务)

podman|385x358, 50%

Quadlet 使用场景

Quadlet 是 podman 的一项功能,允许用户将容器作为 systemd 单元运行。它使用类似 docker compose 的声明式语法,但集成到 systemd 中并以 podman 作为后端。

Quadlet 可用于以容器打包的应用,例如服务器应用。你可以在 Linux Server 找到大量容器化应用示例。

管理 Quadlet

Quadlet 可以像其它 systemd 服务一样使用以下命令管理。

检查 Quadlet 状态

systemctl --user status <service>

停止 Quadlet

systemctl --user stop <service>

你可以在 man systemctl 或 tldr systemctl 中查看更多命令。

Note

与 systemctl 交互时不要添加 .container 后缀,否则会出错。

Quadlet 文件位置

你可以将 quadlet 放在以下位置,按优先级排序:

  • $XDG_RUNTIME_DIR/containers/systemd/ - 通常用于临时 quadlet
  • ~/.config/containers/systemd/ - 推荐位置
  • /etc/containers/systemd/users/$(UID)
  • /etc/containers/systemd/users/

Note

如果你希望服务在未登录时也能启动,请运行 loginctl enable-linger $USER 使其自动启动。

开机运行 Quadlet

你可能希望 quadlet 在开机时自动运行,只需在 quadlet 文件中添加 install 部分即可实现自动启动。大多数情况下 default.target 就是你需要的,但如果需要其它 target,可以查阅 systemd 文档。

[Install]
WantedBy=default.target

将 Docker Compose 转换为 Quadlet 单元

你会发现网上大多数容器化应用都是使用 docker compose 构建的。即使是上面链接的 Linux Server,所有容器也都用 compose 文件记录。因此,在作为 quadlet 运行之前,你需要先进行转换。幸运的是,你可以使用 podlet 来帮助完成转换。

Note

默认情况下 quadlet 需要完整的仓库名称。大多数镜像位于 docker hub,因此需添加 docker.io/(例如 "nginxinc/nginx-unprivileged" 变为 "docker.io/nginxinc/nginx-unprivileged")。

以 Rootful 容器运行 Quadlet

虽然理想情况下你应该使用 rootless podman 运行所有容器,但遗憾的是并非所有容器都能与之配合。使用 rootful podman 时,需要使用不同的 quadlet 路径,并通过 root systemctl(不带 --user)运行。

Rootful Quadlet 路径 - /run/containers/systemd/ - 临时 quadlet - /etc/containers/systemd/ - 推荐位置 - /usr/share/containers/systemd/ - 镜像定义

常用 Quadlet 键说明

选项 示例 说明
ContainerName ContainerName=nginx 容器名称。
Image Image=docker.io/nginxinc/nginx-unprivileged 你要使用的容器镜像。
AutoUpdate AutoUpdate=registry 检查更新的来源。值为 registry 或 local。
PublishPort PublishPort=8080:8080 容器开放的端口。(主机端口:容器端口)
Volume Volume=/path/to/data:/data:z 将主机文件夹与容器文件夹关联。(主机文件夹:容器文件夹:选项)
Network Network=host 容器使用的网络。值可以是 host、none 或用户自定义的网络名称

Note

Volume 中的 z 选项用于防止 SELinux 阻止对文件夹的访问。更多信息请阅读这里。

故障排查

如果你的 quadlet 由于某种原因未找到或未启动,可以使用 /usr/libexec/podman/quadlet -dryrun(系统 quadlet)或 /usr/libexec/podman/quadlet -user -dryrun(用户 quadlet)调试容器单元。

示例

Quadlet 用法的实际示例。

Minecraft 服务器托管

Note

创建文件后别忘了运行 systemctl --user daemon-reload

文档:https://docker-minecraft-server.readthedocs.io/en/latest Quadlet 文件:

# ~/.config/containers/systemd/minecraft.container
[Container]
ContainerName=minecraft
Environment=EULA=TRUE
Image=docker.io/itzg/minecraft-server
AutoUpdate=registry
PublishPort=25565:25565
Volume=/path/to/data:/data:z

# Remove if you don't want autostart
[Install]
WantedBy=default.target

Note

Volume 请使用绝对路径,例如 /home/username/minecraft/data。

NGINX Web 服务器

创建名为 ~/.config/containers/systemd/nginx.container 的文件,内容如下:

[Container]
ContainerName=nginx
Image=docker.io/nginxinc/nginx-unprivileged
AutoUpdate=registry
PublishPort=8080:8080

保存后运行以下命令。

systemctl --user daemon-reload
systemctl --user start nginx
xdg-open localhost:8080

Plex 媒体服务器

文档:https://github.com/plexinc/pms-docker Quadlet 文件:

# ~/.config/containers/systemd/plex.container
[Container]
ContainerName=plex
Environment=TZ=Your/TimeZone
Image=docker.io/plexinc/pms-docker
AutoUpdate=registry
Network=host
Volume=/path/to/config:/config:z
Volume=/path/to/transcode:/transcode:z
Volume=/path/to/media:/data:z

# Remove if you don't want autostart
[Install]
WantedBy=default.target

Note

你可以在这里找到时区列表。

Note

Volume 请使用绝对路径,例如 /home/username/plex/config。

Note

可以为媒体挂载多个 volume,例如 Volume=/path/to/media:/tv:z 和 Volume=/path/to/another/media:/movie:z。更多信息请查阅文档。

视频教程

https://www.youtube.com/watch?v=xTVFmvyZGpg

Samba 服务器

文档:https://github.com/ServerContainers/samba Quadlet 文件:

# /etc/containers/systemd/samba.container
[Container]
Environment=ACCOUNT_username=password
# Protected share with write access
Environment="SAMBA_VOLUME_CONFIG_protected=[My Share]; path=/shares/protected; valid users = username; guest ok = no; read only = no; browseable = yes"
# Open share with readonly access
Environment="SAMBA_VOLUME_CONFIG_guest=[Guest Share]; path=/shares/guest; guest ok = yes; browseable = yes"
Image=ghcr.io/servercontainers/samba:smbd-only-latest
AutoUpdate=registry
Network=host
Volume=/path/to/protected:/shares/protected:z
Volume=/path/to/guest:/shares/guest:z

# Remove if you don't want autostart
[Install]
WantedBy=default.target

Note

你可以在这里找到时区列表。

Note

Volume 请使用绝对路径,例如 /home/username/samba/guest。

实用链接

  • https://podman.io/
  • https://docs.podman.io/en/stable/markdown/podman-systemd.unit.5.html
  • https://www.redhat.com/en/blog/quadlet-podman