🧑🏻‍💻 博世

【podman】podman generate systemd踩坑总结

每日一言

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

博客加载caddy默认页面

昨天在查看部署在zz.ac上的博客blog.bosh.zz.ac的时候,发现打开的是caddy的默认页面 image.png ### 尝试其他服务: alist站点 能够正常加载: image.png 高清壁纸 能够正常加载: image.png ### ssh登录zz.ac主机,查看caddy服务:

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

image.png ### 查看所有系统服务:

 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状态:

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

查看配置文件:

```cat /home/bosh/.config/containers/systemd/caddy.container [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

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

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

这里把静态文件屏蔽了
        ### 删除屏蔽,修改配置:

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

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

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

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

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

1. 博客静态站 (静态文件)

http://blog.bosh.zz.ac:8080 { # 必须是容器内路径 root * /usr/share/caddy # 开启静态文件服务 file_server # 开启日志方便调试 log { output stdout } }

#### 这里可以看到/;
        静态服务的roor映射的是容器的/usr/share/caddy
        我当时部署caddy的时候,映射关系是这样的

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

这就诡异了!

        仔细看

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

这里的映射关系:

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

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

root * /srv

#### 重新加载caddy服务:

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 机制强制创建了一个“干净但配置错误”的新容器,覆盖了你之前的配置。

        > 2. Podman 处理“容器开机自启”和“服务化管理”的两代技术:podman generate systemd 是过去式,而 Quadlet(.container 文件)是现在和未来。

        > 3. podman generate systemd(旧款:快照式)
        > - 这是 Podman 早期的做法。它的逻辑是:你先手动运行一个容器,然后通过命令给这个容器“拍张照片”,把它的运行参数转化成一个巨大的 systemd 脚本。缺> 点(坑点):
        > - 僵化性:它是一个“死”的脚本。如果你修改了宿主机的目录,或者想改环境变量,你必须删除旧文件、重新运行容器、再次生成文件。代
        > - 码冗长:生成的文件包含大量复杂的 shell 指令(ExecStart, ExecStop 等),普通人很难看懂和维护。
        > - 易冲突:就像你刚才遇到的,一旦容器名冲突,这种脚本经常导致启动失败(Start-limit-hit)。

        > 4. 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 模板如下:

[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

## 进入容器查看文件:

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`的原因。 ## 知识有限,只能分析到这里了! # :smile: :smile: :smile: :smile: :smile: