手邊題材用盡了,只好拿案子最初的學習筆記來講。沒有Quadlet的Podman,將容器註冊成服務的動作完全與~/.config/containers/systemd這個目錄無關。
以下是用Spring Boot開發的電文模擬程式的Dockerfile,放在Spring Boot專案主目錄下。
FROM openjdk:8-jdk-alpine
RUN apk add --no-cache tzdata
ENV TZ=Asia/Taipei
EXPOSE 8080
ARG JAR_FILE=target/simulator-0.0.1-SNAPSHOT.jar
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
JAR_FILE指向target子目錄下的jar檔,這要事先在主目錄執行過打包(mvn clean packge)才會產生jar檔。
接著後面的動作,對常用Docker開發的同學應該老生常談了。
包成image:(以下指令沒指定CPU結構是當時我的筆電還沒換成Apple M4)
podman build -t esbsimulator:latest .
將image轉出tar檔
podman save -o EsbSimulator.tar esbsimulator:latest
丟到標的主機匯入
podman load -i EsbSimulator.tar
接著是在不用Quadlet功能下如何把image轉生為systemd的service。分別執行一下指令:
$ podman create --name EsbSimulator -p 18080:8080 esbsimulator:latest
6567ded1f9320b385db7819736500ba949c00370aa869096d5e3f925d0847ff2
所產出的ID是容器ID,可以用podman ps -a查看。
$ podman generate systemd --new --files --name EsbSimulator
DEPRECATED command:
It is recommended to use Quadlets for running containers and pods under systemd.
Please refer to podman-systemd.unit(5) for details.
/home/appuser/container-EsbSimulator.service
最終會產生一個.service檔給systemctl使用,內容就與/run/user/<uid>/systemd/generator下的.service類似。會出現「DEPRECATED command」訊息是RedHat建議最好使用Quadlet來建服務。
當時是在root權限下操作,所以把container-EsbSimulator.service這個檔手動放到/etc/systemd/system目錄下再執行systemctl daemon-reload,因為是root,不用加--user參數。
以下是root權限對EsbSimulator.service生效並啟動的操作。
% systemctl is-enabled container-EsbSimulator.service
disabled
# --now參數等同systemctl enable service-name && systemctl start service-name
% sudo systemctl enable --now container-EsbSimulator.service
Created symlink /etc/systemd/system/default.target.wants/container-EsbSimulator.service → /etc/systemd/system/container-EsbSimulator.service.
% systemctl is-enabled container-EsbSimulator.service
enabled
% systemctl status container-EsbSimulator.service
● container-EsbSimulator.service - Podman container-EsbSimulator.service
Loaded: loaded (/etc/systemd/system/container-EsbSimulator.service; enabled; preset: disabled)
Active: active (running) since Fri 2026-01-16 09:46:17 CST; 4min 28s ago
Docs: man:podman-generate-systemd(1)
Main PID: 113081 (conmon)
Tasks: 1 (limit: 100212)
Memory: 1.5M (peak: 20.0M)
CPU: 238ms
CGroup: /system.slice/container-EsbSimulator.service
└─113081 /usr/bin/conmon --api-version 1 -c 5b72a46149c04e9fc92f977efeb77c7f6f204029f20c2598e1c7723c5692
% systemctl stop container-EsbSimulator.service
% systemctl status container-EsbSimulator.service
× container-EsbSimulator.service - Podman container-EsbSimulator.service
Loaded: loaded (/etc/systemd/system/container-EsbSimulator.service; enabled; preset: disabled)
Active: failed (Result: exit-code) since Fri 2026-01-16 09:54:50 CST; 2s ago
Duration: 8min 32.451s
Docs: man:podman-generate-systemd(1)
Process: 113081 ExecStart=/usr/bin/podman run --cidfile=/run/container-EsbSimulator.service.ctr-id --cgroups=no-con>
Process: 113132 ExecStop=/usr/bin/podman stop --ignore -t 10 --cidfile=/run/container-EsbSimulator.service.ctr-id (>
Process: 113205 ExecStopPost=/usr/bin/podman rm -f --ignore -t 10 --cidfile=/run/container-EsbSimulator.service.ctr>
Main PID: 113081 (code=exited, status=143)
CPU: 468ms
做成服務之後,在podman ps -a就看不到container了。
那在rootless呢?
systemctl --user enable container-EsbSimulator.service
systemctl --user start container-EsbSimulator.service
systemctl --user status container-EsbSimulator.service
systemctl --user stop container-EsbSimulator.service
在執行systemctl --user enable container-EsbSimulator.service後,systemd會將container-EsbSimulator.service這個單元檔記錄在啟動清單內。重開機時會自動啟動,所以徹底移除的方式如下:
停用服務:
$ systemctl --user disable container-EsbSimulator.service
Removed "/home/appuser/.config/systemd/user/default.target.wants/container-EsbSimulator.service".
這會取消開機自動啟動,但不會刪除檔案。這裡可以反推執行systemctl enable的動作就是把.service檔放放到.config/systemd/user/default.target.wants目錄下。
停止服務:
systemctl --user stop container-EsbSimulator.service
如果服務正在執行,這會立即停止容器。
刪除檔案:
由於.service 檔案是 Podman 產生的,你可以直接刪除它:
rm /home/appuser/container-EsbSimulator.service
這樣 systemd 就不會再找到這個單元檔。
重新載入systemd:
刪除或修改單元檔後,記得執行:
systemctl --user daemon-reload
讓 systemd 更新它的單元檔快取。