Featured image of post 【podman】podman generate systemd踩坑总结

【podman】podman generate systemd踩坑总结

每日一言

一年中和一生中的秋天,时光很短暂,但是更加晴朗而缺少变化。—— 人生的智慧


博客加载caddy默认页面

昨天在查看部署在zz.ac上的博客blog.bosh.zz.ac的时候,发现打开的是caddy的默认页面 image.png

尝试其他服务:

alist站点 能够正常加载: image.png 高清壁纸 能够正常加载: image.png

ssh登录zz.ac主机,查看caddy服务:

1
systemctl --user status container-my-caddy.service

image.png

查看所有系统服务:

1
 systemctl --user list-units --type=service

image.png

真是奇怪了 :

container-my-caddy.service loaded failed failed caddy.service loaded active running

container-my-caddy.service 是我上次部署运行了container-my-caddy.service 生成的,加载失败。

caddy.service,这个服务是那里来的?我没有设置过这个服务啊!

显然现在caddy的服务是由这个服务提供的,目前的情况是alist和pic能够正常加载,blog不能加载,先查查为什么会有这种情况。

再研究为什么我让自动生成的服务加载失败了,却多出来了一个我没有设置过的服务。

为什么alist和pic能够正常加载,blog不能加载

查看这个addy.service状态:

1
2
3
systemctl --user status caddy.service
 caddy.service - Caddy Server Container
     Loaded: loaded (/home/bosh/.config/containers/systemd/caddy.container; generated)

查看配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
[Unit]
Description=Caddy Server Container
After=network-online.target

[Container]
Image=docker.io/library/caddy:latest
ContainerName=my-caddy
# 使用主机网络
Network=host
# 挂载你的配置文件和数据
Volume=%h/Caddyfile:/etc/caddy/Caddyfile:Z
# 如果有静态网页文件,也可以挂载
#Volume=/home/bosh/blog/public_html:/srv:Z

[Service]
# 重启策略
Restart=always

[Install]
# 随着用户会话启动
WantedBy=default.target

可以看出,这个静态网站配置这里

1
#Volume=/home/bosh/blog/public_html:/srv:Z

这里把静态文件屏蔽了

删除屏蔽,修改配置:

1
Volume=/home/bosh/blog/public_html:/srv:Z

重新加载还是caddy的默认页面。

再看服务文件中:挂载的配置文件和数据

1
Volume=%h/Caddyfile:/etc/caddy/Caddyfile:Z

映射的是我的/home下的Caddyfile文件如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 1. 博客静态站 (静态文件)
http://blog.bosh.zz.ac:8080 {
    # 必须是容器内路径
    root * /usr/share/caddy
    # 开启静态文件服务
    file_server
    # 开启日志方便调试
    log {
        output stdout
    }
}

这里可以看到/;

静态服务的roor映射的是容器的/usr/share/caddy 我当时部署caddy的时候,映射关系是这样的

1
/home/bosh/blog/public_html:/usr/share/caddy

这就诡异了!

仔细看

1
Volume=/home/bosh/blog/public_html:/srv:Z

这里的映射关系:

1
2
主机:/home/bosh/blog/public_html:
容器内:/srv

尝试把Caddyfile的配置中的映射关系改一下:

1
 root * /srv

重新加载caddy服务:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
bosh@h1:~/blog/public_html$ systemctl --user restart caddy
bosh@h1:~/blog/public_html$ systemctl --user status caddy
 caddy.service - Caddy Server Container
     Loaded: loaded (/home/bosh/.config/containers/systemd/caddy.container; generated)
     Active: active (running) since Sun 2026-01-11 02:33:03 UTC; 18s ago
 Invocation: 81ff05fb127f452aa77ff6fb2a736b4e
   Main PID: 33595 (conmon)
      Tasks: 10 (limit: 28650)
     Memory: 12M (peak: 15.4M)
        CPU: 127ms

强制刷新blog.zz.ac

博客居然加载出来!!!! 测试其他服务,加载正常!

到这里,blog加载的是默认页面的问题解决了。

为什么我会多出来一个caddy服务?我自己部署的container-my-caddy.service 为什么会加载失败呢?

查询container-my-caddy.service 运行日志,启动失败的原因是8800 端口被caddy.service 占用的原因。

