mirror of
https://github.com/bestnite/quadlet-migrator-skill.git
synced 2026-04-26 19:21:53 +00:00
Compare commits
14 Commits
0bdcd9a2e1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
5babe1fc14
|
|||
|
d2eb13b0d6
|
|||
|
669c3e1703
|
|||
|
349b8ed436
|
|||
|
108e92be4f
|
|||
|
c7dece4a3d
|
|||
|
fdf1a27fe2
|
|||
|
62704d3a2d
|
|||
|
e2372f1b3d
|
|||
|
17c5eb59a8
|
|||
|
068299e9b3
|
|||
|
2f90be67c9
|
|||
|
b719a3c155
|
|||
|
54376c4f62
|
@@ -12,3 +12,4 @@ Thumbs.db
|
|||||||
*.log
|
*.log
|
||||||
*.tmp
|
*.tmp
|
||||||
*.bak
|
*.bak
|
||||||
|
.codex
|
||||||
@@ -2,42 +2,71 @@
|
|||||||
|
|
||||||
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
||||||
|
|
||||||
A skill for migrating `docker run` commands and Docker Compose-style deployments into maintainable Podman Quadlet units.
|
Quadlet Migrator is a skill for converting Docker-based deployment input into Podman Quadlet output.
|
||||||
|
|
||||||
## What it does
|
## What It Does
|
||||||
|
|
||||||
- translates `docker run` and Compose-style inputs into Quadlet-oriented designs
|
- converts `docker run` commands into Quadlet units
|
||||||
- helps decide between `.container`, `.pod`, `.network`, `.volume`, and `.build`
|
- converts Docker Compose setups into Quadlet deployments
|
||||||
- preserves `.env` / `env_file` workflows when appropriate
|
- analyzes self-hosting deployment files in GitHub repositories
|
||||||
- reduces large env templates into a small set of high-impact deployment questions
|
- keeps env files, mounted config, initialization assets, and helper scripts when they are part of the deployment
|
||||||
- explains rootless vs rootful placement, deployment notes, and validation steps
|
- turns large env templates into a short list of deployment decisions
|
||||||
|
- provides deployment, validation, and troubleshooting guidance
|
||||||
|
|
||||||
## Design principles
|
## Installation
|
||||||
|
|
||||||
- prefer the lightest operating mode that matches the request
|
```bash
|
||||||
- separate planning, review, and generation into explicit phases
|
npx skills add bestnite/quadlet-migrator-skill -g
|
||||||
- do not invent deployment-specific values
|
```
|
||||||
- make lossy mappings explicit
|
|
||||||
- prefer maintainable output over mechanical one-to-one translation
|
|
||||||
|
|
||||||
## Operating modes
|
## When To Use It
|
||||||
|
|
||||||
- `advice`: explain mappings or review source inputs without writing final artifacts
|
Use this skill when you want to:
|
||||||
- `design`: perform planning and finalize review, then stop before runnable artifact generation
|
|
||||||
- `generate`: produce approved runnable artifacts after planning and finalize review
|
|
||||||
|
|
||||||
## References
|
- move a service from Docker to Podman Quadlet
|
||||||
|
- convert a Compose stack into a Quadlet layout
|
||||||
|
- review a repository's self-hosting deployment files
|
||||||
|
- generate files for review before installation
|
||||||
|
- validate or troubleshoot generated Quadlet files
|
||||||
|
|
||||||
- `SKILL.md` contains the operating modes, workflow, and high-level rules
|
## How To Use It
|
||||||
- `references/compose-mapping.md` covers field mapping and topology decisions
|
|
||||||
- `references/env-strategy.md` covers env handling and secret defaults
|
|
||||||
- `references/github-repo-intake.md` covers repository discovery and canonical input selection
|
|
||||||
- `references/deployment-notes.md` covers deployment guidance
|
|
||||||
- `references/validation.md` covers validation and troubleshooting
|
|
||||||
|
|
||||||
## Limitations
|
1. Give it an input:
|
||||||
|
- a `docker run` command
|
||||||
|
- a Compose file or Compose project
|
||||||
|
- a GitHub repository URL
|
||||||
|
- existing Quadlet files that need review or cleanup
|
||||||
|
2. Say what you want:
|
||||||
|
- mapping advice
|
||||||
|
- a deployment design
|
||||||
|
- reviewable runnable output
|
||||||
|
3. Confirm deployment-specific values such as domains, host paths, credentials, storage choices, or optional services.
|
||||||
|
4. Review the generated output before applying it.
|
||||||
|
|
||||||
This skill does not claim perfect equivalence between Docker Compose semantics and Podman Quadlet semantics.
|
## Example Requests
|
||||||
|
|
||||||
|
```text
|
||||||
|
Convert this docker run command into Quadlet and explain the mapping.
|
||||||
|
|
||||||
|
Review this compose.yaml and propose a Podman Quadlet layout.
|
||||||
|
|
||||||
|
Generate reviewable Quadlet files from this repository's self-hosting deployment.
|
||||||
|
|
||||||
|
Help me migrate this stack to rootless Podman and keep the env-file workflow.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Typical Output
|
||||||
|
|
||||||
|
- Quadlet unit files
|
||||||
|
- env files or env deltas
|
||||||
|
- helper scripts for install, reload, start, stop, restart, and uninstall
|
||||||
|
- deployment notes and validation guidance
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Review generated output before installation.
|
||||||
|
- Confirm deployment-specific values instead of guessing them.
|
||||||
|
- Call out behavior changes when Docker Compose and Quadlet do not map cleanly.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
+55
-26
@@ -2,42 +2,71 @@
|
|||||||
|
|
||||||
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
||||||
|
|
||||||
一个 skill,用来将 `docker run` 命令和 Docker Compose 风格部署迁移为可维护的 Podman Quadlet 单元。
|
Quadlet Migrator 是一个把 Docker 部署输入转换为 Podman Quadlet 输出的 skill。
|
||||||
|
|
||||||
## 功能概览
|
## 功能
|
||||||
|
|
||||||
- 将 `docker run` 和 Compose 风格输入转换为面向 Quadlet 的设计
|
- 将 `docker run` 命令转换为 Quadlet 单元文件
|
||||||
- 帮助在 `.container`、`.pod`、`.network`、`.volume`、`.build` 之间做选择
|
- 将 Docker Compose 配置转换为 Quadlet 部署结果
|
||||||
- 在合适时保留 `.env` / `env_file` 工作流
|
- 分析 GitHub 仓库中的自托管部署文件
|
||||||
- 将大型 env 模板归纳为少量高影响部署问题
|
- 在部署需要时保留 env 文件、挂载配置、初始化资产和辅助脚本
|
||||||
- 说明 rootless / rootful 放置路径、部署说明与验证步骤
|
- 将庞杂的 env 模板整理成少量部署决策
|
||||||
|
- 提供部署、验证和排障指引
|
||||||
|
|
||||||
## 设计原则
|
## 安装
|
||||||
|
|
||||||
- 优先选择满足需求的最轻运行模式
|
```bash
|
||||||
- 将规划、审阅、生成拆成明确阶段
|
npx skills add bestnite/quadlet-migrator-skill -g
|
||||||
- 不虚构部署相关取值
|
```
|
||||||
- 对有损映射保持显式说明
|
|
||||||
- 优先输出可维护的结果,而不是机械一比一转换
|
|
||||||
|
|
||||||
## 运行模式
|
## 适用场景
|
||||||
|
|
||||||
- `advice`:解释映射方式或审查输入,不写最终产物
|
适合在这些场景中使用:
|
||||||
- `design`:执行 planning 和 finalize 审阅,但在生成可运行产物前停止
|
|
||||||
- `generate`:在 planning 和 finalize 审阅通过后,生成已批准的可运行产物
|
|
||||||
|
|
||||||
## 文档说明
|
- 将服务从 Docker 迁移到 Podman Quadlet
|
||||||
|
- 将 Compose 栈转换为 Quadlet 布局
|
||||||
|
- 审查仓库中的自托管部署文件
|
||||||
|
- 先生成文件审阅,再决定是否安装
|
||||||
|
- 验证或排查生成后的 Quadlet 文件
|
||||||
|
|
||||||
- `SKILL.md`:运行模式、工作流和高层规则
|
## 使用方式
|
||||||
- `references/compose-mapping.md`:Compose 字段映射与拓扑决策
|
|
||||||
- `references/env-strategy.md`:env 处理与 secret 默认策略
|
|
||||||
- `references/github-repo-intake.md`:仓库发现与 canonical 输入选择
|
|
||||||
- `references/deployment-notes.md`:部署说明
|
|
||||||
- `references/validation.md`:验证与排障
|
|
||||||
|
|
||||||
## 限制
|
1. 提供一种输入:
|
||||||
|
- 一条 `docker run` 命令
|
||||||
|
- 一个 Compose 文件或 Compose 项目
|
||||||
|
- 一个 GitHub 仓库 URL
|
||||||
|
- 一组需要审查或清理的现有 Quadlet 文件
|
||||||
|
2. 说明你的目标:
|
||||||
|
- 映射建议
|
||||||
|
- 部署设计
|
||||||
|
- 可审阅的可运行结果
|
||||||
|
3. 确认域名、主机路径、凭据、存储方案或可选服务等部署取值。
|
||||||
|
4. 在应用前审阅生成结果。
|
||||||
|
|
||||||
本 skill 不保证 Docker Compose 语义与 Podman Quadlet 语义完全等价。
|
## 示例请求
|
||||||
|
|
||||||
|
```text
|
||||||
|
把这条 docker run 命令转换成 Quadlet,并解释映射关系。
|
||||||
|
|
||||||
|
审查这个 compose.yaml,并给出一个 Podman Quadlet 布局方案。
|
||||||
|
|
||||||
|
根据这个仓库的自托管部署生成可审阅的 Quadlet 文件。
|
||||||
|
|
||||||
|
帮我把这套服务迁移到 rootless Podman,并保留 env-file 工作流。
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见产物
|
||||||
|
|
||||||
|
- Quadlet 单元文件
|
||||||
|
- env 文件或 env 增量文件
|
||||||
|
- 用于 install、reload、start、stop、restart、uninstall 的辅助脚本
|
||||||
|
- 部署说明与验证指引
|
||||||
|
|
||||||
|
## 说明
|
||||||
|
|
||||||
|
- 在安装前审阅生成结果。
|
||||||
|
- 对部署相关取值先确认,再生成结果。
|
||||||
|
- Docker Compose 与 Quadlet 不完全等价时,要明确说明行为变化。
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
|
|||||||
@@ -1,190 +1,120 @@
|
|||||||
---
|
---
|
||||||
name: quadlet-migrator
|
name: quadlet-migrator
|
||||||
description: Convert docker run commands or Docker Compose configurations into maintainable Podman Quadlet files, help users map env/env_file/.env usage into Environment or EnvironmentFile, and explain rootless or rootful deployment details and migration risks.
|
description: Convert docker run commands, Docker Compose configurations, or self-hosting deployment assets into reviewable Podman Quadlet output, preserve env/support files, and guide users through planning, review, generation, and validation.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Quadlet Migrator
|
# Quadlet Migrator
|
||||||
|
|
||||||
Use this skill when the user wants to migrate `docker run`, `docker compose`, or Compose-like service definitions into Podman Quadlet units, especially when environment variables, `env_file`, `.env`, rootless deployment, or systemd layout need to be planned or generated.
|
Use this skill when the user wants to migrate `docker run`, `docker compose`, or repository-based self-hosting deployment assets into Podman Quadlet output.
|
||||||
|
|
||||||
Do not rely on `podlet` as an execution dependency. You may use it only as prior-art knowledge, not as part of the runtime workflow.
|
This skill is for review-first migration work. It is responsible for choosing the right source inputs, preserving required runtime assets, reducing deployment decisions to a small confirmed set, and producing maintainable Quadlet artifacts.
|
||||||
|
|
||||||
## What this skill does
|
Do not rely on `podlet` as an execution dependency. You may use it only as prior-art knowledge, not as part of the workflow.
|
||||||
|
|
||||||
This skill helps you:
|
## Core Defaults
|
||||||
|
|
||||||
- discover Docker deployment entry points from a GitHub repository URL
|
- Use the lightest mode that satisfies the request.
|
||||||
- translate `docker run` flags and Compose service fields into Quadlet units
|
- Prefer reviewable output in the current working directory unless the user requested another output location or an existing-file conflict requires a decision.
|
||||||
- choose between `.container`, `.pod`, `.network`, `.volume`, and `.build`
|
- Prefer runnable and maintainable output over mechanical one-to-one translation.
|
||||||
- decide whether values belong in `Environment=` or `EnvironmentFile=`
|
- Preserve required env files, mounted config, initialization assets, and helper scripts when they are part of the deployment.
|
||||||
- work closely with the user to confirm deployment-specific environment values and operational choices
|
- Read docs, comments, and example values yourself; ask the user only about high-impact deployment decisions.
|
||||||
- identify missing variables, unsafe inline secrets, and unsupported Compose semantics
|
- Do not invent deployment-specific values.
|
||||||
- produce deployment notes for rootless or rootful systemd setups
|
- Keep detailed mapping and validation logic in `references/` instead of restating it in the main skill file.
|
||||||
|
|
||||||
## Operating modes
|
## Modes
|
||||||
|
|
||||||
Choose the lightest mode that satisfies the user's request.
|
- `advice`: explain mappings, review inputs, or answer focused migration questions without writing final artifacts
|
||||||
|
- `design`: perform planning and finalize review, then stop before writing runnable artifacts
|
||||||
- `advice`: explain mappings, review source inputs, answer targeted migration questions, or sketch a recommended structure without writing final artifacts
|
- `generate`: perform planning, finalize review, and execution, then write the approved artifacts
|
||||||
- `design`: perform `Planning` and `Finalize`, produce `QUADLET-FINALIZE.md`, but stop before writing runnable artifacts
|
|
||||||
- `generate`: perform `Planning`, `Finalize`, and `Execution`, then write the approved runnable artifacts
|
|
||||||
|
|
||||||
Do not force `generate` mode when the user only wants explanation, review, or a partial conversion.
|
Do not force `generate` mode when the user only wants explanation, review, or a partial conversion.
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
The full workflow has three explicit phases: `Planning`, `Finalize`, and `Execution`.
|
The workflow has three phases: `Planning`, `Finalize`, and `Execution`.
|
||||||
|
|
||||||
- `advice` usually stays in `Planning` or gives a targeted answer without entering all phases
|
- `advice` usually stays in planning or answers a focused question directly
|
||||||
- `design` uses `Planning` and `Finalize`
|
- `design` uses planning and finalize
|
||||||
- `generate` uses all three phases
|
- `generate` uses all three phases
|
||||||
|
|
||||||
Do not skip phase boundaries when you are using them. The skill should not jump directly from discovery into writing files.
|
Do not skip phase boundaries when a full workflow is in play.
|
||||||
|
|
||||||
### Planning phase
|
### Planning
|
||||||
|
|
||||||
Goal: gather inputs, understand the project, and work with the user to make the key decisions.
|
Goal: understand the source inputs, choose the source of truth, identify required runtime assets, and resolve the decisions that actually need user confirmation.
|
||||||
|
|
||||||
Tasks in this phase:
|
In planning:
|
||||||
|
|
||||||
1. Classify the input.
|
1. Classify the input.
|
||||||
- `docker run` or `podman run` style command
|
2. Find the canonical deployment entry point.
|
||||||
- single-file Compose configuration
|
3. Build a semantic model of services, images/builds, ports, storage, networks, env sources, dependencies, and required support files.
|
||||||
- Compose plus `.env` and optional `env_file`
|
4. Identify unresolved deployment decisions and ask the user about them.
|
||||||
- GitHub repository URL that likely contains self-hosting assets
|
5. Summarize what you learned and state the proposed reviewable output location before moving on.
|
||||||
- already partially converted Quadlet files that need cleanup
|
|
||||||
|
|
||||||
2. If the input is a GitHub repository, discover the deployment entry points first.
|
Planning is where you must ask about unresolved high-impact values. The following must be explicitly confirmed before leaving planning:
|
||||||
- start from the repository README and deployment subdirectory READMEs
|
|
||||||
- follow explicit links or references from documentation before making assumptions about file locations
|
|
||||||
- search the repository tree for `docker-compose.yaml`, `docker-compose.yml`, `compose.yaml`, `compose.yml`
|
|
||||||
- inspect common deployment-oriented subdirectories such as `docker/`, `deploy/`, `ops/`, `infra/`, `.devcontainer/`, and `examples/`, but do not assume the right entry point must live there
|
|
||||||
- look for `.env.example`, `.env.sample`, `env.example`, `middleware.env.example`, or similar templates
|
|
||||||
- inspect whether the project uses Compose profiles, multiple compose files, generated compose files, or helper scripts
|
|
||||||
- identify the canonical self-hosting entry point rather than assuming the repo root file is authoritative
|
|
||||||
|
|
||||||
3. Build a semantic model before writing Quadlet.
|
- **Deployment mode** (rootless vs rootful) — determines Quadlet target directory, systemctl scope, linger requirement, and helper-script behavior.
|
||||||
- services
|
- **Volume strategy** (named volume vs bind mount vs `.volume` unit) — determines whether `.volume` files are generated and how mount paths are written.
|
||||||
- images or builds
|
- Domains, host paths, credentials, optional services, and output-location conflicts.
|
||||||
- ports
|
- **Host port availability** — when `PublishPort=` is used, detect whether the host-side port is already occupied before proceeding.
|
||||||
- volumes and bind mounts
|
|
||||||
- networks
|
|
||||||
- environment variables and env files
|
|
||||||
- restart policy
|
|
||||||
- health checks
|
|
||||||
- startup dependencies
|
|
||||||
|
|
||||||
4. Identify which values and decisions must be confirmed with the user.
|
If the source has many env variables, reduce them to a small decision list instead of dumping raw templates back to the user.
|
||||||
- external URLs, domains, and ports
|
|
||||||
- database hostnames, passwords, and database names
|
|
||||||
- storage backend selection and credentials
|
|
||||||
- profile selection or optional service selection
|
|
||||||
- pod grouping when the project has many services or optional containers
|
|
||||||
- volume mode selection: named volume, bind mount, or anonymous volume
|
|
||||||
- rootless vs rootful deployment mode
|
|
||||||
- whether secrets should stay in env files or be moved elsewhere
|
|
||||||
|
|
||||||
Do not silently invent deployment-specific values. If the repository or compose file provides placeholders, defaults, or examples, read the surrounding documentation and comments yourself, infer the intended meaning, and only ask the user to confirm the values that materially affect deployment.
|
Do not leave planning until the canonical input set and the important unresolved decisions are clear enough for a coherent design review.
|
||||||
|
|
||||||
When many variables exist, do not hand the raw `.env.example` back to the user for manual review. Your job is to digest it, reduce it, and produce a concise checklist of high-impact decisions. Prioritize the variables that are required to produce a safe and runnable output.
|
### Finalize
|
||||||
|
|
||||||
At the end of planning, summarize what you learned and what you intend to generate, then explicitly ask the user whether anything should be changed or added before you move to the next phase.
|
Goal: freeze the design that planning established and ask the user to review it in conversation.
|
||||||
|
|
||||||
Planning is also the phase where you must actively ask the user for the unresolved high-impact decisions you identified.
|
Finalize is not a second discovery pass. Do not use it to introduce first-time major choices.
|
||||||
|
|
||||||
Do not defer first-time decision gathering into `QUADLET-FINALIZE.md`.
|
In finalize:
|
||||||
|
|
||||||
If decisions are still unresolved, stop in planning and ask the user directly. Do not write `QUADLET-FINALIZE.md` yet.
|
1. Freeze the chosen service set and topology.
|
||||||
|
2. Freeze storage, image, env, and output-location decisions.
|
||||||
|
3. Confirm the reviewed artifact set, including support files and env files, not only Quadlet units.
|
||||||
|
4. Present a concise design snapshot and ask the user to approve it or request edits.
|
||||||
|
|
||||||
### Finalize phase
|
Do not start execution until the user has reviewed and confirmed the finalize snapshot.
|
||||||
|
|
||||||
Goal: consolidate the decisions already made in planning into one internally consistent design snapshot and ask the user to review it.
|
### Execution
|
||||||
|
|
||||||
The output of this phase must be written to a Markdown file named `QUADLET-FINALIZE.md`.
|
Goal: write the approved artifacts.
|
||||||
|
|
||||||
This filename is fixed. Do not rename it per project.
|
Before writing any file, confirm that the user has explicitly approved the finalize snapshot. If the finalize phase was skipped or the user has not confirmed, stop and ask.
|
||||||
|
|
||||||
This phase starts only after planning-phase questions have been asked and the user has had a chance to answer or explicitly say there is nothing more to add.
|
In execution:
|
||||||
|
|
||||||
Finalize is not a second discovery pass. Do not use it to introduce new major design choices, gather first-time requirements, or expand the scope of analysis. If execution reveals a new material decision or conflict, return to planning rather than stretching finalize into another analysis phase.
|
1. Generate the approved Quadlet files.
|
||||||
|
2. Generate env files or env deltas only when needed for the approved output.
|
||||||
|
3. Generate helper scripts only when they materially help the user apply or operate the result.
|
||||||
|
4. Include required support files and directories in the reviewed deliverable set.
|
||||||
|
5. Add deployment notes or validation guidance when they materially help the user operate the result.
|
||||||
|
|
||||||
Tasks in this phase:
|
If implementation reveals a material conflict with the approved design, stop and return to planning instead of silently diverging.
|
||||||
|
|
||||||
1. Freeze the chosen service set and runtime grouping.
|
## Hard Stops
|
||||||
- prefer putting the whole project in a single pod when practical
|
|
||||||
- if the project is a simple single-container deployment, a standalone `.container` is acceptable
|
|
||||||
- if shared networking, shared published ports, or tighter lifecycle coupling make pod semantics useful, prefer one or more `.pod` units
|
|
||||||
- containers in the same `.pod` can communicate over `127.0.0.1` / `localhost` because they share a network namespace
|
|
||||||
- containers in different pods must not be treated as reachable via `127.0.0.1` / `localhost`; if you split the topology across multiple pods, use container networking and service addressing, or publish ports across the host boundary when that better matches the deployment
|
|
||||||
- if one pod is not practical because of port conflicts or clearly incompatible groupings, split the result into a small number of pods rather than forcing an awkward topology
|
|
||||||
|
|
||||||
2. Freeze the storage strategy.
|
Stop and ask the user before finalizing or generating runnable output when any of these remain unresolved:
|
||||||
- named volume, bind mount, or anonymous volume per storage use case
|
|
||||||
- bind mounts must end up as absolute host paths
|
|
||||||
|
|
||||||
3. Freeze the image strategy.
|
- required secrets, external URLs, host paths, or other deployment-specific values
|
||||||
- prefer upstream prebuilt registry images when they already exist and local build is not required for correctness
|
- multiple plausible source inputs with no confident canonical entry point
|
||||||
- create `.build` only when local build is actually required, or when the user explicitly wants a declarative local-build workflow
|
- image strategy versus local build strategy when the difference materially affects the result
|
||||||
- prefer fully qualified image names in generated output
|
- a lossy mapping that would change runtime behavior in an important way
|
||||||
- if the source image omits a registry and is intended for Docker Hub, expand it explicitly instead of relying on short-name resolution
|
- output-location conflicts or overwrite strategy for files that already exist
|
||||||
- for images of the form `name[:tag]` with no namespace, normalize to `docker.io/library/name[:tag]`
|
- required support files or directories referenced by mounts, docs, commands, or scripts
|
||||||
- for images of the form `namespace/name[:tag]` with no registry, normalize to `docker.io/namespace/name[:tag]`
|
- required env values for minimal startup
|
||||||
- if the source clearly points to another registry such as `ghcr.io`, `quay.io`, or a private registry, preserve that registry explicitly
|
- likely env-key typos or mismatches
|
||||||
|
- host port conflicts when `PublishPort=` is used — detect occupied host ports before finalizing
|
||||||
|
- unresolved deployment mode (rootless vs rootful)
|
||||||
|
- unresolved volume strategy (named volume vs bind mount vs `.volume` unit)
|
||||||
|
- a mismatch between deployment mode and the intended operator model or file locations
|
||||||
|
|
||||||
4. Freeze the environment strategy.
|
Do not keep moving forward by guessing through these gaps.
|
||||||
- use `Environment=` for a small number of stable non-sensitive values
|
|
||||||
- use `EnvironmentFile=` for bulk variables, secrets, or values already sourced from `.env` / `env_file`
|
|
||||||
- if Compose interpolation references variables that are missing, report them explicitly and prepare a candidate env file with placeholders or suggested defaults instead of delegating the entire review back to the user
|
|
||||||
- treat variable names containing `PASSWORD`, `TOKEN`, `SECRET`, `KEY`, `PRIVATE`, or `PASS` as sensitive by default and avoid inlining unless the user explicitly wants that
|
|
||||||
|
|
||||||
5. Summarize already-known conflicts and their chosen resolution.
|
If a structured input tool is unavailable, ask the user directly in conversation before proceeding. Do not substitute defaults for unresolved high-impact decisions.
|
||||||
- port collisions
|
|
||||||
- incompatible grouping decisions
|
|
||||||
- storage mode inconsistencies
|
|
||||||
- unresolved required variables
|
|
||||||
- mismatch between requested deployment mode and selected file locations
|
|
||||||
|
|
||||||
At the end of finalize, write `QUADLET-FINALIZE.md` and ask the user to review it before you start writing the final artifacts.
|
## Decision Priority
|
||||||
|
|
||||||
`QUADLET-FINALIZE.md` is a review artifact, not a questionnaire. It should summarize decisions that were already discussed in planning.
|
|
||||||
|
|
||||||
If `QUADLET-FINALIZE.md` already exists, read it first and update it intentionally. Do not blindly overwrite it without checking whether it reflects a prior review round that should be preserved or revised.
|
|
||||||
|
|
||||||
When the design has materially changed, replace outdated sections so the file remains a single current review snapshot rather than an append-only log.
|
|
||||||
|
|
||||||
`QUADLET-FINALIZE.md` should include:
|
|
||||||
|
|
||||||
- source inputs you chose and why
|
|
||||||
- selected services and omitted optional services
|
|
||||||
- pod layout
|
|
||||||
- naming prefix
|
|
||||||
- image strategy
|
|
||||||
- volume strategy
|
|
||||||
- env strategy
|
|
||||||
- only the minimal placeholders that still cannot be resolved without user secrets or environment-specific values
|
|
||||||
- detected conflicts and how they were resolved
|
|
||||||
- the list of files that will be created in execution phase
|
|
||||||
|
|
||||||
Do not start execution until the user has reviewed and confirmed `QUADLET-FINALIZE.md` or provided requested edits.
|
|
||||||
|
|
||||||
Do not use `QUADLET-FINALIZE.md` as the first place where the user sees important choices. Those choices should already have been raised in planning.
|
|
||||||
|
|
||||||
### Execution phase
|
|
||||||
|
|
||||||
Goal: write the approved runnable artifacts.
|
|
||||||
|
|
||||||
Tasks in this phase:
|
|
||||||
|
|
||||||
1. Generate the Quadlet files.
|
|
||||||
2. Generate the env file or env delta only when needed for runnable output.
|
|
||||||
3. Generate deployment notes or validation guidance only when they materially help the user operate the result.
|
|
||||||
4. Generate a README only when the user explicitly wants a self-contained handoff artifact or a packaged deliverable.
|
|
||||||
|
|
||||||
Execution should follow the approved contents of `QUADLET-FINALIZE.md`. If the implementation reveals a material conflict with the finalized design, stop and return to planning rather than silently diverging.
|
|
||||||
|
|
||||||
If you generate a README or operational notes, use the same language as the user unless the user explicitly asks for another language.
|
|
||||||
|
|
||||||
## Decision priority
|
|
||||||
|
|
||||||
When rules or signals conflict, use this priority order:
|
When rules or signals conflict, use this priority order:
|
||||||
|
|
||||||
@@ -192,93 +122,29 @@ When rules or signals conflict, use this priority order:
|
|||||||
2. the source project's documented canonical deployment path
|
2. the source project's documented canonical deployment path
|
||||||
3. runnable and safe output
|
3. runnable and safe output
|
||||||
4. maintainable output
|
4. maintainable output
|
||||||
5. default style rules in this skill and its references
|
5. defaults in this skill and its references
|
||||||
|
|
||||||
If a lower-priority default conflicts with a higher-priority source of truth, follow the higher-priority source and say so briefly.
|
If a lower-priority default conflicts with a higher-priority source of truth, follow the higher-priority source and say so briefly.
|
||||||
|
|
||||||
## Hard stops
|
## Reference Routing
|
||||||
|
|
||||||
Stop and ask the user before finalizing or generating runnable output when any of these remain unresolved:
|
Use the reference files for detailed rules instead of duplicating them here:
|
||||||
|
|
||||||
- required secrets, external URLs, host paths, or other deployment-specific values are missing
|
- `references/github-repo-intake.md` for repository discovery and source-of-truth selection
|
||||||
- multiple plausible source inputs exist and the canonical deployment entry point cannot be determined confidently
|
- `references/compose-mapping.md` for Compose field mapping, topology, naming, network, storage, and runtime-identity defaults
|
||||||
- image strategy versus local build strategy is materially ambiguous
|
- `references/env-strategy.md` for `.env`, `env_file`, interpolation, sensitive values, completeness checks, and typo detection
|
||||||
- a lossy mapping would change runtime behavior in a way that matters
|
- `references/deployment-notes.md` for rootless/rootful deployment, helper scripts, apply flow, and operational notes
|
||||||
- the requested deployment mode conflicts with the intended output location or operator model
|
- `references/validation.md` for validation, troubleshooting, and runnable-output checks
|
||||||
|
|
||||||
Do not keep moving forward by guessing through these gaps.
|
When Quadlet option semantics or supported behavior are unclear, treat `references/podman-systemd.unit.5.md` as the authoritative source.
|
||||||
|
|
||||||
## Rootless vs rootful
|
## Collaboration Rules
|
||||||
|
|
||||||
Decide early whether the deployment is rootless or rootful, because this changes the output path and some operational guidance.
|
- Confirm deployment-specific values that materially affect connectivity, credentials, storage, or topology.
|
||||||
|
- Keep the user's review burden small by summarizing decisions instead of forwarding raw upstream material.
|
||||||
|
- Distinguish between upstream example values and user-confirmed values.
|
||||||
|
- Preserve placeholders when the user has not provided final values yet, and do not describe the result as runnable when required values are still unresolved.
|
||||||
|
|
||||||
- For rootless deployments, use `~/.config/containers/systemd/` unless the user has a reason to use another supported path.
|
## Validation Reminder
|
||||||
- For rootful deployments, use `/etc/containers/systemd/` unless the user asks for a different placement.
|
|
||||||
- For rootless long-running services, remind the user about lingering if relevant. See `references/deployment-notes.md`.
|
|
||||||
|
|
||||||
When you need authoritative details about supported search paths, unit semantics, option names, or debugging, read `references/podman-systemd.unit.5.md`.
|
When the user wants runnable output, make sure the final artifact set includes the required support files and env sources, and point the user to the deployment and validation references as needed.
|
||||||
|
|
||||||
## Reference routing
|
|
||||||
|
|
||||||
Use the reference files for detailed rules instead of restating them here:
|
|
||||||
|
|
||||||
- `references/compose-mapping.md` for Compose field mapping, topology choices, and naming conventions
|
|
||||||
- `references/env-strategy.md` for `.env`, `env_file`, interpolation, and secret-handling defaults
|
|
||||||
- `references/github-repo-intake.md` for GitHub repository discovery and canonical input selection
|
|
||||||
- `references/deployment-notes.md` for deployment guidance and rootless or rootful operational notes
|
|
||||||
- `references/validation.md` for post-generation validation and troubleshooting steps
|
|
||||||
|
|
||||||
## User collaboration
|
|
||||||
|
|
||||||
This skill is not a blind converter. For runnable output, collaborate tightly with the user.
|
|
||||||
|
|
||||||
- Confirm any environment value that controls external connectivity, credentials, storage, or deployment topology.
|
|
||||||
- If the source contains a large env template, summarize the required variables into a small decision list and ask the user to confirm only those values.
|
|
||||||
- Do not ask the user to read upstream docs or manually audit a large `.env.example` unless they explicitly want to do that themselves.
|
|
||||||
- Read the docs, comments, and example values yourself, then present the user with a reduced set of concrete decisions and a candidate env result.
|
|
||||||
- Ask the user to choose optional services and pod grouping early when the source project offers many containers or feature profiles.
|
|
||||||
- Ask the user which volume mode they want before finalizing storage mappings.
|
|
||||||
- Ask these questions before writing `QUADLET-FINALIZE.md`, not inside it.
|
|
||||||
- Preserve placeholders when the user has not provided final values yet.
|
|
||||||
- Distinguish between upstream example values and user-confirmed production values.
|
|
||||||
|
|
||||||
You should still make reasonable structural decisions yourself, but do not pretend unknown deployment inputs are settled facts.
|
|
||||||
|
|
||||||
## Deployment and validation
|
|
||||||
|
|
||||||
When the user wants runnable output, provide the relevant deployment notes from `references/deployment-notes.md` and the validation steps from `references/validation.md` as needed.
|
|
||||||
|
|
||||||
At minimum, mention the need to:
|
|
||||||
|
|
||||||
- place files in a valid Quadlet directory
|
|
||||||
- run `systemctl daemon-reload` or `systemctl --user daemon-reload`
|
|
||||||
- create required bind-mount directories before first start
|
|
||||||
- verify generator output or systemd unit validity when startup fails
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
- `docker run` for a single web service -> often `advice` or `generate` with one `.container`
|
|
||||||
- small Compose app with api and db -> usually `design` or `generate`, often one `.pod` plus child containers
|
|
||||||
- GitHub repo with `.env.example` and multiple profiles -> start in `Planning`, reduce the env questions, then move to `Finalize`
|
|
||||||
|
|
||||||
## Anti-examples
|
|
||||||
|
|
||||||
- do not dump a large `.env.example` back to the user as the primary review artifact
|
|
||||||
- do not introduce first-time critical decisions inside `QUADLET-FINALIZE.md`
|
|
||||||
- do not force pod topology when a standalone `.container` is the simpler correct result
|
|
||||||
- do not keep generating through unresolved deployment-critical unknowns
|
|
||||||
|
|
||||||
## Boundaries
|
|
||||||
|
|
||||||
Do not claim perfect equivalence where Podman or Quadlet semantics differ from Docker Compose.
|
|
||||||
|
|
||||||
Be especially careful with:
|
|
||||||
|
|
||||||
- Compose interpolation and default syntax
|
|
||||||
- `depends_on` readiness assumptions
|
|
||||||
- complex `deploy` blocks
|
|
||||||
- multi-file Compose merges
|
|
||||||
- secrets and credentials
|
|
||||||
- permission behavior on rootless bind mounts
|
|
||||||
|
|
||||||
If a mapping is lossy, say so directly and explain the concrete risk.
|
|
||||||
|
|||||||
@@ -2,17 +2,27 @@
|
|||||||
|
|
||||||
Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadlet units.
|
Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadlet units.
|
||||||
|
|
||||||
## General approach
|
## Contents
|
||||||
|
|
||||||
- Model each service first, then decide how to group all resulting containers into one or more `.pod` units.
|
- General defaults
|
||||||
|
- Field mapping
|
||||||
|
- Topology guidance
|
||||||
|
- Risky or lossy areas
|
||||||
|
|
||||||
|
## General Defaults
|
||||||
|
|
||||||
|
- Model each service first, then decide how to group the result into one or more `.pod` units.
|
||||||
- Prefer maintainable Quadlet output over mechanical one-to-one translation.
|
- Prefer maintainable Quadlet output over mechanical one-to-one translation.
|
||||||
- Keep names stable and predictable. Generated filenames should use a shared project prefix.
|
- Keep filenames stable and predictable. Use a shared project prefix for generated artifacts.
|
||||||
|
- Do not add explicit runtime naming directives such as `PodName=`, `ServiceName=`, `ContainerName=`, or `NetworkName=` by default. Let Quadlet and Podman derive runtime names unless the user explicitly asks for custom naming or a reviewed requirement depends on it.
|
||||||
|
- Do not add `User=`, `Group=`, or `UserNS=keep-id` by default. Preserve or introduce runtime identity mapping only when the source explicitly requires it or when the user is working through permission or ownership behavior.
|
||||||
|
- For env-specific decisions, use `references/env-strategy.md` instead of expanding the env rules here.
|
||||||
|
|
||||||
## Field strategy
|
## Field Mapping
|
||||||
|
|
||||||
### `name`
|
### `name`
|
||||||
|
|
||||||
- Use as an application prefix when it improves unit naming clarity.
|
- Use it as an application prefix when it improves naming clarity.
|
||||||
- Do not force a top-level project name into every filename if the user prefers shorter units.
|
- Do not force a top-level project name into every filename if the user prefers shorter units.
|
||||||
|
|
||||||
### `services.<name>.image`
|
### `services.<name>.image`
|
||||||
@@ -23,7 +33,7 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
|||||||
- Use these rules when filling in Docker Hub references:
|
- Use these rules when filling in Docker Hub references:
|
||||||
- `redis:7` -> `docker.io/library/redis:7`
|
- `redis:7` -> `docker.io/library/redis:7`
|
||||||
- `nginx` -> `docker.io/library/nginx`
|
- `nginx` -> `docker.io/library/nginx`
|
||||||
- `langgenius/dify-api:latest` -> `docker.io/langgenius/dify-api:latest`
|
- `examplecorp/api:latest` -> `docker.io/examplecorp/api:latest`
|
||||||
- Do not guess `docker.io/library/...` for images that already include a namespace.
|
- Do not guess `docker.io/library/...` for images that already include a namespace.
|
||||||
|
|
||||||
### `services.<name>.build`
|
### `services.<name>.build`
|
||||||
@@ -35,43 +45,46 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
|||||||
### `container_name`
|
### `container_name`
|
||||||
|
|
||||||
- Drop it.
|
- Drop it.
|
||||||
- Do not generate `ContainerName=`. Let Podman and systemd derive the runtime name.
|
- Do not generate `ContainerName=`.
|
||||||
|
|
||||||
### `ports`
|
### `ports`
|
||||||
|
|
||||||
- For a standalone service, map to `PublishPort=` on the `.container`.
|
- For a standalone service, map to `PublishPort=` on the `.container`.
|
||||||
- For a pod-based topology, prefer `PublishPort=` on the `.pod` when the published ports belong to the pod boundary rather than one child container.
|
- For a pod-based topology, prefer `PublishPort=` on the `.pod` when the published ports belong to the pod boundary rather than one child container.
|
||||||
|
- When `PublishPort=` maps a host-side port, detect whether that host port is already in use before finalizing the mapping. Check for TCP/UDP listeners on the host using an available port-detection method. If a conflict is found, stop and ask the user whether to change the host port, skip the mapping, or resolve the conflict manually. Do not silently remap occupied host ports to an alternative.
|
||||||
|
|
||||||
### `volumes`
|
### `volumes`
|
||||||
|
|
||||||
- Bind mounts become `Volume=HOST:CONTAINER[:OPTIONS]`.
|
- Bind mounts become `Volume=HOST:CONTAINER[:OPTIONS]`.
|
||||||
- Normalize relative host paths against the Compose file directory and emit absolute paths in the final Quadlet output.
|
- Normalize relative host paths against the Compose file directory and emit absolute paths in the final Quadlet output.
|
||||||
|
- Preserve bind-mount shape from the source input: a file bind mount must stay a file bind mount, and a directory bind mount must stay a directory bind mount.
|
||||||
|
- Do not widen a file mount into a directory mount, or collapse a directory mount into a file mount, unless the source is genuinely ambiguous or the upstream deployment docs explicitly require a different reviewed mapping.
|
||||||
- Named volumes can remain referenced by name, but when the user wants explicit infrastructure-as-code, create matching `.volume` units.
|
- Named volumes can remain referenced by name, but when the user wants explicit infrastructure-as-code, create matching `.volume` units.
|
||||||
- Ask the user which volume mode they want when the source does not make the intended persistence model obvious.
|
- Ask the user which volume mode they want when the source does not make the intended persistence model obvious.
|
||||||
|
- If a bind mount points to a repo-local file or directory, include that source in the reviewable deliverable set unless the user explicitly wants a host-managed external path instead.
|
||||||
|
- If a bind mount references a whole directory, inspect and preserve the required directory contents rather than only naming the directory root.
|
||||||
|
|
||||||
### `networks`
|
### `networks`
|
||||||
|
|
||||||
- If the source uses a default network only, you often do not need a `.network` unit.
|
- Prefer pod-first topology over preserving Compose bridge networks mechanically.
|
||||||
- If a custom network is intentional and needs to be managed declaratively, create a `.network` unit and reference it explicitly.
|
- If the source uses a default network only, you often do not need a `.network` unit at all.
|
||||||
|
- If the source uses bridge networking for containers that can reasonably live in one pod, collapse that topology into one `.pod` so the containers share one network namespace.
|
||||||
|
- Create a `.network` unit only when services must be split across pods, or when explicit network isolation or custom network management is materially required.
|
||||||
|
- Do not add `NetworkName=` by default.
|
||||||
- Containers in the same `.pod` can communicate over `127.0.0.1` / `localhost` because they share a network namespace.
|
- Containers in the same `.pod` can communicate over `127.0.0.1` / `localhost` because they share a network namespace.
|
||||||
|
- When services in the same `.pod` must accept connections from sibling containers, ensure they listen on `127.0.0.1` or `0.0.0.0`; if they listen only on another interface, sibling containers in the pod may not be able to reach them.
|
||||||
|
- When the upstream service supports configuring the listen address via environment variables or equivalent runtime settings, preserve or generate the necessary configuration instead of assuming the default bind address is correct.
|
||||||
|
- When `Pod=` is set, never generate `AddHost=` entries whose purpose is sibling-container discovery inside that pod. Intra-pod communication should use `127.0.0.1` / `localhost` instead.
|
||||||
|
- `AddHost=` is a host-to-IP override, not an intra-pod service-discovery mechanism. Do not describe `Pod=` as a blanket prohibition on `AddHost=` unless the upstream reference explicitly requires that for the case at hand.
|
||||||
- Containers in different pods must not be treated as reachable via `127.0.0.1` / `localhost`.
|
- Containers in different pods must not be treated as reachable via `127.0.0.1` / `localhost`.
|
||||||
- When splitting services across multiple pods, use container networking and service-level addressing, or publish ports to the host boundary when that is the intended access pattern.
|
- When splitting services across multiple pods or preserving a shared bridge network, use container names, pod names, or explicit `NetworkAlias=` values on the shared network, or publish ports to the host boundary when that is the intended access pattern.
|
||||||
|
- Do not add `ServiceName=` or `PodName=` by default.
|
||||||
|
- `ServiceName=` controls the generated systemd unit name only and must not be used as an application-facing network address.
|
||||||
|
- `PodName=` controls the Podman pod name only; it can participate in the chosen addressing strategy, but it does not determine the systemd service name.
|
||||||
|
|
||||||
### `environment`
|
### `environment`, `env_file`, and `.env` interpolation
|
||||||
|
|
||||||
- Small stable values can become one or more `Environment=` lines.
|
- Use `references/env-strategy.md` for detailed env handling, interpolation, sensitivity defaults, completeness checks, and missing-variable reporting.
|
||||||
- Sensitive values should be moved to `EnvironmentFile=` unless the user explicitly wants them inline.
|
|
||||||
|
|
||||||
### `env_file`
|
|
||||||
|
|
||||||
- Prefer `EnvironmentFile=`.
|
|
||||||
- If there are multiple env files, preserve order and explain precedence if the user asks.
|
|
||||||
|
|
||||||
### `.env` interpolation
|
|
||||||
|
|
||||||
- Resolve only when you have the actual source values.
|
|
||||||
- If variables are missing, surface a missing-variable list.
|
|
||||||
- Never silently replace unknown values with blanks.
|
|
||||||
|
|
||||||
### `profiles`
|
### `profiles`
|
||||||
|
|
||||||
@@ -84,11 +97,6 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
|||||||
- Translate to `Requires=` and `After=` when that reflects intent.
|
- Translate to `Requires=` and `After=` when that reflects intent.
|
||||||
- State clearly that this controls startup ordering, not application readiness.
|
- State clearly that this controls startup ordering, not application readiness.
|
||||||
|
|
||||||
### `restart`
|
|
||||||
|
|
||||||
- Map common cases to `[Service] Restart=`.
|
|
||||||
- If the source policy has no direct systemd equivalent, choose the nearest safe mapping and explain it.
|
|
||||||
|
|
||||||
### `healthcheck`
|
### `healthcheck`
|
||||||
|
|
||||||
- Prefer dedicated Quadlet health fields such as `HealthCmd=`, `HealthInterval=`, `HealthTimeout=`, `HealthRetries=` when representable.
|
- Prefer dedicated Quadlet health fields such as `HealthCmd=`, `HealthInterval=`, `HealthTimeout=`, `HealthRetries=` when representable.
|
||||||
@@ -98,23 +106,36 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
|||||||
|
|
||||||
- `entrypoint` typically maps to `Entrypoint=`.
|
- `entrypoint` typically maps to `Entrypoint=`.
|
||||||
- `command` typically maps to `Exec=`.
|
- `command` typically maps to `Exec=`.
|
||||||
|
- If an entrypoint or helper script is repo-local, treat it as a support file that must be copied or preserved in the generated layout.
|
||||||
|
|
||||||
### `user`
|
### `user`
|
||||||
|
|
||||||
- Map to `User=` and `Group=` in `[Container]` only when it is a container runtime user mapping, not a systemd service user.
|
- Map `User=` and `Group=` only when the source explicitly requires a container runtime user mapping or when the user is addressing permission or ownership behavior.
|
||||||
- Do not use systemd `User=` to try to make a rootless Quadlet run as another login user.
|
- Do not use systemd `User=` to try to make a rootless Quadlet run as another login user.
|
||||||
|
- Consider `UserNS=keep-id` only when the user is working through rootless permission or ownership behavior and the reviewed topology benefits from preserving host identity semantics.
|
||||||
|
|
||||||
### unsupported or risky fields
|
## Topology Guidance
|
||||||
|
|
||||||
|
Choose the simplest topology that preserves the source deployment intent.
|
||||||
|
|
||||||
|
- Prefer a single `.pod` for multi-container applications when practical.
|
||||||
|
- If one logical service contains multiple containers, default to putting them in the same `.pod` so they share networking and lifecycle.
|
||||||
|
- If the project is a simple single-container deployment with no real need for pod semantics, a standalone `.container` is the preferred result.
|
||||||
|
- If one pod is not practical because of port conflicts or clearly incompatible groupings, split the result into a small number of pods rather than forcing an awkward topology.
|
||||||
|
- Avoid preserving bridge networks by default when pod grouping already expresses the intended communication pattern well.
|
||||||
|
- For large application stacks with optional services, ask the user to choose the desired service set before generating a minimized result.
|
||||||
|
|
||||||
|
## Risky Or Lossy Areas
|
||||||
|
|
||||||
Handle these conservatively and usually as migration notes:
|
Handle these conservatively and usually as migration notes:
|
||||||
|
|
||||||
- `deploy`
|
- `deploy`
|
||||||
- `profiles`
|
|
||||||
- `extends`
|
- `extends`
|
||||||
- advanced Compose merge behavior
|
- advanced Compose merge behavior
|
||||||
- readiness semantics hidden behind `depends_on`
|
- readiness semantics hidden behind `depends_on`
|
||||||
|
- any mapping that changes the source network or storage behavior in a way that matters
|
||||||
|
|
||||||
## Minimal examples
|
## Minimal Examples
|
||||||
|
|
||||||
### Single service to standalone container
|
### Single service to standalone container
|
||||||
|
|
||||||
@@ -136,8 +157,6 @@ Image=docker.io/library/nginx:latest
|
|||||||
PublishPort=8080:80
|
PublishPort=8080:80
|
||||||
```
|
```
|
||||||
|
|
||||||
Use this when the deployment is truly a simple single-service case and pod semantics add little value.
|
|
||||||
|
|
||||||
### Small multi-service app to one pod
|
### Small multi-service app to one pod
|
||||||
|
|
||||||
Source intent:
|
Source intent:
|
||||||
@@ -159,19 +178,3 @@ Reasonable result shape:
|
|||||||
- one container unit for `db`
|
- one container unit for `db`
|
||||||
- `api` may reach `db` over `127.0.0.1` / `localhost` because both containers share the pod network namespace
|
- `api` may reach `db` over `127.0.0.1` / `localhost` because both containers share the pod network namespace
|
||||||
- ordering hints for startup, while explicitly noting that `depends_on` does not guarantee readiness
|
- ordering hints for startup, while explicitly noting that `depends_on` does not guarantee readiness
|
||||||
|
|
||||||
Use this when shared networking and a grouped lifecycle make the deployment easier to operate.
|
|
||||||
|
|
||||||
## Pod decision rule
|
|
||||||
|
|
||||||
Choose the simplest topology that preserves the source deployment intent.
|
|
||||||
|
|
||||||
Prefer a single `.pod` for multi-container applications when practical.
|
|
||||||
|
|
||||||
If the project is a simple single-container deployment with no real need for pod semantics, a standalone `.container` is acceptable.
|
|
||||||
|
|
||||||
If shared networking, shared published ports, or tightly coupled service lifecycle make pod semantics useful, prefer one or more `.pod` units.
|
|
||||||
|
|
||||||
If one pod is not practical because of port conflicts or clearly incompatible groupings, split the result into a small number of pods rather than forcing an awkward topology.
|
|
||||||
|
|
||||||
For large application stacks with optional services, ask the user to choose the desired service set before generating a minimized result.
|
|
||||||
|
|||||||
@@ -2,40 +2,80 @@
|
|||||||
|
|
||||||
Use this file when the user wants deployment-ready instructions alongside generated Quadlet units.
|
Use this file when the user wants deployment-ready instructions alongside generated Quadlet units.
|
||||||
|
|
||||||
## Directory choice
|
## Contents
|
||||||
|
|
||||||
|
- Delivery flow
|
||||||
|
- Apply target directories
|
||||||
|
- Helper-script expectations
|
||||||
|
- Operational notes
|
||||||
|
- Optional enhancements
|
||||||
|
|
||||||
|
## Delivery Flow
|
||||||
|
|
||||||
|
For `design` mode, stop after the user reviews the finalize snapshot in conversation.
|
||||||
|
For `generate` mode, continue only after the user has reviewed and confirmed the finalize snapshot or requested edits.
|
||||||
|
|
||||||
|
Recommended apply flow:
|
||||||
|
|
||||||
|
1. Generate the reviewable artifacts in the current working directory by default, or in another user-requested output directory.
|
||||||
|
2. Review the finalized design together with the generated Quadlet files, env files, helper scripts, and required repo-local support files.
|
||||||
|
3. Use `install.sh` to copy only the reviewed Quadlet unit files into the chosen Quadlet directory.
|
||||||
|
4. Run the appropriate `daemon-reload` command.
|
||||||
|
5. Use `start.sh`, `stop.sh`, and `restart.sh` to manage services.
|
||||||
|
6. Use `uninstall.sh` only when the user wants to remove the installed reviewed Quadlet unit files without broad Podman cleanup.
|
||||||
|
|
||||||
|
Keep installation separate from service-management scripts so the user can review generated files before applying them.
|
||||||
|
|
||||||
|
## Apply Target Directories
|
||||||
|
|
||||||
### Rootless
|
### Rootless
|
||||||
|
|
||||||
- primary default: `~/.config/containers/systemd/`
|
- default apply target: `~/.config/containers/systemd/`
|
||||||
- user-scoped management commands use `systemctl --user`
|
- user-scoped management commands use `systemctl --user`
|
||||||
|
|
||||||
### Rootful
|
### Rootful
|
||||||
|
|
||||||
- primary default: `/etc/containers/systemd/`
|
- default apply target: `/etc/containers/systemd/`
|
||||||
- system-scoped management commands use `systemctl`
|
- system-scoped management commands use `systemctl`
|
||||||
|
|
||||||
See `podman-systemd.unit.5.md` for the full search-path matrix.
|
See `podman-systemd.unit.5.md` for the full search-path matrix.
|
||||||
|
|
||||||
## Rootless operational notes
|
## Helper-Script Expectations
|
||||||
|
|
||||||
- Bind mounts may hit UID/GID mismatches.
|
- `install.sh` is the canonical apply script. It copies only reviewed Quadlet unit files into the selected Quadlet target directory.
|
||||||
- For pod-based deployments that should preserve host ownership semantics, consider `UserNS=keep-id` on `[Pod]` when appropriate.
|
- Do not generate a separate `apply.sh` by default. Use that alternate name only when the user explicitly asks for it.
|
||||||
- If the service must survive logout, mention lingering:
|
- Helper shell scripts must discover the reviewed Quadlet files through their shared generated prefix, using shared-prefix glob matching such as `<prefix>*` instead of hardcoding exact filenames or assuming a fixed file count.
|
||||||
|
- `install.sh` must not start, stop, restart, or reload services as a side effect.
|
||||||
|
- `uninstall.sh` removes only the installed reviewed Quadlet unit files from the selected Quadlet target directory.
|
||||||
|
- `uninstall.sh` should stop affected services before removing their installed unit files, and should not delete support files, unrelated files, shared directories, named volumes, images, or Podman objects unless the user explicitly asks for broader cleanup.
|
||||||
|
- `reload.sh` runs only the appropriate `daemon-reload` command after installation changes.
|
||||||
|
- `start.sh`, `stop.sh`, and `restart.sh` manage services only and must not silently install or overwrite reviewed files.
|
||||||
|
- When a generated topology includes `<name>.pod` plus child containers linked with `Pod=<name>.pod`, helper scripts should use the pod service as the lifecycle entrypoint. Derive that service name from `ServiceName=` when present on the `.pod`, otherwise use Quadlet's default generated pod service name. Do not add `ServiceName=` merely to simplify helper scripts.
|
||||||
|
|
||||||
|
## Operational Notes
|
||||||
|
|
||||||
|
- Review not only Quadlet unit files but also env files, mounted config, initialization assets, entrypoint scripts, and other support files required at runtime.
|
||||||
|
- Do not add explicit runtime naming directives such as `PodName=`, `ServiceName=`, `ContainerName=`, or `NetworkName=` by default. Use Quadlet's derived names unless the user explicitly asks for custom naming or a reviewed requirement depends on it.
|
||||||
|
- Do not use `ServiceName=` as an application connection target. It controls the generated systemd unit name only.
|
||||||
|
- Within a single pod, use `127.0.0.1` / `localhost` for container-to-container communication instead of generating `AddHost=` entries for sibling-container discovery.
|
||||||
|
- If a service inside the pod must accept connections from sibling containers, ensure its effective listen address is reachable within the shared pod namespace, typically `127.0.0.1` or `0.0.0.0`.
|
||||||
|
- Bind mounts may hit UID/GID mismatches, especially in rootless deployments.
|
||||||
|
- Do not add `User=`, `Group=`, or `UserNS=keep-id` by default. Consider them only when the user is working through container permission or ownership behavior, or when the source explicitly requires that runtime identity mapping.
|
||||||
|
- For rootless long-running services that should survive logout, mention lingering:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo loginctl enable-linger <username>
|
sudo loginctl enable-linger <username>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Paths and bind mounts
|
|
||||||
|
|
||||||
- Ensure bind-mount source directories exist before first start.
|
- Ensure bind-mount source directories exist before first start.
|
||||||
- Normalize relative source paths against the source Compose file directory or the directory the user specifies.
|
- Normalize relative source paths against the source Compose file directory or the directory the user specifies.
|
||||||
- Emit absolute host paths in generated Quadlet files when using bind mounts.
|
- Emit absolute host paths in generated Quadlet files when using bind mounts.
|
||||||
- Explain the resolved absolute path if the source used `./...`.
|
|
||||||
|
|
||||||
## Recommended service defaults
|
## Optional Enhancements
|
||||||
|
|
||||||
Depending on the workload, consider adding:
|
- `AutoUpdate=registry` for opt-in automatic image refresh workflows when the approved image strategy uses fully qualified registry images
|
||||||
|
- explicit `.volume` or `.network` units when the user wants declarative infrastructure instead of implicit Podman objects
|
||||||
|
- service defaults such as:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Service]
|
[Service]
|
||||||
@@ -45,11 +85,6 @@ TimeoutStartSec=900
|
|||||||
|
|
||||||
Use the timeout especially when first start may need to pull large images or build locally.
|
Use the timeout especially when first start may need to pull large images or build locally.
|
||||||
|
|
||||||
## Useful optional enhancements
|
## Output Language
|
||||||
|
|
||||||
- `AutoUpdate=registry` for opt-in automatic image refresh workflows
|
|
||||||
- explicit `.volume` or `.network` units when the user wants declarative infrastructure instead of implicit Podman objects
|
|
||||||
|
|
||||||
## Output language
|
|
||||||
|
|
||||||
If you generate a README, deployment note, or operator-facing document as part of the migration, write it in the user's language unless the user explicitly asks for another language.
|
If you generate a README, deployment note, or operator-facing document as part of the migration, write it in the user's language unless the user explicitly asks for another language.
|
||||||
|
|||||||
@@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
Use this file whenever the migration includes `.env`, `env_file`, Compose interpolation, or inline `-e` flags.
|
Use this file whenever the migration includes `.env`, `env_file`, Compose interpolation, or inline `-e` flags.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- Goals
|
||||||
|
- Default rules
|
||||||
|
- Sensitive values
|
||||||
|
- Interpolation
|
||||||
|
- Completeness validation
|
||||||
|
- Examples and checklists
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
- preserve source-of-truth for variables
|
- preserve source-of-truth for variables
|
||||||
@@ -9,11 +18,23 @@ Use this file whenever the migration includes `.env`, `env_file`, Compose interp
|
|||||||
- keep resulting units readable
|
- keep resulting units readable
|
||||||
- report missing variables explicitly
|
- report missing variables explicitly
|
||||||
- reduce large upstream env templates into a small set of user decisions
|
- reduce large upstream env templates into a small set of user decisions
|
||||||
|
- validate env completeness before claiming runnable output
|
||||||
|
|
||||||
## Default rules
|
## Default rules
|
||||||
|
|
||||||
The agent should actively interpret the env template and its comments. Do not offload the entire env review back to the user.
|
The agent should actively interpret the env template and its comments. Do not offload the entire env review back to the user.
|
||||||
|
|
||||||
|
Runnable output requires an env completeness check, not just env summarization.
|
||||||
|
A variable is not considered satisfied unless it is present in one of the actual final output sources:
|
||||||
|
|
||||||
|
- `Environment=` in generated Quadlet
|
||||||
|
- the final `EnvironmentFile=` contents
|
||||||
|
- a documented default that is intentionally preserved in the runnable result
|
||||||
|
- an explicit placeholder, but only when the result is intentionally not yet runnable
|
||||||
|
|
||||||
|
If a variable is still absent from the actual output sources, keep it unresolved.
|
||||||
|
Do not silently downgrade a startup-critical variable into an informational note.
|
||||||
|
|
||||||
### Prefer `Environment=` when
|
### Prefer `Environment=` when
|
||||||
|
|
||||||
- there are only a few variables
|
- there are only a few variables
|
||||||
@@ -59,6 +80,23 @@ Strategy:
|
|||||||
|
|
||||||
Do not fabricate values.
|
Do not fabricate values.
|
||||||
|
|
||||||
|
## Env completeness validation
|
||||||
|
|
||||||
|
Before producing runnable artifacts:
|
||||||
|
|
||||||
|
- compare variables referenced by Compose, interpolation, docs, startup scripts, and image-specific setup guidance against the variables present in the final output
|
||||||
|
- verify that every `EnvironmentFile=` referenced in the final result actually contains the required keys the service depends on
|
||||||
|
- treat missing bootstrap credentials for common stateful services as unresolved required variables, not optional omissions
|
||||||
|
- if a high-similarity near-match exists, flag it as a likely typo instead of silently accepting it
|
||||||
|
|
||||||
|
Examples of suspicious mismatches:
|
||||||
|
|
||||||
|
- `POSTGRES_PASSWRD` vs `POSTGRES_PASSWORD`
|
||||||
|
- singular/plural mismatches such as `ALLOWED_HOST` vs `ALLOWED_HOSTS`
|
||||||
|
- prefix mismatches where the docs and final env disagree on the canonical key name
|
||||||
|
|
||||||
|
If a required key is mentioned in the source docs, image guidance, or startup scripts but is absent from the final output sources, stop before claiming runnable output.
|
||||||
|
|
||||||
## Agent responsibility
|
## Agent responsibility
|
||||||
|
|
||||||
When the source project ships a large `.env.example` or multiple env templates:
|
When the source project ships a large `.env.example` or multiple env templates:
|
||||||
@@ -67,6 +105,7 @@ When the source project ships a large `.env.example` or multiple env templates:
|
|||||||
- determine which values can safely stay at documented defaults
|
- determine which values can safely stay at documented defaults
|
||||||
- determine which values are true deployment decisions and must be confirmed with the user
|
- determine which values are true deployment decisions and must be confirmed with the user
|
||||||
- prepare a candidate `.env` or env delta instead of asking the user to read the whole template manually
|
- prepare a candidate `.env` or env delta instead of asking the user to read the whole template manually
|
||||||
|
- verify that the final env output still contains the variables needed for minimal startup
|
||||||
|
|
||||||
The user should only need to answer the small number of high-impact questions that cannot be discovered locally.
|
The user should only need to answer the small number of high-impact questions that cannot be discovered locally.
|
||||||
|
|
||||||
@@ -123,6 +162,20 @@ Recommended behavior:
|
|||||||
- ask the user only for high-impact values such as domain, storage path, or database password
|
- ask the user only for high-impact values such as domain, storage path, or database password
|
||||||
- generate a candidate `.env` or env delta with clear placeholders for the unresolved items
|
- generate a candidate `.env` or env delta with clear placeholders for the unresolved items
|
||||||
|
|
||||||
|
### Required startup variable still missing
|
||||||
|
|
||||||
|
Source intent:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Container]
|
||||||
|
EnvironmentFile=/home/nite/pod/myapp/myapp.env
|
||||||
|
Environment=APP_ENV=production
|
||||||
|
Environment=APP_PORT=8080
|
||||||
|
```
|
||||||
|
|
||||||
|
If `myapp.env` does not contain `APP_SECRET`, do not treat this as runnable output.
|
||||||
|
Report `APP_SECRET` as unresolved and stop before final runnable generation.
|
||||||
|
|
||||||
## Output patterns
|
## Output patterns
|
||||||
|
|
||||||
### Small inline set
|
### Small inline set
|
||||||
@@ -150,6 +203,25 @@ Environment=APP_ENV=production
|
|||||||
EnvironmentFile=/opt/myapp/myapp.env
|
EnvironmentFile=/opt/myapp/myapp.env
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Finalize checklist template
|
||||||
|
|
||||||
|
Before freezing the env plan, confirm:
|
||||||
|
|
||||||
|
- which keys are satisfied by `Environment=`
|
||||||
|
- which keys are satisfied by the final `EnvironmentFile=`
|
||||||
|
- which keys are preserved via documented defaults
|
||||||
|
- which keys remain unresolved and therefore block runnable output
|
||||||
|
- which keys look like typo candidates and need human confirmation
|
||||||
|
|
||||||
|
## Execution checklist template
|
||||||
|
|
||||||
|
Before writing runnable artifacts, confirm:
|
||||||
|
|
||||||
|
- the final env file contains every required startup key
|
||||||
|
- every `EnvironmentFile=` path in the generated Quadlet matches an actual generated or preserved file
|
||||||
|
- placeholder values are clearly marked and do not masquerade as confirmed production values
|
||||||
|
- typo-suspect keys are either corrected or explicitly surfaced in the output
|
||||||
|
|
||||||
## Missing-variable reporting
|
## Missing-variable reporting
|
||||||
|
|
||||||
When variables cannot be resolved, report them as a concrete checklist.
|
When variables cannot be resolved, report them as a concrete checklist.
|
||||||
@@ -159,6 +231,7 @@ Example:
|
|||||||
- missing `DB_PASSWORD`
|
- missing `DB_PASSWORD`
|
||||||
- missing `IMMICH_VERSION`
|
- missing `IMMICH_VERSION`
|
||||||
- missing `UPLOAD_LOCATION`
|
- missing `UPLOAD_LOCATION`
|
||||||
|
- likely typo: `POSTGRES_PASSWRD` should probably be `POSTGRES_PASSWORD`
|
||||||
|
|
||||||
If the user asks for scaffolding, generate a sample env file with obvious placeholders.
|
If the user asks for scaffolding, generate a sample env file with obvious placeholders.
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
Use this file when the user provides a GitHub repository URL and expects you to find the deployment inputs yourself.
|
Use this file when the user provides a GitHub repository URL and expects you to find the deployment inputs yourself.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- Goal
|
||||||
|
- Discovery order
|
||||||
|
- What to extract
|
||||||
|
- Heuristics
|
||||||
|
- Support-file checklist
|
||||||
|
- Reporting expectations
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
Discover the canonical self-hosting assets before attempting any Quadlet conversion.
|
Discover the canonical self-hosting assets before attempting any Quadlet conversion.
|
||||||
@@ -29,15 +38,18 @@ Discover the canonical self-hosting assets before attempting any Quadlet convers
|
|||||||
- `.devcontainer/`
|
- `.devcontainer/`
|
||||||
6. Read deployment-specific README files in those directories.
|
6. Read deployment-specific README files in those directories.
|
||||||
7. Identify helper scripts that generate or sync compose files.
|
7. Identify helper scripts that generate or sync compose files.
|
||||||
|
8. Identify repo-local companion files required at runtime, such as mounted config, templates, initialization files, seed data, bootstrap assets, entrypoint scripts, and bind-mounted directory trees.
|
||||||
|
|
||||||
## What to extract
|
## What to extract
|
||||||
|
|
||||||
- canonical compose file path
|
- canonical compose file path
|
||||||
- companion env template path
|
- companion env template path
|
||||||
- additional compose files used for middleware or optional services
|
- additional compose files used for middleware or optional services
|
||||||
|
- repo-local companion files required for runtime, such as config, templates, initialization files, bootstrap assets, entrypoint scripts, or mounted directories
|
||||||
- whether the compose file is generated
|
- whether the compose file is generated
|
||||||
- whether the source relies on profiles
|
- whether the source relies on profiles
|
||||||
- whether startup requires preparatory steps such as copying `.env.example` to `.env`
|
- whether startup requires preparatory steps such as copying `.env.example` to `.env`
|
||||||
|
- whether those companion files must be copied, rendered, or kept in a specific relative layout for the deployment to work
|
||||||
|
|
||||||
## Heuristics
|
## Heuristics
|
||||||
|
|
||||||
@@ -46,12 +58,30 @@ Discover the canonical self-hosting assets before attempting any Quadlet convers
|
|||||||
- If the repo has both a template and a generated compose file, treat the generated file as the runnable source and the template as explanatory context.
|
- If the repo has both a template and a generated compose file, treat the generated file as the runnable source and the template as explanatory context.
|
||||||
- If profiles control optional databases or vector stores, decide which profile set the user actually wants before generating Quadlet.
|
- If profiles control optional databases or vector stores, decide which profile set the user actually wants before generating Quadlet.
|
||||||
- If env management is mandatory, preserve that pattern rather than flattening hundreds of variables into inline `Environment=` values.
|
- If env management is mandatory, preserve that pattern rather than flattening hundreds of variables into inline `Environment=` values.
|
||||||
|
- If the source mounts or references repo-local config, templates, initialization assets, entrypoint scripts, or directory trees, treat them as first-class deployment inputs rather than incidental files.
|
||||||
|
- If a Compose bind mount points to a repo-relative file or directory, treat that path as a candidate support-file source rather than only recording the mount string.
|
||||||
|
- If docs or startup scripts say to copy, edit, mount, or render a repo-local file before startup, include that asset in the deliverable review set.
|
||||||
|
- If a whole directory is mounted, inspect the directory contents and preserve the required files instead of only naming the directory root.
|
||||||
|
- Do not reduce runnable output to only Quadlet plus env when the source project depends on additional repo-local assets.
|
||||||
- If several candidate compose files exist, explain which one you selected and why.
|
- If several candidate compose files exist, explain which one you selected and why.
|
||||||
|
|
||||||
## Migration posture for GitHub-sourced projects
|
## Support-file checklist
|
||||||
|
|
||||||
|
Before choosing the final source of truth, confirm:
|
||||||
|
|
||||||
|
- which repo-local files are mounted directly
|
||||||
|
- which repo-local directories are mounted as whole trees
|
||||||
|
- which startup docs require copying, editing, or rendering companion files
|
||||||
|
- which entrypoint or helper scripts refer to additional local assets
|
||||||
|
- which companion files are mandatory for minimal startup versus optional extras
|
||||||
|
|
||||||
|
Use this checklist to prevent reducing the deliverable to Quadlet plus env when the source project depends on more than that.
|
||||||
|
|
||||||
|
## Reporting expectations
|
||||||
|
|
||||||
When converting a GitHub-hosted project, report:
|
When converting a GitHub-hosted project, report:
|
||||||
|
|
||||||
- which files you chose as source of truth
|
- which files you chose as source of truth
|
||||||
|
- which required repo-local companion files must ship with the result
|
||||||
- which optional files or profiles you ignored
|
- which optional files or profiles you ignored
|
||||||
- which variables still require user decisions
|
- which variables still require user decisions
|
||||||
|
|||||||
+218
-193
@@ -6,7 +6,7 @@ podman\-systemd.unit - systemd units using Podman Quadlet
|
|||||||
|
|
||||||
## SYNOPSIS
|
## SYNOPSIS
|
||||||
|
|
||||||
*name*.container, *name*.volume, *name*.network, *name*.kube *name*.image, *name*.build *name*.pod, *name*.artifact
|
_name_.container, _name_.volume, _name_.network, _name_.kube _name_.image, _name_.build _name_.pod, _name_.artifact
|
||||||
|
|
||||||
### Podman rootful unit search path
|
### Podman rootful unit search path
|
||||||
|
|
||||||
@@ -14,26 +14,26 @@ Quadlet files for the root user can be placed in the following directories order
|
|||||||
|
|
||||||
Temporary quadlets, usually used for testing:
|
Temporary quadlets, usually used for testing:
|
||||||
|
|
||||||
* /run/containers/systemd/
|
- /run/containers/systemd/
|
||||||
|
|
||||||
System administrator's defined quadlets:
|
System administrator's defined quadlets:
|
||||||
|
|
||||||
* /etc/containers/systemd/
|
- /etc/containers/systemd/
|
||||||
|
|
||||||
Distribution defined quadlets:
|
Distribution defined quadlets:
|
||||||
|
|
||||||
* /usr/share/containers/systemd/
|
- /usr/share/containers/systemd/
|
||||||
|
|
||||||
### Podman rootless unit search path
|
### Podman rootless unit search path
|
||||||
|
|
||||||
Quadlet files for non-root users can be placed in the following directories:
|
Quadlet files for non-root users can be placed in the following directories:
|
||||||
|
|
||||||
* $XDG_RUNTIME_DIR/containers/systemd/
|
- $XDG_RUNTIME_DIR/containers/systemd/
|
||||||
* $XDG_CONFIG_HOME/containers/systemd/ or ~/.config/containers/systemd/
|
- $XDG_CONFIG_HOME/containers/systemd/ or ~/.config/containers/systemd/
|
||||||
* /etc/containers/systemd/users/${UID}
|
- /etc/containers/systemd/users/${UID}
|
||||||
* /etc/containers/systemd/users/
|
- /etc/containers/systemd/users/
|
||||||
* /usr/share/containers/systemd/users/${UID}
|
- /usr/share/containers/systemd/users/${UID}
|
||||||
* /usr/share/containers/systemd/users/
|
- /usr/share/containers/systemd/users/
|
||||||
|
|
||||||
### Using symbolic links
|
### Using symbolic links
|
||||||
|
|
||||||
@@ -91,9 +91,9 @@ and add the unit file to one of the above rootless unit search paths.
|
|||||||
|
|
||||||
When a Quadlet unit starts, Podman may need to pull or build container images, which can take significantly longer
|
When a Quadlet unit starts, Podman may need to pull or build container images, which can take significantly longer
|
||||||
than systemd's default 90-second service startup limit. If this causes the unit to fail, you can either pre-pull the
|
than systemd's default 90-second service startup limit. If this causes the unit to fail, you can either pre-pull the
|
||||||
required images or increase the service's startup timeout using the *TimeoutStartSec* option. Keep in mind, however,
|
required images or increase the service's startup timeout using the _TimeoutStartSec_ option. Keep in mind, however,
|
||||||
that for units that specify `Type=oneshot`, the startup timeout is disabled by default (set to infinity), so
|
that for units that specify `Type=oneshot`, the startup timeout is disabled by default (set to infinity), so
|
||||||
*TimeoutStartSec* must be explicitly configured if a timeout is desired. For further details on *TimeoutStartSec*, see `systemd.service(5)`.
|
_TimeoutStartSec_ must be explicitly configured if a timeout is desired. For further details on _TimeoutStartSec_, see `systemd.service(5)`.
|
||||||
|
|
||||||
Adding the following snippet to a Quadlet file extends the startup timeout to 15 minutes.
|
Adding the following snippet to a Quadlet file extends the startup timeout to 15 minutes.
|
||||||
|
|
||||||
@@ -119,6 +119,7 @@ leaves the job in a "started" state which prevents subsequent activations by the
|
|||||||
`systemd.service(5)` man page.
|
`systemd.service(5)` man page.
|
||||||
|
|
||||||
Examples for such cases:
|
Examples for such cases:
|
||||||
|
|
||||||
- `.container` file with an image that exits after their entrypoint has finished
|
- `.container` file with an image that exits after their entrypoint has finished
|
||||||
|
|
||||||
- `.kube` file pointing to a Kubernetes Yaml file that does not define any containers. E.g. PVCs only
|
- `.kube` file pointing to a Kubernetes Yaml file that does not define any containers. E.g. PVCs only
|
||||||
@@ -203,6 +204,7 @@ In addition, if you do `ln -s sleep@.container sleep@10.container` you
|
|||||||
will also have a 10 second sleep running at boot. And, if you want
|
will also have a 10 second sleep running at boot. And, if you want
|
||||||
that particular instance to be running with another image, you can
|
that particular instance to be running with another image, you can
|
||||||
create a drop-in file like `sleep@10.container.d/10-image.conf`:
|
create a drop-in file like `sleep@10.container.d/10-image.conf`:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Container]
|
[Container]
|
||||||
Image=quay.io/centos/centos
|
Image=quay.io/centos/centos
|
||||||
@@ -216,6 +218,7 @@ to mount a distinct volume. In this case you can create a template Quadlet
|
|||||||
`foo-data@.volume` (the name is arbitrary) and reference it in `foo@.container`:
|
`foo-data@.volume` (the name is arbitrary) and reference it in `foo@.container`:
|
||||||
|
|
||||||
`foo-data@.volume`:
|
`foo-data@.volume`:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Volume]
|
[Volume]
|
||||||
# Optional: without an explicit VolumeName, Quadlet auto-generates one with a
|
# Optional: without an explicit VolumeName, Quadlet auto-generates one with a
|
||||||
@@ -225,6 +228,7 @@ VolumeName=my-name-%i
|
|||||||
```
|
```
|
||||||
|
|
||||||
`foo@.container`:
|
`foo@.container`:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Container]
|
[Container]
|
||||||
Volume=foo-data@.volume:/mnt/path
|
Volume=foo-data@.volume:/mnt/path
|
||||||
@@ -257,11 +261,13 @@ used an option from a newer version of Podman Quadlet and the
|
|||||||
generator failed to create a service file.
|
generator failed to create a service file.
|
||||||
|
|
||||||
View the generated files and/or error messages with:
|
View the generated files and/or error messages with:
|
||||||
|
|
||||||
```
|
```
|
||||||
/usr/lib/systemd/system-generators/podman-system-generator {--user} --dryrun
|
/usr/lib/systemd/system-generators/podman-system-generator {--user} --dryrun
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, show only the errors with:
|
Alternatively, show only the errors with:
|
||||||
|
|
||||||
```
|
```
|
||||||
systemd-analyze {--user} --generators=true verify example.service
|
systemd-analyze {--user} --generators=true verify example.service
|
||||||
```
|
```
|
||||||
@@ -302,6 +308,7 @@ Quadlet will automatically translate dependencies, specified in the keys
|
|||||||
of the `[Unit]` section, between different Quadlet units.
|
of the `[Unit]` section, between different Quadlet units.
|
||||||
|
|
||||||
For example the `fedora.container` unit below specifies a dependency on the `basic.container` unit.
|
For example the `fedora.container` unit below specifies a dependency on the `basic.container` unit.
|
||||||
|
|
||||||
```
|
```
|
||||||
[Unit]
|
[Unit]
|
||||||
After=basic.container
|
After=basic.container
|
||||||
@@ -335,97 +342,97 @@ There is only one required key, `Image`, which defines the container image the s
|
|||||||
|
|
||||||
Valid options for `[Container]` are listed below:
|
Valid options for `[Container]` are listed below:
|
||||||
|
|
||||||
| **[Container] options** | **podman run equivalent** |
|
| **[Container] options** | **podman run equivalent** |
|
||||||
|--------------------------------------|------------------------------------------------------|
|
| ----------------------------------- | ---------------------------------------------------- |
|
||||||
| AddCapability=CAP | --cap-add CAP |
|
| AddCapability=CAP | --cap-add CAP |
|
||||||
| AddDevice=/dev/foo | --device /dev/foo |
|
| AddDevice=/dev/foo | --device /dev/foo |
|
||||||
| AddHost=example\.com:192.168.10.11 | --add-host example.com:192.168.10.11 |
|
| AddHost=example\.com:192.168.10.11 | --add-host example.com:192.168.10.11 |
|
||||||
| Annotation="XYZ" | --annotation "XYZ" |
|
| Annotation="XYZ" | --annotation "XYZ" |
|
||||||
| AppArmor="alternate-profile" | --security-opt apparmor=alternate-profile |
|
| AppArmor="alternate-profile" | --security-opt apparmor=alternate-profile |
|
||||||
| AutoUpdate=registry | --label "io.containers.autoupdate=registry" |
|
| AutoUpdate=registry | --label "io.containers.autoupdate=registry" |
|
||||||
| CgroupsMode=no-conmon | --cgroups=no-conmon |
|
| CgroupsMode=no-conmon | --cgroups=no-conmon |
|
||||||
| ContainerName=name | --name name |
|
| ContainerName=name | --name name |
|
||||||
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
||||||
| DNS=192.168.55.1 | --dns=192.168.55.1 |
|
| DNS=192.168.55.1 | --dns=192.168.55.1 |
|
||||||
| DNSOption=ndots:1 | --dns-option=ndots:1 |
|
| DNSOption=ndots:1 | --dns-option=ndots:1 |
|
||||||
| DNSSearch=example.com | --dns-search example.com |
|
| DNSSearch=example.com | --dns-search example.com |
|
||||||
| DropCapability=CAP | --cap-drop=CAP |
|
| DropCapability=CAP | --cap-drop=CAP |
|
||||||
| Entrypoint=/foo.sh | --entrypoint=/foo.sh |
|
| Entrypoint=/foo.sh | --entrypoint=/foo.sh |
|
||||||
| Environment=foo=bar | --env foo=bar |
|
| Environment=foo=bar | --env foo=bar |
|
||||||
| EnvironmentFile=/tmp/env | --env-file /tmp/env |
|
| EnvironmentFile=/tmp/env | --env-file /tmp/env |
|
||||||
| EnvironmentHost=true | --env-host |
|
| EnvironmentHost=true | --env-host |
|
||||||
| Exec=/usr/bin/command | Command after image specification - /usr/bin/command |
|
| Exec=/usr/bin/command | Command after image specification - /usr/bin/command |
|
||||||
| ExposeHostPort=50-59 | --expose 50-59 |
|
| ExposeHostPort=50-59 | --expose 50-59 |
|
||||||
| GIDMap=0:10000:10 | --gidmap=0:10000:10 |
|
| GIDMap=0:10000:10 | --gidmap=0:10000:10 |
|
||||||
| GlobalArgs=--log-level=debug | --log-level=debug |
|
| GlobalArgs=--log-level=debug | --log-level=debug |
|
||||||
| Group=1234 | --user UID:1234 |
|
| Group=1234 | --user UID:1234 |
|
||||||
| GroupAdd=keep-groups | --group-add=keep-groups |
|
| GroupAdd=keep-groups | --group-add=keep-groups |
|
||||||
| HealthCmd=/usr/bin/command | --health-cmd=/usr/bin/command |
|
| HealthCmd=/usr/bin/command | --health-cmd=/usr/bin/command |
|
||||||
| HealthInterval=2m | --health-interval=2m |
|
| HealthInterval=2m | --health-interval=2m |
|
||||||
| HealthLogDestination=/foo/log | --health-log-destination=/foo/log |
|
| HealthLogDestination=/foo/log | --health-log-destination=/foo/log |
|
||||||
| HealthMaxLogCount=5 | --health-max-log-count=5 |
|
| HealthMaxLogCount=5 | --health-max-log-count=5 |
|
||||||
| HealthMaxLogSize=500 | --health-max-log-size=500 |
|
| HealthMaxLogSize=500 | --health-max-log-size=500 |
|
||||||
| HealthOnFailure=kill | --health-on-failure=kill |
|
| HealthOnFailure=kill | --health-on-failure=kill |
|
||||||
| HealthRetries=5 | --health-retries=5 |
|
| HealthRetries=5 | --health-retries=5 |
|
||||||
| HealthStartPeriod=1m | --health-start-period=1m |
|
| HealthStartPeriod=1m | --health-start-period=1m |
|
||||||
| HealthStartupCmd=command | --health-startup-cmd=command |
|
| HealthStartupCmd=command | --health-startup-cmd=command |
|
||||||
| HealthStartupInterval=1m | --health-startup-interval=1m |
|
| HealthStartupInterval=1m | --health-startup-interval=1m |
|
||||||
| HealthStartupRetries=8 | --health-startup-retries=8 |
|
| HealthStartupRetries=8 | --health-startup-retries=8 |
|
||||||
| HealthStartupSuccess=2 | --health-startup-success=2 |
|
| HealthStartupSuccess=2 | --health-startup-success=2 |
|
||||||
| HealthStartupTimeout=1m33s | --health-startup-timeout=1m33s |
|
| HealthStartupTimeout=1m33s | --health-startup-timeout=1m33s |
|
||||||
| HealthTimeout=20s | --health-timeout=20s |
|
| HealthTimeout=20s | --health-timeout=20s |
|
||||||
| HostName=example.com | --hostname example.com |
|
| HostName=example.com | --hostname example.com |
|
||||||
| HttpProxy=true | --http-proxy=true |
|
| HttpProxy=true | --http-proxy=true |
|
||||||
| Image=ubi8 | Image specification - ubi8 |
|
| Image=ubi8 | Image specification - ubi8 |
|
||||||
| IP=192.5.0.1 | --ip 192.5.0.1 |
|
| IP=192.5.0.1 | --ip 192.5.0.1 |
|
||||||
| IP6=2001:db8::1 | --ip6 2001:db8::1 |
|
| IP6=2001:db8::1 | --ip6 2001:db8::1 |
|
||||||
| Label="XYZ" | --label "XYZ" |
|
| Label="XYZ" | --label "XYZ" |
|
||||||
| LogDriver=journald | --log-driver journald |
|
| LogDriver=journald | --log-driver journald |
|
||||||
| LogOpt=path=/var/log/mykube\.json | --log-opt path=/var/log/mykube\.json |
|
| LogOpt=path=/var/log/mykube\.json | --log-opt path=/var/log/mykube\.json |
|
||||||
| Mask=/proc/sys/foo\:/proc/sys/bar | --security-opt mask=/proc/sys/foo:/proc/sys/bar |
|
| Mask=/proc/sys/foo\:/proc/sys/bar | --security-opt mask=/proc/sys/foo:/proc/sys/bar |
|
||||||
| Memory=20g | --memory 20g |
|
| Memory=20g | --memory 20g |
|
||||||
| Mount=type=... | --mount type=... |
|
| Mount=type=... | --mount type=... |
|
||||||
| Network=host | --network host |
|
| Network=host | --network host |
|
||||||
| NetworkAlias=name | --network-alias name |
|
| NetworkAlias=name | --network-alias name |
|
||||||
| NoNewPrivileges=true | --security-opt no-new-privileges |
|
| NoNewPrivileges=true | --security-opt no-new-privileges |
|
||||||
| Notify=true | --sdnotify container |
|
| Notify=true | --sdnotify container |
|
||||||
| PidsLimit=10000 | --pids-limit 10000 |
|
| PidsLimit=10000 | --pids-limit 10000 |
|
||||||
| Pod=pod-name | --pod=pod-name |
|
| Pod=pod-name | --pod=pod-name |
|
||||||
| PodmanArgs=--publish 8080:80 | --publish 8080:80 |
|
| PodmanArgs=--publish 8080:80 | --publish 8080:80 |
|
||||||
| PublishPort=8080:80 | --publish 8080:80 |
|
| PublishPort=8080:80 | --publish 8080:80 |
|
||||||
| Pull=never | --pull never |
|
| Pull=never | --pull never |
|
||||||
| ReadOnly=true | --read-only |
|
| ReadOnly=true | --read-only |
|
||||||
| ReadOnlyTmpfs=true | --read-only-tmpfs |
|
| ReadOnlyTmpfs=true | --read-only-tmpfs |
|
||||||
| ReloadCmd=/usr/bin/command | Add ExecReload and run exec with the value |
|
| ReloadCmd=/usr/bin/command | Add ExecReload and run exec with the value |
|
||||||
| ReloadSignal=SIGHUP | Add ExecReload and run kill with the signal |
|
| ReloadSignal=SIGHUP | Add ExecReload and run kill with the signal |
|
||||||
| Retry=5 | --retry=5 |
|
| Retry=5 | --retry=5 |
|
||||||
| RetryDelay=5s | --retry-delay=5s |
|
| RetryDelay=5s | --retry-delay=5s |
|
||||||
| Rootfs=/var/lib/rootfs | --rootfs /var/lib/rootfs |
|
| Rootfs=/var/lib/rootfs | --rootfs /var/lib/rootfs |
|
||||||
| RunInit=true | --init |
|
| RunInit=true | --init |
|
||||||
| SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json |
|
| SeccompProfile=/tmp/s.json | --security-opt seccomp=/tmp/s.json |
|
||||||
| Secret=secret | --secret=secret[,opt=opt ...] |
|
| Secret=secret | --secret=secret[,opt=opt ...] |
|
||||||
| SecurityLabelDisable=true | --security-opt label=disable |
|
| SecurityLabelDisable=true | --security-opt label=disable |
|
||||||
| SecurityLabelFileType=usr_t | --security-opt label=filetype:usr_t |
|
| SecurityLabelFileType=usr_t | --security-opt label=filetype:usr_t |
|
||||||
| SecurityLabelLevel=s0:c1,c2 | --security-opt label=level:s0:c1,c2 |
|
| SecurityLabelLevel=s0:c1,c2 | --security-opt label=level:s0:c1,c2 |
|
||||||
| SecurityLabelNested=true | --security-opt label=nested |
|
| SecurityLabelNested=true | --security-opt label=nested |
|
||||||
| SecurityLabelType=spc_t | --security-opt label=type:spc_t |
|
| SecurityLabelType=spc_t | --security-opt label=type:spc_t |
|
||||||
| ServiceName=name | Name the systemd unit `name.service` |
|
| ServiceName=name | Name the systemd unit `name.service` |
|
||||||
| ShmSize=100m | --shm-size=100m |
|
| ShmSize=100m | --shm-size=100m |
|
||||||
| StartWithPod=true | If Pod= is defined, container is started by pod |
|
| StartWithPod=true | If Pod= is defined, container is started by pod |
|
||||||
| StopSignal=SIGINT | --stop-signal=SIGINT |
|
| StopSignal=SIGINT | --stop-signal=SIGINT |
|
||||||
| StopTimeout=20 | --stop-timeout=20 |
|
| StopTimeout=20 | --stop-timeout=20 |
|
||||||
| SubGIDMap=gtest | --subgidname=gtest |
|
| SubGIDMap=gtest | --subgidname=gtest |
|
||||||
| SubUIDMap=utest | --subuidname=utest |
|
| SubUIDMap=utest | --subuidname=utest |
|
||||||
| Sysctl=name=value | --sysctl=name=value |
|
| Sysctl=name=value | --sysctl=name=value |
|
||||||
| Timezone=local | --tz local |
|
| Timezone=local | --tz local |
|
||||||
| Tmpfs=/work | --tmpfs /work |
|
| Tmpfs=/work | --tmpfs /work |
|
||||||
| UIDMap=0:10000:10 | --uidmap=0:10000:10 |
|
| UIDMap=0:10000:10 | --uidmap=0:10000:10 |
|
||||||
| Ulimit=nofile=1000:10000 | --ulimit nofile=1000:10000 |
|
| Ulimit=nofile=1000:10000 | --ulimit nofile=1000:10000 |
|
||||||
| Unmask=ALL | --security-opt unmask=ALL |
|
| Unmask=ALL | --security-opt unmask=ALL |
|
||||||
| User=bin | --user bin |
|
| User=bin | --user bin |
|
||||||
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
||||||
| Volume=/source:/dest | --volume /source:/dest |
|
| Volume=/source:/dest | --volume /source:/dest |
|
||||||
| WorkingDir=$HOME | --workdir $HOME |
|
| WorkingDir=$HOME | --workdir $HOME |
|
||||||
|
|
||||||
Description of `[Container]` section are:
|
Description of `[Container]` section are:
|
||||||
|
|
||||||
@@ -436,6 +443,7 @@ Add these capabilities, in addition to the default Podman capability set, to the
|
|||||||
This is a space separated list of capabilities. This key can be listed multiple times.
|
This is a space separated list of capabilities. This key can be listed multiple times.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
AddCapability=CAP_DAC_OVERRIDE CAP_IPC_OWNER
|
AddCapability=CAP_DAC_OVERRIDE CAP_IPC_OWNER
|
||||||
```
|
```
|
||||||
@@ -453,7 +461,7 @@ This key can be listed multiple times.
|
|||||||
|
|
||||||
### `AddHost=`
|
### `AddHost=`
|
||||||
|
|
||||||
Add host-to-IP mapping to /etc/hosts.
|
Add host-to-IP mapping to /etc/hosts.
|
||||||
The format is `hostname:ip`.
|
The format is `hostname:ip`.
|
||||||
|
|
||||||
Equivalent to the Podman `--add-host` option.
|
Equivalent to the Podman `--add-host` option.
|
||||||
@@ -474,9 +482,9 @@ Sets the apparmor confinement profile for the container. A value of `unconfined`
|
|||||||
|
|
||||||
Indicates whether the container will be auto-updated ([podman-auto-update(1)](podman-auto-update.1.md)). The following values are supported:
|
Indicates whether the container will be auto-updated ([podman-auto-update(1)](podman-auto-update.1.md)). The following values are supported:
|
||||||
|
|
||||||
* `registry`: Requires a fully-qualified image reference (e.g., quay.io/podman/stable:latest) to be used to create the container. This enforcement is necessary to know which image to actually check and pull. If an image ID was used, Podman does not know which image to check/pull anymore.
|
- `registry`: Requires a fully-qualified image reference (e.g., quay.io/podman/stable:latest) to be used to create the container. This enforcement is necessary to know which image to actually check and pull. If an image ID was used, Podman does not know which image to check/pull anymore.
|
||||||
|
|
||||||
* `local`: Tells Podman to compare the image a container is using to the image with its raw name in local storage. If an image is updated locally, Podman simply restarts the systemd unit executing the container.
|
- `local`: Tells Podman to compare the image a container is using to the image with its raw name in local storage. If an image is updated locally, Podman simply restarts the systemd unit executing the container.
|
||||||
|
|
||||||
### `CgroupsMode=`
|
### `CgroupsMode=`
|
||||||
|
|
||||||
@@ -525,6 +533,7 @@ Drop these capabilities from the default podman capability set, or `all` to drop
|
|||||||
This is a space separated list of capabilities. This key can be listed multiple times.
|
This is a space separated list of capabilities. This key can be listed multiple times.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
DropCapability=CAP_DAC_OVERRIDE CAP_IPC_OWNER
|
DropCapability=CAP_DAC_OVERRIDE CAP_IPC_OWNER
|
||||||
```
|
```
|
||||||
@@ -621,9 +630,9 @@ Set the destination of the HealthCheck log. Directory path, local or events_logg
|
|||||||
(Default: local)
|
(Default: local)
|
||||||
Equivalent to the Podman `--health-log-destination` option.
|
Equivalent to the Podman `--health-log-destination` option.
|
||||||
|
|
||||||
* `local`: (default) HealthCheck logs are stored in overlay containers. (For example: `$runroot/healthcheck.log`)
|
- `local`: (default) HealthCheck logs are stored in overlay containers. (For example: `$runroot/healthcheck.log`)
|
||||||
* `directory`: creates a log file named `<container-ID>-healthcheck.log` with HealthCheck logs in the specified directory.
|
- `directory`: creates a log file named `<container-ID>-healthcheck.log` with HealthCheck logs in the specified directory.
|
||||||
* `events_logger`: The log will be written with logging mechanism set by events_logger. It also saves the log to a default directory, for performance on a system with a large number of logs.
|
- `events_logger`: The log will be written with logging mechanism set by events_logger. It also saves the log to a default directory, for performance on a system with a large number of logs.
|
||||||
|
|
||||||
### `HealthMaxLogCount=`
|
### `HealthMaxLogCount=`
|
||||||
|
|
||||||
@@ -710,8 +719,8 @@ The format of the name is the same as when passed to `podman pull`. So, it suppo
|
|||||||
|
|
||||||
Special Cases:
|
Special Cases:
|
||||||
|
|
||||||
* If the `name` of the image ends with `.image`, Quadlet will use the image pulled by the corresponding `.image` file, and the generated systemd service contains a dependency on the `$name-image.service` (or the service name set in the .image file). Note that the corresponding `.image` file must exist.
|
- If the `name` of the image ends with `.image`, Quadlet will use the image pulled by the corresponding `.image` file, and the generated systemd service contains a dependency on the `$name-image.service` (or the service name set in the .image file). Note that the corresponding `.image` file must exist.
|
||||||
* If the `name` of the image ends with `.build`, Quadlet will use the image built by the corresponding `.build` file, and the generated systemd service contains a dependency on the `$name-build.service`. Note: the corresponding `.build` file must exist.
|
- If the `name` of the image ends with `.build`, Quadlet will use the image built by the corresponding `.build` file, and the generated systemd service contains a dependency on the `$name-build.service`. Note: the corresponding `.build` file must exist.
|
||||||
|
|
||||||
### `IP=`
|
### `IP=`
|
||||||
|
|
||||||
@@ -757,8 +766,8 @@ generally has the form `type=TYPE,TYPE-SPECIFIC-OPTION[,...]`.
|
|||||||
|
|
||||||
Special cases:
|
Special cases:
|
||||||
|
|
||||||
* For `type=volume`, if `source` ends with `.volume`, the Podman named volume generated by the corresponding `.volume` file is used.
|
- For `type=volume`, if `source` ends with `.volume`, the Podman named volume generated by the corresponding `.volume` file is used.
|
||||||
* For `type=image`, if `source` ends with `.image`, the image generated by the corresponding `.image` file is used.
|
- For `type=image`, if `source` ends with `.image`, the image generated by the corresponding `.image` file is used.
|
||||||
|
|
||||||
In both cases, the generated systemd service will contain a dependency on the service generated for the corresponding unit. Note: the corresponding `.volume` or `.image` file must exist.
|
In both cases, the generated systemd service will contain a dependency on the service generated for the corresponding unit. Note: the corresponding `.volume` or `.image` file must exist.
|
||||||
|
|
||||||
@@ -772,14 +781,14 @@ not set up networking in the container.
|
|||||||
|
|
||||||
Special cases:
|
Special cases:
|
||||||
|
|
||||||
* If the `name` of the network ends with `.network`, a Podman network called
|
- If the `name` of the network ends with `.network`, a Podman network called
|
||||||
`systemd-$name` is used, and the generated systemd service contains
|
`systemd-$name` is used, and the generated systemd service contains
|
||||||
a dependency on the `$name-network.service`. Such a network can be automatically
|
a dependency on the `$name-network.service`. Such a network can be automatically
|
||||||
created by using a `$name.network` Quadlet file. Note: the corresponding `.network` file must exist.
|
created by using a `$name.network` Quadlet file. Note: the corresponding `.network` file must exist.
|
||||||
|
|
||||||
* If the `name` ends with `.container`,
|
- If the `name` ends with `.container`,
|
||||||
the container will reuse the network stack of another container created by `$name.container`.
|
the container will reuse the network stack of another container created by `$name.container`.
|
||||||
The generated systemd service contains a dependency on `$name.service`. Note: the corresponding `.container` file must exist.
|
The generated systemd service contains a dependency on `$name.service`. Note: the corresponding `.container` file must exist.
|
||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
@@ -822,7 +831,6 @@ The value must take the form of `<name>.pod` and the `.pod` unit must exist.
|
|||||||
|
|
||||||
Quadlet will add all the necessary parameters to link between the container and the pod and between their corresponding services.
|
Quadlet will add all the necessary parameters to link between the container and the pod and between their corresponding services.
|
||||||
|
|
||||||
|
|
||||||
### `PodmanArgs=`
|
### `PodmanArgs=`
|
||||||
|
|
||||||
This key contains a list of arguments passed directly to the end of the `podman run` command
|
This key contains a list of arguments passed directly to the end of the `podman run` command
|
||||||
@@ -988,6 +996,7 @@ Configures namespaced kernel parameters for the container. The format is `Sysctl
|
|||||||
This is a space separated list of kernel parameters. This key can be listed multiple times.
|
This is a space separated list of kernel parameters. This key can be listed multiple times.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
Sysctl=net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.all.use_tempaddr=1
|
Sysctl=net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.all.use_tempaddr=1
|
||||||
```
|
```
|
||||||
@@ -1018,7 +1027,7 @@ This key can be listed multiple times.
|
|||||||
|
|
||||||
### `Unmask=`
|
### `Unmask=`
|
||||||
|
|
||||||
Specify the paths to unmask separated by a colon. unmask=ALL or /path/1:/path/2, or shell expanded paths (/proc/*):
|
Specify the paths to unmask separated by a colon. unmask=ALL or /path/1:/path/2, or shell expanded paths (/proc/\*):
|
||||||
|
|
||||||
If set to `ALL`, Podman will unmask all the paths that are masked or made read-only by default.
|
If set to `ALL`, Podman will unmask all the paths that are masked or made read-only by default.
|
||||||
|
|
||||||
@@ -1048,7 +1057,7 @@ If `SOURCE-VOLUME` starts with `.`, Quadlet resolves the path relative to the lo
|
|||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
|
|
||||||
* If `SOURCE-VOLUME` ends with `.volume`, a Podman named volume called `systemd-$name` is used as the source, and the generated systemd service contains a dependency on the `$name-volume.service`. Note that the corresponding `.volume` file must exist.
|
- If `SOURCE-VOLUME` ends with `.volume`, a Podman named volume called `systemd-$name` is used as the source, and the generated systemd service contains a dependency on the `$name-volume.service`. Note that the corresponding `.volume` file must exist.
|
||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
@@ -1076,39 +1085,39 @@ when containers exit, set `Restart=always` in the `[Service]` section of the `.p
|
|||||||
|
|
||||||
Valid options for `[Pod]` are listed below:
|
Valid options for `[Pod]` are listed below:
|
||||||
|
|
||||||
| **[Pod] options** | **podman pod create equivalent** |
|
| **[Pod] options** | **podman pod create equivalent** |
|
||||||
|-------------------------------------|----------------------------------------|
|
| ----------------------------------- | ------------------------------------ |
|
||||||
| AddHost=example\.com:192.168.10.11 | --add-host example.com:192.168.10.11 |
|
| AddHost=example\.com:192.168.10.11 | --add-host example.com:192.168.10.11 |
|
||||||
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
||||||
| DNS=192.168.55.1 | --dns=192.168.55.1 |
|
| DNS=192.168.55.1 | --dns=192.168.55.1 |
|
||||||
| DNSOption=ndots:1 | --dns-option=ndots:1 |
|
| DNSOption=ndots:1 | --dns-option=ndots:1 |
|
||||||
| DNSSearch=example.com | --dns-search example.com |
|
| DNSSearch=example.com | --dns-search example.com |
|
||||||
| ExitPolicy=stop | --exit-policy stop |
|
| ExitPolicy=stop | --exit-policy stop |
|
||||||
| GIDMap=0:10000:10 | --gidmap=0:10000:10 |
|
| GIDMap=0:10000:10 | --gidmap=0:10000:10 |
|
||||||
| GlobalArgs=--log-level=debug | --log-level=debug |
|
| GlobalArgs=--log-level=debug | --log-level=debug |
|
||||||
| HostName=name | --hostname=name |
|
| HostName=name | --hostname=name |
|
||||||
| IP=192.5.0.1 | --ip 192.5.0.1 |
|
| IP=192.5.0.1 | --ip 192.5.0.1 |
|
||||||
| IP6=2001:db8::1 | --ip6 2001:db8::1 |
|
| IP6=2001:db8::1 | --ip6 2001:db8::1 |
|
||||||
| Label="XYZ" | --label "XYZ" |
|
| Label="XYZ" | --label "XYZ" |
|
||||||
| Network=host | --network host |
|
| Network=host | --network host |
|
||||||
| NetworkAlias=name | --network-alias name |
|
| NetworkAlias=name | --network-alias name |
|
||||||
| PodmanArgs=\-\-cpus=2 | --cpus=2 |
|
| PodmanArgs=\-\-cpus=2 | --cpus=2 |
|
||||||
| PodName=name | --name=name |
|
| PodName=name | --name=name |
|
||||||
| PublishPort=8080:80 | --publish 8080:80 |
|
| PublishPort=8080:80 | --publish 8080:80 |
|
||||||
| ServiceName=name | Name the systemd unit `name.service` |
|
| ServiceName=name | Name the systemd unit `name.service` |
|
||||||
| ShmSize=100m | --shm-size=100m |
|
| ShmSize=100m | --shm-size=100m |
|
||||||
| StopTimeout=20 | --time=20 |
|
| StopTimeout=20 | --time=20 |
|
||||||
| SubGIDMap=gtest | --subgidname=gtest |
|
| SubGIDMap=gtest | --subgidname=gtest |
|
||||||
| SubUIDMap=utest | --subuidname=utest |
|
| SubUIDMap=utest | --subuidname=utest |
|
||||||
| UIDMap=0:10000:10 | --uidmap=0:10000:10 |
|
| UIDMap=0:10000:10 | --uidmap=0:10000:10 |
|
||||||
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
| UserNS=keep-id:uid=200,gid=210 | --userns keep-id:uid=200,gid=210 |
|
||||||
| Volume=/source:/dest | --volume /source:/dest |
|
| Volume=/source:/dest | --volume /source:/dest |
|
||||||
|
|
||||||
Supported keys in the `[Pod]` section are:
|
Supported keys in the `[Pod]` section are:
|
||||||
|
|
||||||
### `AddHost=`
|
### `AddHost=`
|
||||||
|
|
||||||
Add host-to-IP mapping to /etc/hosts.
|
Add host-to-IP mapping to /etc/hosts.
|
||||||
The format is `hostname:ip`.
|
The format is `hostname:ip`.
|
||||||
|
|
||||||
Equivalent to the Podman `--add-host` option.
|
Equivalent to the Podman `--add-host` option.
|
||||||
@@ -1196,7 +1205,7 @@ For example, use `host` to use the host network in the pod, or `none` to not set
|
|||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
|
|
||||||
* If the `name` of the network ends with `.network`, Quadlet will look for the corresponding `.network` Quadlet unit. If found, Quadlet will use the name of the Network set in the Unit, otherwise, `systemd-$name` is used.
|
- If the `name` of the network ends with `.network`, Quadlet will look for the corresponding `.network` Quadlet unit. If found, Quadlet will use the name of the Network set in the Unit, otherwise, `systemd-$name` is used.
|
||||||
|
|
||||||
The generated systemd service contains a dependency on the service unit generated for that `.network` unit. Note: the corresponding `.network` file must exist.
|
The generated systemd service contains a dependency on the service unit generated for that `.network` unit. Note: the corresponding `.network` file must exist.
|
||||||
|
|
||||||
@@ -1252,7 +1261,6 @@ When using `host` networking via `Network=host`, the `PublishPort=` option canno
|
|||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
|
|
||||||
### `ServiceName=`
|
### `ServiceName=`
|
||||||
|
|
||||||
By default, Quadlet will name the systemd service unit by appending `-pod` to the name of the Quadlet.
|
By default, Quadlet will name the systemd service unit by appending `-pod` to the name of the Quadlet.
|
||||||
@@ -1303,7 +1311,7 @@ If `SOURCE-VOLUME` starts with `.`, Quadlet resolves the path relative to the lo
|
|||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
|
|
||||||
* If `SOURCE-VOLUME` ends with `.volume`, Quadlet will look for the corresponding `.volume` Quadlet unit. If found, Quadlet will use the name of the Volume set in the Unit, otherwise, `systemd-$name` is used. Note: the corresponding `.volume` file must exist.
|
- If `SOURCE-VOLUME` ends with `.volume`, Quadlet will look for the corresponding `.volume` Quadlet unit. If found, Quadlet will use the name of the Volume set in the Unit, otherwise, `systemd-$name` is used. Note: the corresponding `.volume` file must exist.
|
||||||
|
|
||||||
The generated systemd service contains a dependency on the service unit generated for that `.volume` unit,
|
The generated systemd service contains a dependency on the service unit generated for that `.volume` unit,
|
||||||
or on `$name-volume.service` if the `.volume` unit is not found.
|
or on `$name-volume.service` if the `.volume` unit is not found.
|
||||||
@@ -1323,7 +1331,7 @@ There is only one required key, `Yaml`, which defines the path to the Kubernetes
|
|||||||
Valid options for `[Kube]` are listed below:
|
Valid options for `[Kube]` are listed below:
|
||||||
|
|
||||||
| **[Kube] options** | **podman kube play equivalent** |
|
| **[Kube] options** | **podman kube play equivalent** |
|
||||||
| ------------------------------------| -----------------------------------------------------------------|
|
| ----------------------------------- | ---------------------------------------------------------------- |
|
||||||
| AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" |
|
| AutoUpdate=registry | --annotation "io.containers.autoupdate=registry" |
|
||||||
| ConfigMap=/tmp/config.map | --config-map /tmp/config.map |
|
| ConfigMap=/tmp/config.map | --config-map /tmp/config.map |
|
||||||
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
||||||
@@ -1345,11 +1353,11 @@ Supported keys in the `[Kube]` section are:
|
|||||||
|
|
||||||
Indicates whether containers will be auto-updated ([podman-auto-update(1)](podman-auto-update.1.md)). AutoUpdate can be specified multiple times. The following values are supported:
|
Indicates whether containers will be auto-updated ([podman-auto-update(1)](podman-auto-update.1.md)). AutoUpdate can be specified multiple times. The following values are supported:
|
||||||
|
|
||||||
* `registry`: Requires a fully-qualified image reference (e.g., quay.io/podman/stable:latest) to be used to create the container. This enforcement is necessary to know which images to actually check and pull. If an image ID was used, Podman does not know which image to check/pull anymore.
|
- `registry`: Requires a fully-qualified image reference (e.g., quay.io/podman/stable:latest) to be used to create the container. This enforcement is necessary to know which images to actually check and pull. If an image ID was used, Podman does not know which image to check/pull anymore.
|
||||||
|
|
||||||
* `local`: Tells Podman to compare the image a container is using to the image with its raw name in local storage. If an image is updated locally, Podman simply restarts the systemd unit executing the Kubernetes Quadlet.
|
- `local`: Tells Podman to compare the image a container is using to the image with its raw name in local storage. If an image is updated locally, Podman simply restarts the systemd unit executing the Kubernetes Quadlet.
|
||||||
|
|
||||||
* `name/(local|registry)`: Tells Podman to perform the `local` or `registry` autoupdate on the specified container name.
|
- `name/(local|registry)`: Tells Podman to perform the `local` or `registry` autoupdate on the specified container name.
|
||||||
|
|
||||||
### `ConfigMap=`
|
### `ConfigMap=`
|
||||||
|
|
||||||
@@ -1368,6 +1376,7 @@ This key can be listed multiple times.
|
|||||||
### `ExitCodePropagation=`
|
### `ExitCodePropagation=`
|
||||||
|
|
||||||
Control how the main PID of the systemd service should exit. The following values are supported:
|
Control how the main PID of the systemd service should exit. The following values are supported:
|
||||||
|
|
||||||
- `all`: exit non-zero if all containers have failed (i.e., exited non-zero)
|
- `all`: exit non-zero if all containers have failed (i.e., exited non-zero)
|
||||||
- `any`: exit non-zero if any container has failed
|
- `any`: exit non-zero if any container has failed
|
||||||
- `none`: exit zero and ignore failed containers
|
- `none`: exit zero and ignore failed containers
|
||||||
@@ -1404,7 +1413,7 @@ not set up networking in the container.
|
|||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
|
|
||||||
* If the `name` of the network ends with `.network`, a Podman network called `systemd-$name` is used, and the generated systemd service contains a dependency on the `$name-network.service`. Such a network can be automatically created by using a `$name.network` Quadlet file. Note: the corresponding `.network` file must exist.
|
- If the `name` of the network ends with `.network`, a Podman network called `systemd-$name` is used, and the generated systemd service contains a dependency on the `$name-network.service`. Such a network can be automatically created by using a `$name.network` Quadlet file. Note: the corresponding `.network` file must exist.
|
||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
@@ -1457,7 +1466,8 @@ Please note that if the `WorkingDirectory` field of the `Service` group is set,
|
|||||||
Quadlet will not set it even if `SetWorkingDirectory` is set
|
Quadlet will not set it even if `SetWorkingDirectory` is set
|
||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
* If multiple `Yaml` path are provided only `unit` is supported.
|
|
||||||
|
- If multiple `Yaml` path are provided only `unit` is supported.
|
||||||
|
|
||||||
### `UserNS=`
|
### `UserNS=`
|
||||||
|
|
||||||
@@ -1490,7 +1500,7 @@ particularly interesting when using special options to control network creation,
|
|||||||
Valid options for `[Network]` are listed below:
|
Valid options for `[Network]` are listed below:
|
||||||
|
|
||||||
| **[Network] options** | **podman network create equivalent** |
|
| **[Network] options** | **podman network create equivalent** |
|
||||||
|-------------------------------------|-----------------------------------------------------------------|
|
| ----------------------------------- | --------------------------------------------------------------- |
|
||||||
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
||||||
| DisableDNS=true | --disable-dns |
|
| DisableDNS=true | --disable-dns |
|
||||||
| DNS=192.168.55.1 | --dns=192.168.55.1 |
|
| DNS=192.168.55.1 | --dns=192.168.55.1 |
|
||||||
@@ -1558,7 +1568,7 @@ This key can be listed multiple times.
|
|||||||
|
|
||||||
### `InterfaceName=`
|
### `InterfaceName=`
|
||||||
|
|
||||||
This option maps the *network_interface* option in the network config, see **podman network inspect**.
|
This option maps the _network_interface_ option in the network config, see **podman network inspect**.
|
||||||
Depending on the driver, this can have different effects; for `bridge`, it uses the bridge interface name.
|
Depending on the driver, this can have different effects; for `bridge`, it uses the bridge interface name.
|
||||||
For `macvlan` and `ipvlan`, it is the parent device on the host. It is the same as `--opt parent=...`.
|
For `macvlan` and `ipvlan`, it is the parent device on the host. It is the same as `--opt parent=...`.
|
||||||
|
|
||||||
@@ -1662,7 +1672,7 @@ as Podman otherwise creates volumes with the default options.
|
|||||||
Valid options for `[Volume]` are listed below:
|
Valid options for `[Volume]` are listed below:
|
||||||
|
|
||||||
| **[Volume] options** | **podman volume create equivalent** |
|
| **[Volume] options** | **podman volume create equivalent** |
|
||||||
|-------------------------------------|-------------------------------------------|
|
| ----------------------------------- | ----------------------------------------- |
|
||||||
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
||||||
| Copy=true | --opt copy |
|
| Copy=true | --opt copy |
|
||||||
| Device=tmpfs | --opt device=tmpfs |
|
| Device=tmpfs | --opt device=tmpfs |
|
||||||
@@ -1734,8 +1744,8 @@ The format of the name is the same as when passed to `podman pull`. So, it suppo
|
|||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
|
|
||||||
* If the `name` of the image ends with `.image`, Quadlet will use the image
|
- If the `name` of the image ends with `.image`, Quadlet will use the image
|
||||||
pulled by the corresponding `.image` file, and the generated systemd service contains a dependency on the `$name-image.service` (or the service name set in the .image file). Note: the corresponding `.image` file must exist.
|
pulled by the corresponding `.image` file, and the generated systemd service contains a dependency on the `$name-image.service` (or the service name set in the .image file). Note: the corresponding `.image` file must exist.
|
||||||
|
|
||||||
### `Label=`
|
### `Label=`
|
||||||
|
|
||||||
@@ -1805,7 +1815,7 @@ testing and development.
|
|||||||
Valid options for `[Build]` are listed below:
|
Valid options for `[Build]` are listed below:
|
||||||
|
|
||||||
| **[Build] options** | **podman build equivalent** |
|
| **[Build] options** | **podman build equivalent** |
|
||||||
|-------------------------------------|---------------------------------------------|
|
| ----------------------------------- | ------------------------------------------- |
|
||||||
| Annotation=annotation=value | --annotation=annotation=value |
|
| Annotation=annotation=value | --annotation=annotation=value |
|
||||||
| Arch=aarch64 | --arch=aarch64 |
|
| Arch=aarch64 | --arch=aarch64 |
|
||||||
| AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json |
|
| AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json |
|
||||||
@@ -1837,7 +1847,7 @@ Valid options for `[Build]` are listed below:
|
|||||||
|
|
||||||
### `Annotation=`
|
### `Annotation=`
|
||||||
|
|
||||||
Add an image *annotation* (e.g. annotation=*value*) to the image metadata. Can be used multiple
|
Add an image _annotation_ (e.g. annotation=_value_) to the image metadata. Can be used multiple
|
||||||
times.
|
times.
|
||||||
|
|
||||||
This is equivalent to the `--annotation` option of `podman build`.
|
This is equivalent to the `--annotation` option of `podman build`.
|
||||||
@@ -1857,7 +1867,7 @@ This is equivalent to the `--authfile` option of `podman build`.
|
|||||||
### `BuildArg=`
|
### `BuildArg=`
|
||||||
|
|
||||||
Specifies a build argument and its value in the same way environment variables are
|
Specifies a build argument and its value in the same way environment variables are
|
||||||
(e.g., env=*value*), but it is not added to the environment variable list in the
|
(e.g., env=_value_), but it is not added to the environment variable list in the
|
||||||
resulting image's configuration. Can be listed multiple times.
|
resulting image's configuration. Can be listed multiple times.
|
||||||
|
|
||||||
This is equivalent to the `--build-arg` option of `podman build`.
|
This is equivalent to the `--build-arg` option of `podman build`.
|
||||||
@@ -1894,7 +1904,7 @@ This is equivalent to the `--dns-search` option of `podman build`.
|
|||||||
|
|
||||||
### `Environment=`
|
### `Environment=`
|
||||||
|
|
||||||
Add a value (e.g. env=*value*) to the built image. This uses the same format as [services in
|
Add a value (e.g. env=_value_) to the built image. This uses the same format as [services in
|
||||||
systemd](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment=) and can be
|
systemd](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment=) and can be
|
||||||
listed multiple times.
|
listed multiple times.
|
||||||
|
|
||||||
@@ -1954,7 +1964,7 @@ This key can be listed multiple times. The first instance will be used as the na
|
|||||||
|
|
||||||
### `Label=`
|
### `Label=`
|
||||||
|
|
||||||
Add an image *label* (e.g. label=*value*) to the image metadata. Can be used multiple times.
|
Add an image _label_ (e.g. label=_value_) to the image metadata. Can be used multiple times.
|
||||||
|
|
||||||
This is equivalent to the `--label` option of `podman build`.
|
This is equivalent to the `--label` option of `podman build`.
|
||||||
|
|
||||||
@@ -1966,7 +1976,7 @@ or `none` to not set up networking.
|
|||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
|
|
||||||
* If the `name` of the network ends with `.network`, Quadlet will look for the corresponding `.network` Quadlet unit. If found, Quadlet will use the name of the Network set in the Unit, otherwise, `systemd-$name` is used. The generated systemd service contains a dependency on the service unit generated for that `.network` unit, or on `$name-network.service` if the `.network` unit is not found. Note: the corresponding `.network` file must exist.
|
- If the `name` of the network ends with `.network`, Quadlet will look for the corresponding `.network` Quadlet unit. If found, Quadlet will use the name of the Network set in the Unit, otherwise, `systemd-$name` is used. The generated systemd service contains a dependency on the service unit generated for that `.network` unit, or on `$name-network.service` if the `.network` unit is not found. Note: the corresponding `.network` file must exist.
|
||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
@@ -2061,7 +2071,7 @@ If `SOURCE-VOLUME` starts with `.`, Quadlet resolves the path relative to the lo
|
|||||||
|
|
||||||
Special case:
|
Special case:
|
||||||
|
|
||||||
* If `SOURCE-VOLUME` ends with `.volume`, Quadlet will look for the corresponding `.volume` Quadlet unit. If found, Quadlet will use the name of the Volume set in the Unit, otherwise, `systemd-$name` is used. The generated systemd service contains a dependency on the service unit generated for that `.volume` unit, or on `$name-volume.service` if the `.volume` unit is not found. Note: the corresponding `.volume` file must exist.
|
- If `SOURCE-VOLUME` ends with `.volume`, Quadlet will look for the corresponding `.volume` Quadlet unit. If found, Quadlet will use the name of the Volume set in the Unit, otherwise, `systemd-$name` is used. The generated systemd service contains a dependency on the service unit generated for that `.volume` unit, or on `$name-volume.service` if the `.volume` unit is not found. Note: the corresponding `.volume` file must exist.
|
||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
@@ -2077,7 +2087,7 @@ particularly interesting when using special options to control image pulls.
|
|||||||
Valid options for `[Image]` are listed below:
|
Valid options for `[Image]` are listed below:
|
||||||
|
|
||||||
| **[Image] options** | **podman image pull equivalent** |
|
| **[Image] options** | **podman image pull equivalent** |
|
||||||
|----------------------------------------|--------------------------------------------------|
|
| -------------------------------------- | ------------------------------------------------ |
|
||||||
| AllTags=true | --all-tags |
|
| AllTags=true | --all-tags |
|
||||||
| Arch=aarch64 | --arch=aarch64 |
|
| Arch=aarch64 | --arch=aarch64 |
|
||||||
| AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json |
|
| AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json |
|
||||||
@@ -2117,7 +2127,7 @@ This is equivalent to the Podman `--authfile` option.
|
|||||||
|
|
||||||
### `CertDir=`
|
### `CertDir=`
|
||||||
|
|
||||||
Use certificates at path (*.crt, *.cert, *.key) to connect to the registry.
|
Use certificates at path (_.crt, _.cert, \*.key) to connect to the registry.
|
||||||
|
|
||||||
This is equivalent to the Podman `--cert-dir` option.
|
This is equivalent to the Podman `--cert-dir` option.
|
||||||
|
|
||||||
@@ -2170,6 +2180,7 @@ For example, an image saved into a `docker-archive` with the following Podman co
|
|||||||
`podman image save --format docker-archive --output /tmp/archive-file.tar quay.io/podman/stable:latest`
|
`podman image save --format docker-archive --output /tmp/archive-file.tar quay.io/podman/stable:latest`
|
||||||
|
|
||||||
requires setting
|
requires setting
|
||||||
|
|
||||||
- `Image=docker-archive:/tmp/archive-file.tar`
|
- `Image=docker-archive:/tmp/archive-file.tar`
|
||||||
- `ImageTag=quay.io/podman/stable:latest`
|
- `ImageTag=quay.io/podman/stable:latest`
|
||||||
|
|
||||||
@@ -2240,21 +2251,21 @@ particularly useful for managing artifacts that containers need to mount or acce
|
|||||||
|
|
||||||
Valid options for `[Artifact]` are listed below:
|
Valid options for `[Artifact]` are listed below:
|
||||||
|
|
||||||
| **[Artifact] options** | **podman artifact pull equivalent** |
|
| **[Artifact] options** | **podman artifact pull equivalent** |
|
||||||
|---------------------------------------------|--------------------------------------------------------|
|
| ----------------------------------------- | ----------------------------------------------------- |
|
||||||
| Artifact=quay\.io/foobar/artifact:special | podman artifact pull quay\.io/foobar/artifact:special |
|
| Artifact=quay\.io/foobar/artifact:special | podman artifact pull quay\.io/foobar/artifact:special |
|
||||||
| AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json |
|
| AuthFile=/etc/registry/auth\.json | --authfile=/etc/registry/auth\.json |
|
||||||
| CertDir=/etc/registry/certs | --cert-dir=/etc/registry/certs |
|
| CertDir=/etc/registry/certs | --cert-dir=/etc/registry/certs |
|
||||||
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
| ContainersConfModule=/etc/nvd\.conf | --module=/etc/nvd\.conf |
|
||||||
| Creds=username:password | --creds=username:password |
|
| Creds=username:password | --creds=username:password |
|
||||||
| DecryptionKey=/etc/registry\.key | --decryption-key=/etc/registry\.key |
|
| DecryptionKey=/etc/registry\.key | --decryption-key=/etc/registry\.key |
|
||||||
| GlobalArgs=--log-level=debug | --log-level=debug |
|
| GlobalArgs=--log-level=debug | --log-level=debug |
|
||||||
| PodmanArgs=--pull never | --pull never |
|
| PodmanArgs=--pull never | --pull never |
|
||||||
| Quiet=true | --quiet |
|
| Quiet=true | --quiet |
|
||||||
| Retry=5 | --retry=5 |
|
| Retry=5 | --retry=5 |
|
||||||
| RetryDelay=10s | --retry-delay=10s |
|
| RetryDelay=10s | --retry-delay=10s |
|
||||||
| ServiceName=my-artifact | Set the systemd service name to my-artifact.service |
|
| ServiceName=my-artifact | Set the systemd service name to my-artifact.service |
|
||||||
| TLSVerify=false | --tls-verify=false |
|
| TLSVerify=false | --tls-verify=false |
|
||||||
|
|
||||||
### `Artifact=`
|
### `Artifact=`
|
||||||
|
|
||||||
@@ -2271,7 +2282,7 @@ This is equivalent to the Podman `--authfile` option.
|
|||||||
|
|
||||||
### `CertDir=`
|
### `CertDir=`
|
||||||
|
|
||||||
Use certificates at path (*.crt, *.cert, *.key) to connect to the registry.
|
Use certificates at path (_.crt, _.cert, \*.key) to connect to the registry.
|
||||||
|
|
||||||
This is equivalent to the Podman `--cert-dir` option.
|
This is equivalent to the Podman `--cert-dir` option.
|
||||||
|
|
||||||
@@ -2343,14 +2354,15 @@ Require HTTPS and verification of certificates when contacting registries.
|
|||||||
This is equivalent to the Podman `--tls-verify` option.
|
This is equivalent to the Podman `--tls-verify` option.
|
||||||
|
|
||||||
## Quadlet section [Quadlet]
|
## Quadlet section [Quadlet]
|
||||||
|
|
||||||
Some quadlet specific configuration is shared between different unit types. Those settings
|
Some quadlet specific configuration is shared between different unit types. Those settings
|
||||||
can be configured in the `[Quadlet]` section.
|
can be configured in the `[Quadlet]` section.
|
||||||
|
|
||||||
Valid options for `[Quadlet]` are listed below:
|
Valid options for `[Quadlet]` are listed below:
|
||||||
|
|
||||||
| **[Quadlet] options** | **Description** |
|
| **[Quadlet] options** | **Description** |
|
||||||
|----------------------------|---------------------------------------------------|
|
| ------------------------- | ------------------------------------------------- |
|
||||||
| DefaultDependencies=false | Disable implicit network dependencies to the unit |
|
| DefaultDependencies=false | Disable implicit network dependencies to the unit |
|
||||||
|
|
||||||
### `DefaultDependencies=`
|
### `DefaultDependencies=`
|
||||||
|
|
||||||
@@ -2395,6 +2407,7 @@ WantedBy=multi-user.target default.target
|
|||||||
```
|
```
|
||||||
|
|
||||||
Example `test.kube`:
|
Example `test.kube`:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=A kubernetes yaml based service
|
Description=A kubernetes yaml based service
|
||||||
@@ -2411,6 +2424,7 @@ WantedBy=multi-user.target default.target
|
|||||||
Example for locally built image to be used in a container with build-specific arguments:
|
Example for locally built image to be used in a container with build-specific arguments:
|
||||||
|
|
||||||
`test.build`
|
`test.build`
|
||||||
|
|
||||||
```
|
```
|
||||||
[Build]
|
[Build]
|
||||||
# Tag the image to be built
|
# Tag the image to be built
|
||||||
@@ -2426,6 +2440,7 @@ BuildArg=VERSION=1.0 \
|
|||||||
```
|
```
|
||||||
|
|
||||||
`test.container`
|
`test.container`
|
||||||
|
|
||||||
```
|
```
|
||||||
[Container]
|
[Container]
|
||||||
Image=test.build
|
Image=test.build
|
||||||
@@ -2441,6 +2456,7 @@ Label=org.test.Key=value
|
|||||||
```
|
```
|
||||||
|
|
||||||
Example `test.network`:
|
Example `test.network`:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Network]
|
[Network]
|
||||||
Subnet=172.16.0.0/24
|
Subnet=172.16.0.0/24
|
||||||
@@ -2450,6 +2466,7 @@ Label=org.test.Key=value
|
|||||||
```
|
```
|
||||||
|
|
||||||
Example `test.artifact` to only pull the artifact using one auth file:
|
Example `test.artifact` to only pull the artifact using one auth file:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Artifact]
|
[Artifact]
|
||||||
Artifact=quay.io/example/my-artifact:latest
|
Artifact=quay.io/example/my-artifact:latest
|
||||||
@@ -2460,12 +2477,14 @@ TLSVerify=false
|
|||||||
Example usage where a container depends on an artifact:
|
Example usage where a container depends on an artifact:
|
||||||
|
|
||||||
`my-artifact.artifact`:
|
`my-artifact.artifact`:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Artifact]
|
[Artifact]
|
||||||
Artifact=quay.io/example/my-config:latest
|
Artifact=quay.io/example/my-config:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
`my-app.container`:
|
`my-app.container`:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Container]
|
[Container]
|
||||||
Image=quay.io/example/my-app:latest
|
Image=quay.io/example/my-app:latest
|
||||||
@@ -2475,12 +2494,14 @@ Mount=type=artifact,source=my-artifact.artifact,destination=/etc/config
|
|||||||
Example for a container in a Pod:
|
Example for a container in a Pod:
|
||||||
|
|
||||||
`test.pod`
|
`test.pod`
|
||||||
|
|
||||||
```
|
```
|
||||||
[Pod]
|
[Pod]
|
||||||
PodName=test
|
PodName=test
|
||||||
```
|
```
|
||||||
|
|
||||||
`centos.container`
|
`centos.container`
|
||||||
|
|
||||||
```
|
```
|
||||||
[Container]
|
[Container]
|
||||||
Image=quay.io/centos/centos:latest
|
Image=quay.io/centos/centos:latest
|
||||||
@@ -2491,6 +2512,7 @@ Pod=test.pod
|
|||||||
Example for a Pod with a one-shot startup task:
|
Example for a Pod with a one-shot startup task:
|
||||||
|
|
||||||
`test.pod`
|
`test.pod`
|
||||||
|
|
||||||
```
|
```
|
||||||
[Pod]
|
[Pod]
|
||||||
PodName=test
|
PodName=test
|
||||||
@@ -2498,6 +2520,7 @@ ExitPolicy=continue
|
|||||||
```
|
```
|
||||||
|
|
||||||
`startup-task.container`
|
`startup-task.container`
|
||||||
|
|
||||||
```
|
```
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
@@ -2510,6 +2533,7 @@ Exec=sh -c "echo 'setup starting'; sleep 2; echo 'setup complete'"
|
|||||||
```
|
```
|
||||||
|
|
||||||
`app.container`
|
`app.container`
|
||||||
|
|
||||||
```
|
```
|
||||||
[Unit]
|
[Unit]
|
||||||
Requires=startup-task.container
|
Requires=startup-task.container
|
||||||
@@ -2548,6 +2572,7 @@ Options=iam_role,endpoint=${AWS_REGION},use_xattr,listobjectsv2,del_cache,use_ca
|
|||||||
```
|
```
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
|
|
||||||
**[systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html)**,
|
**[systemd.unit(5)](https://www.freedesktop.org/software/systemd/man/systemd.unit.html)**,
|
||||||
**[systemd.service(5)](https://www.freedesktop.org/software/systemd/man/systemd.service.html)**,
|
**[systemd.service(5)](https://www.freedesktop.org/software/systemd/man/systemd.service.html)**,
|
||||||
**[systemd-analyze(1)](https://www.freedesktop.org/software/systemd/man/latest/systemd-analyze.html)**,
|
**[systemd-analyze(1)](https://www.freedesktop.org/software/systemd/man/latest/systemd-analyze.html)**,
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Copy reviewed Quadlet unit files into the target Quadlet directory.
|
||||||
|
# Update the variables below before using this template.
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
QUADLET_PREFIX='app-'
|
||||||
|
QUADLET_TARGET_DIR="${HOME}/.config/containers/systemd"
|
||||||
|
|
||||||
|
list_quadlet_files() {
|
||||||
|
for ext in container pod network volume build image kube; do
|
||||||
|
for file in "$SCRIPT_DIR"/"$QUADLET_PREFIX"*."$ext"; do
|
||||||
|
[ -e "$file" ] || continue
|
||||||
|
printf '%s\n' "$file"
|
||||||
|
done
|
||||||
|
done | LC_ALL=C sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
files=$(list_quadlet_files)
|
||||||
|
[ -n "$files" ] || {
|
||||||
|
printf 'No Quadlet files found for prefix %s\n' "$QUADLET_PREFIX" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p -- "$QUADLET_TARGET_DIR"
|
||||||
|
printf '%s\n' "$files" | while IFS= read -r file; do
|
||||||
|
install -m 0644 -- "$file" "$QUADLET_TARGET_DIR/$(basename -- "$file")"
|
||||||
|
done
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Reload systemd after reviewed Quadlet unit changes.
|
||||||
|
# Update the systemctl_cmd() function below before using this template.
|
||||||
|
|
||||||
|
systemctl_cmd() {
|
||||||
|
systemctl --user "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
systemctl_cmd daemon-reload
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Restart the reviewed lifecycle unit(s).
|
||||||
|
# Update the variables and systemctl_cmd() function below before using this template.
|
||||||
|
|
||||||
|
LIFECYCLE_UNITS='app-pod.service'
|
||||||
|
|
||||||
|
systemctl_cmd() {
|
||||||
|
systemctl --user "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
for unit in $LIFECYCLE_UNITS; do
|
||||||
|
systemctl_cmd restart "$unit"
|
||||||
|
done
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Start the reviewed lifecycle unit(s).
|
||||||
|
# Update the variables and systemctl_cmd() function below before using this template.
|
||||||
|
|
||||||
|
LIFECYCLE_UNITS='app-pod.service'
|
||||||
|
|
||||||
|
systemctl_cmd() {
|
||||||
|
systemctl --user "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
for unit in $LIFECYCLE_UNITS; do
|
||||||
|
systemctl_cmd start "$unit"
|
||||||
|
done
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Stop the reviewed lifecycle unit(s).
|
||||||
|
# Update the variables and systemctl_cmd() function below before using this template.
|
||||||
|
|
||||||
|
LIFECYCLE_UNITS='app-pod.service'
|
||||||
|
|
||||||
|
systemctl_cmd() {
|
||||||
|
systemctl --user "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
for unit in $LIFECYCLE_UNITS; do
|
||||||
|
systemctl_cmd stop "$unit"
|
||||||
|
done
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Stop the reviewed lifecycle unit(s), then remove installed Quadlet unit files.
|
||||||
|
# Update the variables and systemctl_cmd() function below before using this template.
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
QUADLET_PREFIX='app-'
|
||||||
|
QUADLET_TARGET_DIR="${HOME}/.config/containers/systemd"
|
||||||
|
LIFECYCLE_UNITS='app-pod.service'
|
||||||
|
|
||||||
|
systemctl_cmd() {
|
||||||
|
systemctl --user "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
list_quadlet_files() {
|
||||||
|
for ext in container pod network volume build image kube; do
|
||||||
|
for file in "$SCRIPT_DIR"/"$QUADLET_PREFIX"*."$ext"; do
|
||||||
|
[ -e "$file" ] || continue
|
||||||
|
printf '%s\n' "$file"
|
||||||
|
done
|
||||||
|
done | LC_ALL=C sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
files=$(list_quadlet_files)
|
||||||
|
[ -n "$files" ] || {
|
||||||
|
printf 'No Quadlet files found for prefix %s\n' "$QUADLET_PREFIX" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for unit in $LIFECYCLE_UNITS; do
|
||||||
|
systemctl_cmd stop "$unit" || true
|
||||||
|
done
|
||||||
|
|
||||||
|
printf '%s\n' "$files" | while IFS= read -r file; do
|
||||||
|
rm -f -- "$QUADLET_TARGET_DIR/$(basename -- "$file")"
|
||||||
|
done
|
||||||
+70
-14
@@ -2,7 +2,30 @@
|
|||||||
|
|
||||||
Use this file when the user asks how to verify or troubleshoot generated Quadlet units.
|
Use this file when the user asks how to verify or troubleshoot generated Quadlet units.
|
||||||
|
|
||||||
## Basic deployment flow
|
## Contents
|
||||||
|
|
||||||
|
- Validation flow
|
||||||
|
- Verification commands
|
||||||
|
- Runnable-output checks
|
||||||
|
- Common failure causes
|
||||||
|
- Troubleshooting posture
|
||||||
|
|
||||||
|
## Validation Flow
|
||||||
|
|
||||||
|
Validation belongs after execution, after the reviewed Quadlet files have been applied to a valid Quadlet directory, and while the referenced support files still exist at the host paths used by the generated units.
|
||||||
|
|
||||||
|
Recommended validation flow:
|
||||||
|
|
||||||
|
1. Confirm the user already reviewed the finalize snapshot and approved execution.
|
||||||
|
2. Confirm the generated deliverable set contains the expected Quadlet units, env files, helper scripts, and required support files.
|
||||||
|
3. Run `install.sh` to copy only the reviewed Quadlet unit files into the target Quadlet directory.
|
||||||
|
4. Run the appropriate reload command.
|
||||||
|
5. Start the relevant units and inspect their status.
|
||||||
|
6. If needed, run `uninstall.sh` to remove the installed reviewed artifact set before regenerating or abandoning the deployment.
|
||||||
|
|
||||||
|
If the user requested an alternate apply script name explicitly, substitute that name where needed, but treat `install.sh` as the default documentation path.
|
||||||
|
|
||||||
|
## Verification Commands
|
||||||
|
|
||||||
### Rootless
|
### Rootless
|
||||||
|
|
||||||
@@ -20,7 +43,7 @@ systemctl start <unit>
|
|||||||
systemctl status <unit>
|
systemctl status <unit>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generator debugging
|
### Generator debugging
|
||||||
|
|
||||||
Use the Podman systemd generator dry run when units fail to appear or options look unsupported.
|
Use the Podman systemd generator dry run when units fail to appear or options look unsupported.
|
||||||
|
|
||||||
@@ -34,7 +57,7 @@ For rootless debugging:
|
|||||||
/usr/lib/systemd/system-generators/podman-system-generator --user --dryrun
|
/usr/lib/systemd/system-generators/podman-system-generator --user --dryrun
|
||||||
```
|
```
|
||||||
|
|
||||||
## Systemd verification
|
### Systemd verification
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemd-analyze verify <unit>.service
|
systemd-analyze verify <unit>.service
|
||||||
@@ -46,25 +69,58 @@ For user units:
|
|||||||
systemd-analyze --user verify <unit>.service
|
systemd-analyze --user verify <unit>.service
|
||||||
```
|
```
|
||||||
|
|
||||||
## Common failure causes
|
## Runnable-Output Checks
|
||||||
|
|
||||||
|
Before calling the result runnable, verify that:
|
||||||
|
|
||||||
|
- every referenced `EnvironmentFile=` exists at the path referenced by the installed unit
|
||||||
|
- required env keys are present in the final env sources, or are explicitly surfaced as unresolved placeholders
|
||||||
|
- bind-mounted files and directories exist at the absolute paths referenced by the generated Quadlet files
|
||||||
|
- bind-mounted file-versus-directory shape still matches the source input
|
||||||
|
- if `AutoUpdate=registry` is enabled, the generated unit uses a fully qualified image reference
|
||||||
|
- when sibling containers in the same pod must connect to a service, its effective listen address is reachable within the pod namespace (`127.0.0.1` or `0.0.0.0`, unless upstream docs require another reviewed bind address)
|
||||||
|
- repo-local entrypoint or helper scripts referenced by the container exist and are executable when needed
|
||||||
|
- initialization assets such as `init.sql`, seeds, bootstrap files, or config templates are present where the deployment expects them
|
||||||
|
- service-management scripts operate on the same reviewed artifact set that finalize approved
|
||||||
|
- helper shell scripts match reviewed Quadlet files by their shared generated prefix with globbing such as `<prefix>*`, not hardcoded filenames or assumed file counts
|
||||||
|
|
||||||
|
Runnable-output gate checklist template:
|
||||||
|
|
||||||
|
- [ ] the support-file set is complete
|
||||||
|
- [ ] every `EnvironmentFile=` path resolves to an actual reviewed file
|
||||||
|
- [ ] env completeness check passed against the actual final env sources
|
||||||
|
- [ ] startup-critical env keys are present, or explicitly marked as unresolved placeholders
|
||||||
|
- [ ] unit files are installed in the intended Quadlet directory
|
||||||
|
- [ ] support files remain available at the absolute paths expected by mounts and scripts
|
||||||
|
- [ ] bind-mounted file-versus-directory shape still matches the source input
|
||||||
|
- [ ] if `AutoUpdate=registry` is enabled, the generated unit uses a fully qualified image reference
|
||||||
|
- [ ] intra-pod service listeners that must accept sibling-container traffic are reachable on `127.0.0.1` or `0.0.0.0`, unless upstream docs require another reviewed bind address
|
||||||
|
- [ ] service-management scripts operate on the same artifact set that was reviewed
|
||||||
|
- [ ] no required support file, env key, or typo-suspect mismatch remains unresolved
|
||||||
|
- [ ] host-side `PublishPort=` ports are free on the target host
|
||||||
|
|
||||||
|
Do not call the result runnable until every item above is checked.
|
||||||
|
|
||||||
|
## Common Failure Causes
|
||||||
|
|
||||||
- unsupported Quadlet option for the installed Podman version
|
- unsupported Quadlet option for the installed Podman version
|
||||||
|
- `AutoUpdate=registry` was enabled but the image reference is not fully qualified
|
||||||
- bind-mount source directory missing
|
- bind-mount source directory missing
|
||||||
- wrong rootless or rootful unit directory
|
- files were generated but `install.sh` has not yet copied the unit files into the target rootless or rootful unit directory
|
||||||
|
- wrong rootless or rootful apply target directory
|
||||||
- unresolved env file path
|
- unresolved env file path
|
||||||
|
- required env key missing from the final env file
|
||||||
|
- likely env-key typo or mismatch between source docs and final env output
|
||||||
|
- required repo-local config, init assets, or helper scripts missing from the installed artifact set
|
||||||
- permissions on rootless bind mounts
|
- permissions on rootless bind mounts
|
||||||
- readiness assumptions hidden behind `depends_on`
|
- readiness assumptions hidden behind `depends_on`
|
||||||
|
- host port already in use by another service or process, causing `PublishPort=` binding to fail at start
|
||||||
|
|
||||||
## Troubleshooting posture
|
## Troubleshooting Posture
|
||||||
|
|
||||||
When validation fails, report:
|
When validation fails, report:
|
||||||
|
|
||||||
- what generated successfully
|
- what generated successfully
|
||||||
- what failed to generate or start
|
- what was applied successfully
|
||||||
- whether the issue is syntax, unsupported feature, path resolution, or permissions
|
- what failed to generate, apply, or start
|
||||||
|
- whether the issue is syntax, unsupported feature, path resolution, installation path, missing support files, missing env keys, or permissions
|
||||||
## Relationship to execution phase
|
|
||||||
|
|
||||||
Validation belongs after the files are written in the execution phase.
|
|
||||||
|
|
||||||
Before execution, the skill should already have completed planning and finalize review with the user. Do not treat validation as a substitute for design review.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user