mirror of
https://github.com/bestnite/quadlet-migrator-skill.git
synced 2026-04-26 17:41:53 +00:00
Compare commits
7 Commits
62704d3a2d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
5babe1fc14
|
|||
|
d2eb13b0d6
|
|||
|
669c3e1703
|
|||
|
349b8ed436
|
|||
|
108e92be4f
|
|||
|
c7dece4a3d
|
|||
|
fdf1a27fe2
|
@@ -12,3 +12,4 @@ Thumbs.db
|
|||||||
*.log
|
*.log
|
||||||
*.tmp
|
*.tmp
|
||||||
*.bak
|
*.bak
|
||||||
|
.codex
|
||||||
@@ -2,65 +2,71 @@
|
|||||||
|
|
||||||
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
||||||
|
|
||||||
A skill that helps turn `docker run` commands and Docker Compose setups into Podman Quadlet files you can review, adjust, and apply.
|
Quadlet Migrator is a skill for converting Docker-based deployment input into Podman Quadlet output.
|
||||||
|
|
||||||
## What it does
|
## What It Does
|
||||||
|
|
||||||
- converts `docker run` commands and Docker Compose setups into Podman Quadlet files
|
- converts `docker run` commands into Quadlet units
|
||||||
- writes the generated files to the current directory first so you can review them before installing them
|
- converts Docker Compose setups into Quadlet deployments
|
||||||
- asks about the output location only when you already requested another location or existing files would conflict
|
- analyzes self-hosting deployment files in GitHub repositories
|
||||||
- helps choose between `.container`, `.pod`, `.network`, `.volume`, and `.build`, usually preferring a pod for related multi-container services
|
- keeps env files, mounted config, initialization assets, and helper scripts when they are part of the deployment
|
||||||
- keeps `.env` / `env_file` workflows when they still fit the deployment
|
- turns large env templates into a short list of deployment decisions
|
||||||
- turns large env templates into a short list of decisions the user actually needs to make
|
- provides deployment, validation, and troubleshooting guidance
|
||||||
- can generate helper scripts such as `install.sh`, `uninstall.sh`, `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh`
|
|
||||||
- finds files from the current project that the service still needs when it runs, such as mounted config, setup data, and helper scripts
|
|
||||||
- checks that env files are complete before calling the result runnable
|
|
||||||
- asks the user to confirm important deployment choices during planning, then uses clear review and execution checklists
|
|
||||||
- can optionally plan `AutoUpdate=registry` when the chosen image uses a complete image name that includes the registry, such as `docker.io/...` or `ghcr.io/...`
|
|
||||||
- explains rootless vs rootful install paths, deployment notes, and validation steps
|
|
||||||
|
|
||||||
## Design principles
|
## Installation
|
||||||
|
|
||||||
- use the simplest mode that fits the request
|
```bash
|
||||||
- keep planning, review, and file generation as separate steps
|
npx skills add bestnite/quadlet-migrator-skill -g
|
||||||
- do not invent deployment-specific values
|
```
|
||||||
- call out behavior changes when a mapping is lossy
|
|
||||||
- prefer output that is easy to understand and maintain
|
|
||||||
- write files to the current directory for review before installation
|
|
||||||
- prefer pod-based grouping when it is the clearest fit for a multi-container service
|
|
||||||
- keep required extra files in the reviewed output and point to them with absolute paths on the host machine instead of copying them into the Quadlet unit directory
|
|
||||||
|
|
||||||
## Operating modes
|
## When To Use It
|
||||||
|
|
||||||
- `advice`: explain the mapping, review source inputs, or answer targeted questions without writing final files
|
Use this skill when you want to:
|
||||||
- `design`: do planning and a final interactive review, then stop before generating runnable files
|
|
||||||
- `generate`: do planning, the final interactive review, and execution, then generate the approved runnable files
|
|
||||||
|
|
||||||
## Workflow
|
- 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
|
||||||
|
|
||||||
The workflow has three phases: `Planning`, `Finalize`, and `Execution`.
|
## How To Use It
|
||||||
|
|
||||||
- `advice` usually stays in `Planning` or answers a focused question directly
|
1. Give it an input:
|
||||||
- `design` includes `Planning` and `Finalize`
|
- a `docker run` command
|
||||||
- `generate` includes all three phases
|
- 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.
|
||||||
|
|
||||||
Planning is where unresolved deployment decisions are gathered and confirmed with the user.
|
## Example Requests
|
||||||
Finalize is a review step in the conversation after those decisions have been discussed.
|
|
||||||
Execution starts only after the user approves that review.
|
|
||||||
|
|
||||||
## References
|
```text
|
||||||
|
Convert this docker run command into Quadlet and explain the mapping.
|
||||||
|
|
||||||
- `SKILL.md` contains the operating modes, workflow, and high-level rules
|
Review this compose.yaml and propose a Podman Quadlet layout.
|
||||||
- `references/compose-mapping.md` covers field mapping and topology decisions
|
|
||||||
- `references/env-strategy.md` covers env handling, completeness validation, and typo detection
|
|
||||||
- `references/github-repo-intake.md` covers how the skill finds the right repository entry point
|
|
||||||
- `references/deployment-notes.md` covers deployment guidance
|
|
||||||
- `references/validation.md` covers validation and troubleshooting
|
|
||||||
- `references/template/` contains simple helper-script templates for stable prefix-based Quadlet file handling and lifecycle management
|
|
||||||
|
|
||||||
## Limitations
|
Generate reviewable Quadlet files from this repository's self-hosting deployment.
|
||||||
|
|
||||||
This skill does not claim perfect equivalence between Docker Compose semantics and Podman Quadlet semantics.
|
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
|
||||||
|
|
||||||
|
|||||||
+51
-45
@@ -2,65 +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` 命令和 Docker Compose 配置转换成 Podman Quadlet 文件
|
- 将 `docker run` 命令转换为 Quadlet 单元文件
|
||||||
- 默认先把生成文件写到当前目录,方便你在安装前先审阅
|
- 将 Docker Compose 配置转换为 Quadlet 部署结果
|
||||||
- 只有在你已经指定其他位置,或现有文件会发生冲突时,才询问输出位置
|
- 分析 GitHub 仓库中的自托管部署文件
|
||||||
- 帮助在 `.container`、`.pod`、`.network`、`.volume`、`.build` 之间做选择;对有关联的多容器服务,通常优先用 pod
|
- 在部署需要时保留 env 文件、挂载配置、初始化资产和辅助脚本
|
||||||
- 在合适时保留 `.env` / `env_file` 工作流
|
- 将庞杂的 env 模板整理成少量部署决策
|
||||||
- 把庞杂的 env 模板收敛成用户真正需要确认的少量问题
|
- 提供部署、验证和排障指引
|
||||||
- 可生成辅助脚本,例如 `install.sh`、`uninstall.sh`、`reload.sh`、`start.sh`、`stop.sh`、`restart.sh`
|
|
||||||
- 识别服务运行时仍需要的项目内文件,例如挂载配置、初始化数据和辅助脚本
|
|
||||||
- 在声称结果可运行前,检查 env 文件是否完整
|
|
||||||
- 在 planning 阶段先确认关键部署决策,并在审阅和执行阶段使用清晰的检查清单
|
|
||||||
- 当所选镜像使用包含仓库地址的完整镜像名时,例如 `docker.io/...` 或 `ghcr.io/...`,可选规划 `AutoUpdate=registry`
|
|
||||||
- 说明 rootless / rootful 安装路径、部署说明和验证步骤
|
|
||||||
|
|
||||||
## 设计原则
|
## 安装
|
||||||
|
|
||||||
- 用能满足需求的最简单模式
|
```bash
|
||||||
- 将 planning、审阅、生成文件分成独立步骤
|
npx skills add bestnite/quadlet-migrator-skill -g
|
||||||
- 不虚构部署相关取值
|
```
|
||||||
- 如果映射会带来行为变化,要明确说出来
|
|
||||||
- 优先产出容易理解、容易维护的结果
|
|
||||||
- 先把文件写到当前目录审阅,再决定是否安装
|
|
||||||
- 对多容器服务,如果用 pod 更清晰,就优先用 pod
|
|
||||||
- 运行仍需要的额外文件保留在已审阅的输出中,并通过主机上的绝对路径引用,而不是复制进 Quadlet 单元目录
|
|
||||||
|
|
||||||
## 运行模式
|
## 适用场景
|
||||||
|
|
||||||
- `advice`:解释映射方式、审查输入,或回答定向问题,不写最终文件
|
适合在这些场景中使用:
|
||||||
- `design`:执行 planning 和最后一轮交互式审阅,但在生成可运行文件前停止
|
|
||||||
- `generate`:执行 planning、最后一轮交互式审阅和 execution,然后生成已批准的可运行文件
|
|
||||||
|
|
||||||
## 工作流
|
- 将服务从 Docker 迁移到 Podman Quadlet
|
||||||
|
- 将 Compose 栈转换为 Quadlet 布局
|
||||||
|
- 审查仓库中的自托管部署文件
|
||||||
|
- 先生成文件审阅,再决定是否安装
|
||||||
|
- 验证或排查生成后的 Quadlet 文件
|
||||||
|
|
||||||
工作流分为三个阶段:`Planning`、`Finalize`、`Execution`。
|
## 使用方式
|
||||||
|
|
||||||
- `advice` 通常停留在 `Planning`,或直接回答一个聚焦的问题
|
1. 提供一种输入:
|
||||||
- `design` 包含 `Planning` 和 `Finalize`
|
- 一条 `docker run` 命令
|
||||||
- `generate` 包含全部三个阶段
|
- 一个 Compose 文件或 Compose 项目
|
||||||
|
- 一个 GitHub 仓库 URL
|
||||||
|
- 一组需要审查或清理的现有 Quadlet 文件
|
||||||
|
2. 说明你的目标:
|
||||||
|
- 映射建议
|
||||||
|
- 部署设计
|
||||||
|
- 可审阅的可运行结果
|
||||||
|
3. 确认域名、主机路径、凭据、存储方案或可选服务等部署取值。
|
||||||
|
4. 在应用前审阅生成结果。
|
||||||
|
|
||||||
Planning 用来收集并确认仍未决定的部署问题。
|
## 示例请求
|
||||||
Finalize 是在这些问题讨论清楚之后进行的对话式审阅。
|
|
||||||
只有在用户批准这次审阅后,才进入 Execution。
|
|
||||||
|
|
||||||
## 文档说明
|
```text
|
||||||
|
把这条 docker run 命令转换成 Quadlet,并解释映射关系。
|
||||||
|
|
||||||
- `SKILL.md`:运行模式、工作流和高层规则
|
审查这个 compose.yaml,并给出一个 Podman Quadlet 布局方案。
|
||||||
- `references/compose-mapping.md`:Compose 字段映射与拓扑决策
|
|
||||||
- `references/env-strategy.md`:env 处理、完整性校验与 typo 检测
|
|
||||||
- `references/github-repo-intake.md`:说明 skill 如何找到正确的仓库入口
|
|
||||||
- `references/deployment-notes.md`:部署说明
|
|
||||||
- `references/validation.md`:验证与排障
|
|
||||||
- `references/template/`:用于稳定处理 Quadlet 文件与 lifecycle 管理的简洁 helper script 模板目录
|
|
||||||
|
|
||||||
## 限制
|
根据这个仓库的自托管部署生成可审阅的 Quadlet 文件。
|
||||||
|
|
||||||
本 skill 不保证 Docker Compose 语义与 Podman Quadlet 语义完全等价。
|
帮我把这套服务迁移到 rootless Podman,并保留 env-file 工作流。
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见产物
|
||||||
|
|
||||||
|
- Quadlet 单元文件
|
||||||
|
- env 文件或 env 增量文件
|
||||||
|
- 用于 install、reload、start、stop、restart、uninstall 的辅助脚本
|
||||||
|
- 部署说明与验证指引
|
||||||
|
|
||||||
|
## 说明
|
||||||
|
|
||||||
|
- 在安装前审阅生成结果。
|
||||||
|
- 对部署相关取值先确认,再生成结果。
|
||||||
|
- Docker Compose 与 Quadlet 不完全等价时,要明确说明行为变化。
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
|
|||||||
@@ -1,245 +1,120 @@
|
|||||||
---
|
---
|
||||||
name: quadlet-migrator
|
name: quadlet-migrator
|
||||||
description: Convert docker run commands or Docker Compose configurations into maintainable Podman Quadlet files, default to writing reviewable output in the current directory, generate helper install/reload/start/stop/restart scripts, carry along required repo-local companion files such as config templates or init assets, 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, systemd layout, review-first generation into the current directory, or helper management scripts 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`, with a pod-first bias for multi-container services
|
- 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.
|
||||||
- write reviewable output to the current directory by default, unless the user requested another output directory or an existing-file conflict requires a decision before writing
|
- Read docs, comments, and example values yourself; ask the user only about high-impact deployment decisions.
|
||||||
- generate helper scripts with `install.sh` as the canonical apply script name, plus `uninstall.sh`, `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` when producing runnable artifacts, using the reviewed shell templates under `references/template/` as the default source
|
- Do not invent deployment-specific values.
|
||||||
- identify required repo-local companion files such as config files, templates, seed data, or initialization assets that must be shipped alongside Quadlet output for the deployment to run correctly
|
- Keep detailed mapping and validation logic in `references/` instead of restating it in the main skill file.
|
||||||
- validate env completeness before claiming runnable output, including missing required keys and suspicious env-key mismatches
|
|
||||||
- work closely with the user to confirm deployment-specific environment values and operational choices
|
|
||||||
- identify missing variables, unsafe inline secrets, and unsupported Compose semantics
|
|
||||||
- produce deployment notes for rootless or rootful systemd setups
|
|
||||||
|
|
||||||
## 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 interactive `Finalize` review, then stop before writing runnable artifacts
|
|
||||||
- `generate`: perform `Planning`, interactive `Finalize` review, 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 repo-local companion files referenced by bind mounts, docs, `entrypoint`, `command`, or wrapper scripts, and decide whether they belong in the deliverable set
|
|
||||||
- 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
|
|
||||||
- repo-local companion files required at runtime, such as config files, templates, migrations, seed data, or initialization assets
|
|
||||||
- repo-local entrypoint scripts, helper scripts, and bind-mounted directories that must remain part of the deliverable set
|
|
||||||
|
|
||||||
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
|
|
||||||
- whether to opt into `AutoUpdate=registry` when the approved image strategy uses fully qualified registry images and the user wants runnable output
|
|
||||||
- whether a user-requested non-default output directory should override the current-directory default
|
|
||||||
- how to resolve any existing-file conflicts in the chosen output directory before writing runnable artifacts
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
If Compose files, bind mounts, startup docs, entrypoints, or helper scripts reference repo-local files or whole directories, treat those assets as candidates for the final deliverable set rather than incidental source files.
|
### Finalize
|
||||||
Do not assume runnable output is complete when Quadlet files exist but required mounted config, init assets, or startup scripts have not been identified.
|
|
||||||
|
|
||||||
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.
|
Goal: freeze the design that planning established and ask the user to review it in conversation.
|
||||||
|
|
||||||
At the end of planning, summarize what you learned, state the proposed output location, state whether `AutoUpdate=registry` is in scope, and explicitly ask the user whether anything should be changed or added before you move to finalize review.
|
Finalize is not a second discovery pass. Do not use it to introduce first-time major choices.
|
||||||
|
|
||||||
Planning is also the phase where you must actively ask the user for the unresolved high-impact decisions you identified.
|
In finalize:
|
||||||
If the approved runnable path would use fully qualified registry image references, ask before finalize whether the user wants to opt into `AutoUpdate=registry`.
|
|
||||||
If the image strategy does not yield a fully qualified registry image reference, do not force or imply that `AutoUpdate=registry` is available.
|
|
||||||
If the user did not request a different output directory, treat the current working directory as the default deliverable location and say so explicitly during planning instead of asking an unnecessary directory question.
|
|
||||||
If the user already requested another output directory, honor that request unless it conflicts with a higher-priority source of truth.
|
|
||||||
If files that would be written already exist in the chosen output directory, stop before writing and ask the user whether to overwrite, update selectively, or choose a different location.
|
|
||||||
|
|
||||||
Do not defer first-time decision gathering into finalize review.
|
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.
|
||||||
|
|
||||||
If decisions are still unresolved, stop in planning and ask the user directly. Do not enter finalize review yet.
|
Do not start execution until the user has reviewed and confirmed the finalize snapshot.
|
||||||
|
|
||||||
### Finalize phase
|
### Execution
|
||||||
|
|
||||||
Goal: consolidate the decisions already made in planning into one internally consistent design snapshot and ask the user to review it in conversation.
|
Goal: write the approved artifacts.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
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.
|
In execution:
|
||||||
|
|
||||||
Tasks in this 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.
|
||||||
|
|
||||||
1. Freeze the chosen service set and runtime grouping.
|
If implementation reveals a material conflict with the approved design, stop and return to planning instead of silently diverging.
|
||||||
- prefer putting the whole project in a single pod when practical
|
|
||||||
- if the project is a simple single-container deployment, a standalone `.container` is the default
|
|
||||||
- if one logical service contains multiple containers, prefer keeping them in the same `.pod` so they share one network namespace
|
|
||||||
- even when the source Compose topology uses bridge networking, prefer pod-based grouping over preserving bridge semantics mechanically
|
|
||||||
- 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 must use `127.0.0.1` / `localhost` instead
|
|
||||||
- `AddHost=` remains a host-to-IP override, not an intra-pod service-discovery mechanism; because upstream Quadlet supports `AddHost=` in both `[Container]` and `[Pod]`, do not claim that `Pod=` categorically forbids `AddHost=` unless the upstream reference says so for the specific case
|
|
||||||
- when containers are attached with `Pod=<name>.pod`, treat the pod's generated systemd service as the primary lifecycle unit; derive that service name from `ServiceName=` when present on the `.pod`, otherwise use Quadlet's default generated pod service name. Starting that pod service brings up the pod-managed containers, so do not add redundant per-container start commands for those child units in helper scripts
|
|
||||||
- containers in different pods must not be treated as reachable via `127.0.0.1` / `localhost`; if you split the topology across multiple pods or preserve a shared bridge network, use container names, pod names, or explicit `NetworkAlias=` values on the shared network instead
|
|
||||||
- `ServiceName=` controls the generated systemd unit name only and must not be treated as an application-facing network address
|
|
||||||
- `PodName=` controls the Podman pod name only and may be part of the chosen addressing strategy, but it does not determine the systemd service name
|
|
||||||
- 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 `.network` / bridge-first designs unless pod topology cannot express the intended deployment cleanly
|
|
||||||
|
|
||||||
2. Freeze the storage strategy.
|
## Hard Stops
|
||||||
- named volume, bind mount, or anonymous volume per storage use case
|
|
||||||
- bind mounts must end up as absolute host paths
|
|
||||||
- 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
|
|
||||||
|
|
||||||
3. Freeze the image strategy.
|
Stop and ask the user before finalizing or generating runnable output when any of these remain unresolved:
|
||||||
- prefer upstream prebuilt registry images when they already exist and local build is not required for correctness
|
|
||||||
- create `.build` only when local build is actually required, or when the user explicitly wants a declarative local-build workflow
|
|
||||||
- prefer fully qualified image names in generated output
|
|
||||||
- if the source image omits a registry and is intended for Docker Hub, expand it explicitly instead of relying on short-name resolution
|
|
||||||
- for images of the form `name[:tag]` with no namespace, normalize to `docker.io/library/name[:tag]`
|
|
||||||
- for images of the form `namespace/name[:tag]` with no registry, normalize to `docker.io/namespace/name[:tag]`
|
|
||||||
- if the source clearly points to another registry such as `ghcr.io`, `quay.io`, or a private registry, preserve that registry explicitly
|
|
||||||
- if the approved image strategy uses fully qualified registry images and the user opted in earlier, include `AutoUpdate=registry` in the finalized design snapshot; otherwise leave it out
|
|
||||||
|
|
||||||
4. Freeze the environment strategy.
|
- required secrets, external URLs, host paths, or other deployment-specific values
|
||||||
- use `Environment=` for a small number of stable non-sensitive values
|
- multiple plausible source inputs with no confident canonical entry point
|
||||||
- use `EnvironmentFile=` for bulk variables, secrets, or values already sourced from `.env` / `env_file`
|
- image strategy versus local build strategy when the difference materially affects the result
|
||||||
- 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
|
- a lossy mapping that would change runtime behavior in an important way
|
||||||
- treat variable names containing `PASSWORD`, `TOKEN`, `SECRET`, `KEY`, `PRIVATE`, or `PASS` as sensitive by default and avoid inlining unless the user explicitly wants that
|
- output-location conflicts or overwrite strategy for files that already exist
|
||||||
- do not treat a variable as satisfied unless it is present in an actual final source such as `Environment=`, the final `EnvironmentFile=`, or an explicitly preserved default
|
- required support files or directories referenced by mounts, docs, commands, or scripts
|
||||||
- if a likely required startup variable is still absent from the final output, keep it unresolved instead of downgrading it to an informational note
|
- required env values for minimal startup
|
||||||
- if referenced env keys and final env keys contain likely near-match typos, call them out explicitly before execution
|
- 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
|
||||||
|
|
||||||
5. Summarize already-known conflicts and their chosen resolution.
|
Do not keep moving forward by guessing through these gaps.
|
||||||
- port collisions
|
|
||||||
- incompatible grouping decisions
|
|
||||||
- storage mode inconsistencies
|
|
||||||
- unresolved required variables
|
|
||||||
- suspicious env-key mismatches or typo candidates
|
|
||||||
- missing required repo-local support files or directories
|
|
||||||
- mismatch between requested deployment mode and selected file locations
|
|
||||||
- existing-file conflicts in the chosen output directory and the agreed handling for them
|
|
||||||
|
|
||||||
At the end of finalize, present the finalized design snapshot in conversation and ask the user to review it before you start writing the final artifacts.
|
If a structured input tool is unavailable, ask the user directly in conversation before proceeding. Do not substitute defaults for unresolved high-impact decisions.
|
||||||
|
|
||||||
Before finalizing, use this checklist template:
|
## Decision Priority
|
||||||
|
|
||||||
- [ ] support-file set identified, including mounted config, entrypoint scripts, init assets, and bind-mounted directories
|
|
||||||
- [ ] support files classified as upstream-preserved, locally generated, or locally rewritten
|
|
||||||
- [ ] env keys classified into satisfied, unresolved, default-derived, and typo-suspect states
|
|
||||||
- [ ] finalized file list reflects everything the runtime needs, not just Quadlet units
|
|
||||||
- [ ] output location and any existing-file conflicts have an explicit plan
|
|
||||||
- [ ] any remaining placeholders are explicit and understood as non-runnable until filled
|
|
||||||
|
|
||||||
Finalize review is a review conversation, not a questionnaire and not a required markdown file. It should summarize decisions that were already discussed in planning.
|
|
||||||
|
|
||||||
Do not start execution until the user has reviewed and confirmed the finalize snapshot or provided requested edits.
|
|
||||||
|
|
||||||
Do not use finalize review 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 in the current working directory by default so the user can review them before applying them.
|
|
||||||
2. Generate the env file or env delta only when needed for runnable output.
|
|
||||||
3. Generate helper scripts such as `install.sh`, `uninstall.sh`, `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` when they materially help the user apply and operate the result.
|
|
||||||
- Generate these shell scripts by adapting the reviewed templates under `references/template/`.
|
|
||||||
- Use `install.sh` as the default and canonical script name for applying the reviewed artifact set.
|
|
||||||
- Do not also generate `apply.sh` unless the user explicitly asks for that alternate name.
|
|
||||||
- `install.sh` should copy only Quadlet unit files into the chosen Quadlet target directory. Required env files, mounted config, scripts, and other runtime support files should remain in the reviewed current-directory deliverable set and be referenced from Quadlet via absolute host paths.
|
|
||||||
- helper shell scripts must not hardcode exact Quadlet filenames or assume a fixed number of Quadlet files. They should operate on the reviewed Quadlet set via the shared generated prefix, using shared-prefix glob matching such as `<prefix>*`.
|
|
||||||
- `install.sh` should not start, stop, restart, or reload services as a side effect.
|
|
||||||
- `uninstall.sh` should remove only the previously installed reviewed Quadlet unit files from the chosen Quadlet target directory.
|
|
||||||
- `uninstall.sh` should stop affected services before removing their installed unit files, and should not delete support files from the current-directory deliverable set, unrelated files, shared directories, named volumes, images, or Podman objects unless the user explicitly asks for that broader cleanup.
|
|
||||||
- `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` should manage services only and should not silently install or overwrite files.
|
|
||||||
- when a generated topology includes `<name>.pod` plus child containers linked with `Pod=<name>.pod`, make the pod service the lifecycle entrypoint in helper scripts; derive that service name from `ServiceName=` when present on the `.pod`, otherwise use Quadlet's default generated pod service name. Do not emit redundant `systemctl start/stop/restart` lines for each child container that is already managed through the pod service.
|
|
||||||
4. If the deployment depends on repo-local support files or directories, generate or copy those reviewed artifacts into the current-directory deliverable set as well.
|
|
||||||
5. Do not claim runnable output until the final env sources and support-file set are complete enough for minimal startup.
|
|
||||||
6. Generate deployment notes or validation guidance only when they materially help the user operate the result.
|
|
||||||
7. Generate a README only when the user explicitly wants a self-contained handoff artifact or a packaged deliverable.
|
|
||||||
|
|
||||||
Execution should follow the approved finalize snapshot. If the implementation reveals a material conflict with the finalized design, stop and return to planning rather than silently diverging.
|
|
||||||
|
|
||||||
Before calling the result runnable, pass this gate:
|
|
||||||
|
|
||||||
- the generated artifact set includes all required support files and directories
|
|
||||||
- every referenced `EnvironmentFile=` exists in the deliverable set and contains the required keys
|
|
||||||
- startup-critical env values are either present or explicitly unresolved
|
|
||||||
- suspected env typos have been resolved or surfaced to the user
|
|
||||||
- install, uninstall, reload, and service-management scripts match the approved artifact set
|
|
||||||
|
|
||||||
Use this execution checklist template:
|
|
||||||
|
|
||||||
- [ ] support-file set copied, generated, or preserved in the deliverable tree
|
|
||||||
- [ ] every `EnvironmentFile=` path resolves to an actual reviewed file
|
|
||||||
- [ ] startup-critical env keys present, or explicitly marked as unresolved placeholders
|
|
||||||
- [ ] support files, scripts, and config trees map to the correct host-side destination paths
|
|
||||||
- [ ] runnable-output gate passed before describing the result as runnable
|
|
||||||
- [ ] helper scripts operate on the same reviewed artifact set that finalize approved
|
|
||||||
- [ ] chosen output directory still matches the approved plan and no new file conflicts appeared before writing
|
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
@@ -247,106 +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
|
||||||
- the user requested a non-default output directory but the resulting deliverable layout or operator model is still ambiguous
|
|
||||||
- files that would be written already exist in the chosen output directory and the overwrite/update strategy is not yet approved
|
|
||||||
- required repo-local support files or directories referenced by mounts, docs, commands, or scripts have not been identified confidently
|
|
||||||
- required runtime files are known but are still missing from the planned deliverable set
|
|
||||||
- required env values for minimal service startup are still missing from the final env sources
|
|
||||||
- likely env-key typos or mismatches remain unresolved
|
|
||||||
|
|
||||||
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 apply target 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.
|
||||||
|
|
||||||
- By default, generate reviewable artifacts in the current working directory first.
|
## Validation Reminder
|
||||||
- If the user explicitly requests another output directory for the reviewable artifact set, use that directory instead of forcing the current working directory.
|
|
||||||
- For rootless deployments, the default apply target directory is `~/.config/containers/systemd/` unless the user has a reason to use another supported path.
|
|
||||||
- For rootful deployments, the default apply target directory is `/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, generated-service behavior, 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.
|
||||||
If a Quadlet mapping, option meaning, or supported behavior is unclear or seems to conflict with higher-level guidance, treat `references/podman-systemd.unit.5.md` as the gold standard for Quadlet-specific behavior and align the result to it.
|
|
||||||
|
|
||||||
## 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 whether to opt into `AutoUpdate=registry` before finalize only when the approved image strategy actually supports it.
|
|
||||||
- Do not ask a first-time "which output directory?" question when the default current working directory is acceptable; say the default plainly and only ask when the user already asked for a different location or an existing-file conflict requires a choice.
|
|
||||||
- Resolve these questions before finalize review, not during execution.
|
|
||||||
- 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:
|
|
||||||
|
|
||||||
- review the generated files in the current directory
|
|
||||||
- apply the reviewed Quadlet files into the correct Quadlet directory while keeping support files in the current directory at the absolute paths referenced by the units
|
|
||||||
- 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`
|
|
||||||
- review-first runnable output -> `generate` often writes Quadlet files plus `install.sh`, `uninstall.sh`, `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` into the current directory, with `install.sh` as the canonical apply step
|
|
||||||
|
|
||||||
## 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 only during finalize review
|
|
||||||
- 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,18 +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.
|
||||||
- When one deliverable set includes multiple Quadlet files, keep that shared prefix consistent so helper shell scripts can match them by shared-prefix globbing such as `<prefix>*`, instead of hardcoding exact filenames or assuming a fixed file count.
|
- 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`
|
||||||
@@ -24,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`
|
||||||
@@ -36,12 +45,13 @@ 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`
|
||||||
|
|
||||||
@@ -60,31 +70,21 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
|||||||
- If the source uses a default network only, you often do not need a `.network` unit at all.
|
- 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.
|
- 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.
|
- 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 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 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.
|
- 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. Upstream Quadlet documents `AddHost=` in both `[Container]` and `[Pod]`, so do not describe `Pod=` as a blanket prohibition on `AddHost=` unless the upstream reference explicitly requires that for the case at hand.
|
- `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 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.
|
- 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.
|
- `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.
|
- `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`
|
||||||
|
|
||||||
@@ -110,20 +110,32 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
|||||||
|
|
||||||
### `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
|
||||||
|
|
||||||
@@ -145,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. A single container should usually stay a standalone `.container` rather than being wrapped in a pod.
|
|
||||||
|
|
||||||
### Small multi-service app to one pod
|
### Small multi-service app to one pod
|
||||||
|
|
||||||
Source intent:
|
Source intent:
|
||||||
@@ -168,23 +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 as the default shape for a small multi-container service unless port conflicts or incompatible grouping force a split into multiple pods.
|
|
||||||
|
|
||||||
## Pod decision rule
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
When services are split across multiple pods, do not rely on `127.0.0.1` / `localhost` for cross-pod communication. Use container names, pod names, or explicit `NetworkAlias=` values on the shared network instead.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|||||||
@@ -2,22 +2,31 @@
|
|||||||
|
|
||||||
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.
|
||||||
|
|
||||||
## Delivery flow
|
## 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 `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.
|
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.
|
1. Generate the reviewable artifacts in the current working directory by default, or in another user-requested output directory.
|
||||||
2. Resolve high-impact planning questions with the user before freezing the design.
|
2. Review the finalized design together with the generated Quadlet files, env files, helper scripts, and required repo-local support files.
|
||||||
3. Review the finalized design snapshot together with the generated Quadlet files, env files, helper scripts, and any required repo-local support files or directories.
|
3. Use `install.sh` to copy only the reviewed Quadlet unit files into the chosen Quadlet directory.
|
||||||
4. Use `install.sh` to copy only the reviewed Quadlet unit files into the chosen Quadlet directory.
|
4. Run the appropriate `daemon-reload` command.
|
||||||
5. Run the appropriate `daemon-reload` command.
|
5. Use `start.sh`, `stop.sh`, and `restart.sh` to manage services.
|
||||||
6. Use `start.sh`, `stop.sh`, and `restart.sh` to manage the deployed services.
|
6. Use `uninstall.sh` only when the user wants to remove the installed reviewed Quadlet unit files without broad Podman cleanup.
|
||||||
7. Use `uninstall.sh` when the user wants to remove the installed reviewed Quadlet unit files without broad Podman cleanup.
|
|
||||||
|
|
||||||
Do not start execution until the user has reviewed and confirmed the finalize snapshot or requested edits.
|
Keep installation separate from service-management scripts so the user can review generated files before applying them.
|
||||||
|
|
||||||
## Apply target directory
|
## Apply Target Directories
|
||||||
|
|
||||||
### Rootless
|
### Rootless
|
||||||
|
|
||||||
@@ -31,66 +40,42 @@ Do not start execution until the user has reviewed and confirmed the finalize sn
|
|||||||
|
|
||||||
See `podman-systemd.unit.5.md` for the full search-path matrix.
|
See `podman-systemd.unit.5.md` for the full search-path matrix.
|
||||||
|
|
||||||
## Helper scripts
|
## Helper-Script Expectations
|
||||||
|
|
||||||
- `install.sh`: canonical apply script; copy only reviewed Quadlet unit files into the selected Quadlet target directory
|
- `install.sh` is the canonical apply script. It copies only reviewed Quadlet unit files into the selected Quadlet target directory.
|
||||||
- do not generate a separate `apply.sh` by default; reserve that alternate name only when the user explicitly asks for it
|
- Do not generate a separate `apply.sh` by default. Use that alternate name only when the user explicitly asks for it.
|
||||||
- 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
|
- 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
|
- `install.sh` must not start, stop, restart, or reload services as a side effect.
|
||||||
- `uninstall.sh`: remove the installed reviewed Quadlet unit files from the selected Quadlet target directory
|
- `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 from the current-directory deliverable set, unrelated files, shared directories, named volumes, images, or Podman objects unless the user explicitly asks for broader cleanup
|
- `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`: run only the appropriate `daemon-reload` command after installation changes
|
- `reload.sh` runs only the appropriate `daemon-reload` command after installation changes.
|
||||||
- `start.sh`, `stop.sh`, `restart.sh`: manage services only and must not silently install or overwrite reviewed files
|
- `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, instead of duplicating per-container lifecycle commands for child units
|
- 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.
|
||||||
|
|
||||||
Keep installation separate from service-management scripts so the user can review generated files before applying them.
|
## Operational Notes
|
||||||
Do not use `ServiceName=` as an application connection target. It controls the generated systemd unit name only. When services communicate over a shared network outside a single pod namespace, prefer container names, pod names, or explicit `NetworkAlias=` values.
|
|
||||||
Within a single pod, use `127.0.0.1` / `localhost` for container-to-container communication instead of generating `AddHost=` entries whose purpose is 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`. When the upstream service exposes this through environment variables or similar runtime configuration, preserve or generate that setting explicitly.
|
|
||||||
|
|
||||||
## Review checklist before install
|
- 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.
|
||||||
Review not only the Quadlet unit files but also:
|
- 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.
|
||||||
- env files referenced by `EnvironmentFile=`
|
- 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`.
|
||||||
- repo-local mounted config files and directory trees
|
- Bind mounts may hit UID/GID mismatches, especially in rootless deployments.
|
||||||
- initialization files such as `init.sql`, seed data, or bootstrap assets
|
- 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.
|
||||||
- repo-local entrypoint and helper scripts referenced by `Entrypoint=`, `Exec=`, docs, or wrapper scripts
|
- For rootless long-running services that should survive logout, mention lingering:
|
||||||
|
|
||||||
Do not treat the deliverable as complete if these support files are still missing from the reviewable artifact set.
|
|
||||||
|
|
||||||
Execution checklist template before install:
|
|
||||||
|
|
||||||
- [ ] all reviewed artifacts are present in the current-directory deliverable tree
|
|
||||||
- [ ] required support files and directories are included alongside the Quadlet and env artifacts
|
|
||||||
- [ ] every `EnvironmentFile=` path resolves to an actual reviewed file
|
|
||||||
- [ ] support files remain in the current-directory deliverable tree at the absolute paths referenced by mounts and scripts
|
|
||||||
- [ ] startup-critical env keys are present, or explicitly marked as unresolved placeholders
|
|
||||||
- [ ] any unresolved values are clearly marked as intentionally non-runnable placeholders
|
|
||||||
- [ ] service-management scripts operate on the same reviewed artifact set that finalize approved
|
|
||||||
- [ ] runnable-output gate passed before describing the result as runnable
|
|
||||||
|
|
||||||
## Rootless operational notes
|
|
||||||
|
|
||||||
- Bind mounts may hit UID/GID mismatches.
|
|
||||||
- For pod-based deployments that should preserve host ownership semantics, consider `UserNS=keep-id` on `[Pod]` when appropriate.
|
|
||||||
- If the service must 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 `./...`.
|
|
||||||
- If the source project bind-mounts repo-local files or directories, make sure the reviewed current-directory deliverable set preserves the required contents and that the generated Quadlet files reference their absolute paths correctly.
|
|
||||||
|
|
||||||
## 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]
|
||||||
@@ -100,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 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
|
|
||||||
|
|
||||||
## 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
|
||||||
@@ -153,20 +162,19 @@ 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 variable still missing
|
### Required startup variable still missing
|
||||||
|
|
||||||
Source intent:
|
Source intent:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Container]
|
[Container]
|
||||||
EnvironmentFile=/home/nite/pod/dify/dify.env
|
EnvironmentFile=/home/nite/pod/myapp/myapp.env
|
||||||
Environment=POSTGRES_USER=postgres
|
Environment=APP_ENV=production
|
||||||
Environment=POSTGRES_DB=dify
|
Environment=APP_PORT=8080
|
||||||
Environment=PGDATA=/var/lib/postgresql/data/pgdata
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If `dify.env` does not contain `POSTGRES_PASSWORD`, do not treat this as runnable output.
|
If `myapp.env` does not contain `APP_SECRET`, do not treat this as runnable output.
|
||||||
Report `POSTGRES_PASSWORD` as unresolved and stop before final runnable generation.
|
Report `APP_SECRET` as unresolved and stop before final runnable generation.
|
||||||
|
|
||||||
## Output patterns
|
## Output patterns
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -56,7 +65,7 @@ Discover the canonical self-hosting assets before attempting any Quadlet convers
|
|||||||
- Do not reduce runnable output to only Quadlet plus env when the source project depends on additional repo-local assets.
|
- 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.
|
||||||
|
|
||||||
## Support-file checklist template
|
## Support-file checklist
|
||||||
|
|
||||||
Before choosing the final source of truth, confirm:
|
Before choosing the final source of truth, confirm:
|
||||||
|
|
||||||
@@ -68,7 +77,7 @@ Before choosing the final source of truth, confirm:
|
|||||||
|
|
||||||
Use this checklist to prevent reducing the deliverable to Quadlet plus env when the source project depends on more than that.
|
Use this checklist to prevent reducing the deliverable to Quadlet plus env when the source project depends on more than that.
|
||||||
|
|
||||||
## Migration posture for GitHub-sourced projects
|
## Reporting expectations
|
||||||
|
|
||||||
When converting a GitHub-hosted project, report:
|
When converting a GitHub-hosted project, report:
|
||||||
|
|
||||||
|
|||||||
+26
-16
@@ -2,10 +2,22 @@
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
1. Review the generated files in the current working directory by default, or in another user-requested output directory, and confirm the expected Quadlet units, env files, helper scripts, and required repo-local support files exist.
|
- Validation flow
|
||||||
2. Confirm the user has already reviewed the finalize snapshot and approved execution, or requested edits that were incorporated before writing runnable artifacts.
|
- 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.
|
3. Run `install.sh` to copy only the reviewed Quadlet unit files into the target Quadlet directory.
|
||||||
4. Run the appropriate reload command.
|
4. Run the appropriate reload command.
|
||||||
5. Start the relevant units and inspect their status.
|
5. Start the relevant units and inspect their status.
|
||||||
@@ -13,6 +25,8 @@ Use this file when the user asks how to verify or troubleshoot generated Quadlet
|
|||||||
|
|
||||||
If the user requested an alternate apply script name explicitly, substitute that name where needed, but treat `install.sh` as the default documentation path.
|
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
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -29,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.
|
||||||
|
|
||||||
@@ -43,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
|
||||||
@@ -55,16 +69,16 @@ For user units:
|
|||||||
systemd-analyze --user verify <unit>.service
|
systemd-analyze --user verify <unit>.service
|
||||||
```
|
```
|
||||||
|
|
||||||
## Support-file and env checks
|
## Runnable-Output Checks
|
||||||
|
|
||||||
Before calling the result runnable, verify that:
|
Before calling the result runnable, verify that:
|
||||||
|
|
||||||
- every referenced `EnvironmentFile=` exists at the path referenced by the installed unit
|
- every referenced `EnvironmentFile=` exists at the path referenced by the installed unit
|
||||||
- required env keys are actually present in the final env sources, or are explicitly surfaced as unresolved placeholders
|
- 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 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
|
- 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
|
- 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 reachable bind address)
|
- 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
|
- 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
|
- 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
|
- service-management scripts operate on the same reviewed artifact set that finalize approved
|
||||||
@@ -83,10 +97,11 @@ Runnable-output gate checklist template:
|
|||||||
- [ ] 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
|
- [ ] 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
|
- [ ] service-management scripts operate on the same artifact set that was reviewed
|
||||||
- [ ] no required support file, env key, or typo-suspect mismatch remains unresolved
|
- [ ] 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.
|
Do not call the result runnable until every item above is checked.
|
||||||
|
|
||||||
## Common failure causes
|
## 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
|
- `AutoUpdate=registry` was enabled but the image reference is not fully qualified
|
||||||
@@ -99,8 +114,9 @@ Do not call the result runnable until every item above is checked.
|
|||||||
- required repo-local config, init assets, or helper scripts missing from the installed artifact set
|
- 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:
|
||||||
|
|
||||||
@@ -108,9 +124,3 @@ When validation fails, report:
|
|||||||
- what was applied successfully
|
- what was applied successfully
|
||||||
- what failed to generate, apply, or start
|
- 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
|
- 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, the Quadlet units are applied to a valid Quadlet directory, and the referenced support files remain available at the absolute host paths used by the generated units.
|
|
||||||
|
|
||||||
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