核心问题:这个caddy.service 是怎么产生的?

经过让Gemini沟通我的部署过程和分析运行日志,总结如下:

  1. 产生的原因:是执行了 podman generate systemd –new,它产生了一个硬编码了错误路径的 .service 文件,并在重启时通过 –new 机制强制创建了一个“干净但配置错误”的新容器,覆盖了你之前的配置。
  1. Podman 处理“容器开机自启”和“服务化管理”的两代技术:podman generate systemd 是过去式,而 Quadlet(.container 文件)是现在和未来。
  1. podman generate systemd(旧款:快照式)
  • 这是 Podman 早期的做法。它的逻辑是:你先手动运行一个容器,然后通过命令给这个容器“拍张照片”,把它的运行参数转化成一个巨大的 systemd 脚本。缺> 点(坑点):
  • 僵化性:它是一个“死”的脚本。如果你修改了宿主机的目录,或者想改环境变量,你必须删除旧文件、重新运行容器、再次生成文件。代
  • 码冗长:生成的文件包含大量复杂的 shell 指令(ExecStart, ExecStop 等),普通人很难看懂和维护。
  • 易冲突:就像你刚才遇到的,一旦容器名冲突,这种脚本经常导致启动失败(Start-limit-hit)。
  1. Quadlet(新款:声明式):
  • 这是 Podman 4.4 版本后引入的现代方案,它让 Podman 像 Docker Compose 一样好用,同时完美融入 systemd。
  • 工作原理: 你只需要写一个简洁的配置文件(.container 文件),告诉 Podman 你想要什么(镜像名、挂载路径、网络)。剩下的所有复杂逻辑(如何启动、如何停止),由 Podman 自动帮你完成。
  • 存放位置:~/.config/containers/systemd/
  • 优点:
  • 简洁明了:文件内容非常像 INI 格式或 Compose 格式。
  • 自动生产:你只要运行 systemctl –user daemon-reload,Podman 的生成器就会自动在后台“生产”出服务文件。
  • 动态更新:你想改配置?直接修改 .container 文件,然后 reload 即可。不需要重新运行复杂的 podman run 命令。

总结:

删除所有 ~/.config/systemd/user/ 下带 container- 前缀的 .service 文件。

今后管理podman 容器的自启动和后台运行,管理:~/.config/containers/systemd/ 下的 .container 文件。 .container 模板如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[Unit]
Description=Caddy Web Server (Quadlet)
After=network-online.target

[Container]
# 1. 镜像设置
Image=docker.io/library/caddy:latest
ContainerName=my-caddy

# 2. 网络设置 (根据你之前的需求,使用主机网络)
Network=host

# 3. 自动更新 (配合 podman-auto-update 服务使用)
Annotation=io.containers.autoupdate=image

# 4. 挂载配置文件
# %h 是 systemd 变量,指向你的家目录 /home/bosh
# :Z 用于处理 SELinux 标签(如果你开启了 SELinux)
Volume=%h/Caddyfile:/etc/caddy/Caddyfile:Z

# 5. 挂载博客静态文件
Volume=%h/blog/public_html:/srv:Z

# 6. 持久化 Caddy 内部数据(防止证书和密钥丢失)
# 建议创建这两个目录:mkdir -p ~/caddy_data ~/caddy_config
Volume=%h/caddy_data:/data:Z
Volume=%h/caddy_config:/config:Z

# 7. 资源限制(可选,防止容器占用过多内存)
Memory=512M

[Service]
# 失败后自动重启
Restart=always
# 停止容器前等待的时间
TimeoutStopSec=70

[Install]
# 随用户登录自动启动
WantedBy=default.target

进入容器查看文件:

1
2
3
4
podman exec -it my-caddy sh
/srv # ls
CNAME           archives        content.json    draft           index.html      lib             page            posts           search.xml      我的第一篇博客
about           categories      css             images          js              links           photos          preset          tags

容器的默认工作目录是/srv,里面加载的是blog的的静态文件。

这个容器是系统重写了配置的,可能的原因就是因为之前用了podman generate systemd --new的原因。

知识有限,只能分析到这里了!

😄 😄 😄 😄 😄

热爱生活 学无止境
使用 Hugo 构建
主题 StackJimmy 设计