mirror of
https://github.com/bestnite/quadlet-migrator-skill.git
synced 2026-04-03 22:53:28 +00:00
Refine review-first Quadlet migration guidance
Clarify that generated artifacts should be reviewed in the current directory first, install.sh only places Quadlet units into the Quadlet target directory, and runtime support files must be copied to their correct host-side paths. Also strengthen the skill's pod-first, support-file discovery, and env completeness validation rules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
14
README.md
14
README.md
@@ -7,10 +7,15 @@ A skill for migrating `docker run` commands and Docker Compose-style deployments
|
||||
## What it does
|
||||
|
||||
- translates `docker run` and Compose-style inputs into Quadlet-oriented designs
|
||||
- helps decide between `.container`, `.pod`, `.network`, `.volume`, and `.build`
|
||||
- writes generated artifacts to the current directory by default so they can be reviewed before being applied
|
||||
- helps decide between `.container`, `.pod`, `.network`, `.volume`, and `.build`, with a pod-first bias for multi-container services
|
||||
- preserves `.env` / `env_file` workflows when appropriate
|
||||
- reduces large env templates into a small set of high-impact deployment questions
|
||||
- explains rootless vs rootful placement, deployment notes, and validation steps
|
||||
- can generate helper scripts with `install.sh` as the canonical apply step, plus `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh`
|
||||
- identifies required repo-local support files such as mounted config, init assets, and helper scripts that must ship with the result
|
||||
- validates env completeness before claiming runnable output
|
||||
- encourages explicit finalize and execution checklists for support files and env completeness
|
||||
- explains rootless vs rootful apply targets, deployment notes, and validation steps
|
||||
|
||||
## Design principles
|
||||
|
||||
@@ -19,6 +24,9 @@ A skill for migrating `docker run` commands and Docker Compose-style deployments
|
||||
- do not invent deployment-specific values
|
||||
- make lossy mappings explicit
|
||||
- prefer maintainable output over mechanical one-to-one translation
|
||||
- default to review-first output in the current directory before installation
|
||||
- prefer pod-first topology over preserving bridge networking when pod grouping expresses the intent cleanly
|
||||
- copy runtime-required files to their correct host-side destinations, not just into the Quadlet unit directory
|
||||
|
||||
## Operating modes
|
||||
|
||||
@@ -30,7 +38,7 @@ A skill for migrating `docker run` commands and Docker Compose-style deployments
|
||||
|
||||
- `SKILL.md` contains the operating modes, workflow, and high-level rules
|
||||
- `references/compose-mapping.md` covers field mapping and topology decisions
|
||||
- `references/env-strategy.md` covers env handling and secret defaults
|
||||
- `references/env-strategy.md` covers env handling, completeness validation, and typo detection
|
||||
- `references/github-repo-intake.md` covers repository discovery and canonical input selection
|
||||
- `references/deployment-notes.md` covers deployment guidance
|
||||
- `references/validation.md` covers validation and troubleshooting
|
||||
|
||||
@@ -7,10 +7,15 @@
|
||||
## 功能概览
|
||||
|
||||
- 将 `docker run` 和 Compose 风格输入转换为面向 Quadlet 的设计
|
||||
- 帮助在 `.container`、`.pod`、`.network`、`.volume`、`.build` 之间做选择
|
||||
- 默认先把生成产物写到当前目录,便于审查后再应用
|
||||
- 帮助在 `.container`、`.pod`、`.network`、`.volume`、`.build` 之间做选择,并对多容器服务默认偏向 pod-first 拓扑
|
||||
- 在合适时保留 `.env` / `env_file` 工作流
|
||||
- 将大型 env 模板归纳为少量高影响部署问题
|
||||
- 说明 rootless / rootful 放置路径、部署说明与验证步骤
|
||||
- 可生成辅助脚本,其中 `install.sh` 是规范的 apply 步骤,另可生成 `reload.sh`、`start.sh`、`stop.sh`、`restart.sh`
|
||||
- 会识别并交付运行所需的 repo 内配套文件,例如挂载配置、初始化资源和辅助脚本
|
||||
- 在声称结果可运行前,会检查环境变量完整性,而不是只做 env 摘要
|
||||
- 鼓励在 finalize 与 execution 阶段显式使用 support files 与 env completeness 检查清单
|
||||
- 说明 rootless / rootful 应用目标路径、部署说明与验证步骤
|
||||
|
||||
## 设计原则
|
||||
|
||||
@@ -19,6 +24,9 @@
|
||||
- 不虚构部署相关取值
|
||||
- 对有损映射保持显式说明
|
||||
- 优先输出可维护的结果,而不是机械一比一转换
|
||||
- 默认先输出到当前目录供审查,再执行安装
|
||||
- 当 pod 分组已经能清晰表达意图时,优先采用 pod-first 拓扑而不是保留 bridge 网络
|
||||
- 将运行必需文件复制到各自正确的主机路径,而不只是复制到 Quadlet 单元目录
|
||||
|
||||
## 运行模式
|
||||
|
||||
@@ -30,7 +38,7 @@
|
||||
|
||||
- `SKILL.md`:运行模式、工作流和高层规则
|
||||
- `references/compose-mapping.md`:Compose 字段映射与拓扑决策
|
||||
- `references/env-strategy.md`:env 处理与 secret 默认策略
|
||||
- `references/env-strategy.md`:env 处理、完整性校验与 typo 检测
|
||||
- `references/github-repo-intake.md`:仓库发现与 canonical 输入选择
|
||||
- `references/deployment-notes.md`:部署说明
|
||||
- `references/validation.md`:验证与排障
|
||||
|
||||
92
SKILL.md
92
SKILL.md
@@ -1,11 +1,11 @@
|
||||
---
|
||||
name: quadlet-migrator
|
||||
description: Convert docker run commands or Docker Compose configurations into maintainable Podman Quadlet files, help users map env/env_file/.env usage into Environment or EnvironmentFile, and explain rootless or rootful deployment details and migration risks.
|
||||
description: Convert docker run commands 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.
|
||||
---
|
||||
|
||||
# Quadlet Migrator
|
||||
|
||||
Use this skill when the user wants to migrate `docker run`, `docker compose`, or Compose-like service definitions into Podman Quadlet units, especially when environment variables, `env_file`, `.env`, rootless deployment, or systemd layout need to be planned or generated.
|
||||
Use this skill when the user wants to migrate `docker run`, `docker compose`, or 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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -15,8 +15,12 @@ This skill helps you:
|
||||
|
||||
- discover Docker deployment entry points from a GitHub repository URL
|
||||
- translate `docker run` flags and Compose service fields into Quadlet units
|
||||
- choose between `.container`, `.pod`, `.network`, `.volume`, and `.build`
|
||||
- choose between `.container`, `.pod`, `.network`, `.volume`, and `.build`, with a pod-first bias for multi-container services
|
||||
- decide whether values belong in `Environment=` or `EnvironmentFile=`
|
||||
- write reviewable output to the current directory by default before the user applies it to a live Quadlet search path
|
||||
- generate helper scripts with `install.sh` as the canonical apply script name, plus `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` when producing runnable artifacts
|
||||
- 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
|
||||
- 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
|
||||
@@ -61,6 +65,7 @@ Tasks in this phase:
|
||||
- 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.
|
||||
@@ -73,6 +78,8 @@ Tasks in this phase:
|
||||
- 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.
|
||||
- external URLs, domains, and ports
|
||||
@@ -86,6 +93,9 @@ Tasks in this phase:
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
At the end of planning, summarize what you learned and what you intend to generate, then explicitly ask the user whether anything should be changed or added before you move to the next phase.
|
||||
@@ -112,11 +122,13 @@ Tasks in this phase:
|
||||
|
||||
1. Freeze the chosen service set and runtime grouping.
|
||||
- prefer putting the whole project in a single pod when practical
|
||||
- if the project is a simple single-container deployment, a standalone `.container` is acceptable
|
||||
- if shared networking, shared published ports, or tighter lifecycle coupling make pod semantics useful, prefer one or more `.pod` units
|
||||
- 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
|
||||
- containers in different pods must not be treated as reachable via `127.0.0.1` / `localhost`; if you split the topology across multiple pods, use container networking and service addressing, or publish ports across the host boundary when that better matches the deployment
|
||||
- containers in different pods must not be treated as reachable via `127.0.0.1` / `localhost`; if you split the topology across multiple pods, use container naming, pod naming, or service-level addressing instead
|
||||
- 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.
|
||||
- named volume, bind mount, or anonymous volume per storage use case
|
||||
@@ -136,16 +148,30 @@ Tasks in this phase:
|
||||
- use `EnvironmentFile=` for bulk variables, secrets, or values already sourced from `.env` / `env_file`
|
||||
- if Compose interpolation references variables that are missing, report them explicitly and prepare a candidate env file with placeholders or suggested defaults instead of delegating the entire review back to the user
|
||||
- treat variable names containing `PASSWORD`, `TOKEN`, `SECRET`, `KEY`, `PRIVATE`, or `PASS` as sensitive by default and avoid inlining unless the user explicitly wants that
|
||||
- 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
|
||||
- if a likely required startup variable is still absent from the final output, keep it unresolved instead of downgrading it to an informational note
|
||||
- if referenced env keys and final env keys contain likely near-match typos, call them out explicitly before execution
|
||||
|
||||
5. Summarize already-known conflicts and their chosen resolution.
|
||||
- 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
|
||||
|
||||
At the end of finalize, write `QUADLET-FINALIZE.md` and ask the user to review it before you start writing the final artifacts.
|
||||
|
||||
Before finalizing, use this checklist template:
|
||||
|
||||
- [ ] 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
|
||||
- [ ] any remaining placeholders are explicit and understood as non-runnable until filled
|
||||
|
||||
|
||||
`QUADLET-FINALIZE.md` is a review artifact, not a questionnaire. It should summarize decisions that were already discussed in planning.
|
||||
|
||||
If `QUADLET-FINALIZE.md` already exists, read it first and update it intentionally. Do not blindly overwrite it without checking whether it reflects a prior review round that should be preserved or revised.
|
||||
@@ -161,9 +187,14 @@ When the design has materially changed, replace outdated sections so the file re
|
||||
- image strategy
|
||||
- volume strategy
|
||||
- env strategy
|
||||
- env completeness status, including unresolved required variables and suspicious typo candidates
|
||||
- repo-local support files and directories that must be copied, preserved, or rendered for the deployment to run
|
||||
- which support files come from upstream unchanged versus which are generated or rewritten locally
|
||||
- the intended apply target directory for rootless or rootful deployment
|
||||
- the intended host-side destination paths for required support files, scripts, config trees, and initialization assets
|
||||
- only the minimal placeholders that still cannot be resolved without user secrets or environment-specific values
|
||||
- detected conflicts and how they were resolved
|
||||
- the list of files that will be created in execution phase
|
||||
- the list of files that will be created in execution phase, including generated Quadlet files, any env file or env delta, and helper scripts such as `install.sh`, `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` when applicable; do not introduce a parallel `apply.sh` name unless the user explicitly asks for it
|
||||
|
||||
Do not start execution until the user has reviewed and confirmed `QUADLET-FINALIZE.md` or provided requested edits.
|
||||
|
||||
@@ -175,13 +206,39 @@ Goal: write the approved runnable artifacts.
|
||||
|
||||
Tasks in this phase:
|
||||
|
||||
1. Generate the Quadlet files.
|
||||
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 deployment notes or validation guidance only when they materially help the user operate the result.
|
||||
4. Generate a README only when the user explicitly wants a self-contained handoff artifact or a packaged deliverable.
|
||||
3. Generate helper scripts such as `install.sh`, `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` when they materially help the user apply and operate the result.
|
||||
- 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. It should copy env files, mounted config, scripts, and other required runtime support files into the correct host-side paths the deployment actually expects.
|
||||
- `install.sh` should not start, stop, restart, or reload services as a side effect.
|
||||
- `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` should manage services only and should not silently install or overwrite files.
|
||||
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 contents of `QUADLET-FINALIZE.md`. If the implementation reveals a material conflict with the finalized design, stop and return to planning rather than silently diverging.
|
||||
|
||||
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, 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
|
||||
|
||||
|
||||
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
|
||||
@@ -205,15 +262,20 @@ Stop and ask the user before finalizing or generating runnable output when any o
|
||||
- image strategy versus local build strategy is materially ambiguous
|
||||
- a lossy mapping would change runtime behavior in a way that matters
|
||||
- the requested deployment mode conflicts with the intended output location or operator model
|
||||
- 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.
|
||||
|
||||
## Rootless vs rootful
|
||||
|
||||
Decide early whether the deployment is rootless or rootful, because this changes the output path and some operational guidance.
|
||||
Decide early whether the deployment is rootless or rootful, because this changes the apply target path and some operational guidance.
|
||||
|
||||
- For rootless deployments, use `~/.config/containers/systemd/` unless the user has a reason to use another supported path.
|
||||
- For rootful deployments, use `/etc/containers/systemd/` unless the user asks for a different placement.
|
||||
- By default, generate reviewable artifacts in the current working directory first.
|
||||
- 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, or debugging, read `references/podman-systemd.unit.5.md`.
|
||||
@@ -250,7 +312,8 @@ When the user wants runnable output, provide the relevant deployment notes from
|
||||
|
||||
At minimum, mention the need to:
|
||||
|
||||
- place files in a valid Quadlet directory
|
||||
- review the generated files in the current directory
|
||||
- apply the reviewed files into the correct Quadlet directory and host-side runtime paths
|
||||
- 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
|
||||
@@ -260,6 +323,7 @@ At minimum, mention the need to:
|
||||
- `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`, `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` into the current directory, with `install.sh` as the canonical apply step
|
||||
|
||||
## Anti-examples
|
||||
|
||||
|
||||
@@ -48,14 +48,18 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
||||
- Normalize relative host paths against the Compose file directory and emit absolute paths in the final Quadlet output.
|
||||
- Named volumes can remain referenced by name, but when the user wants explicit infrastructure-as-code, create matching `.volume` units.
|
||||
- Ask the user which volume mode they want when the source does not make the intended persistence model obvious.
|
||||
- If a bind mount points to a repo-local file or directory, include that source in the reviewable deliverable set unless the user explicitly wants a host-managed external path instead.
|
||||
- If a bind mount references a whole directory, inspect and preserve the required directory contents rather than only naming the directory root.
|
||||
|
||||
### `networks`
|
||||
|
||||
- If the source uses a default network only, you often do not need a `.network` unit.
|
||||
- If a custom network is intentional and needs to be managed declaratively, create a `.network` unit and reference it explicitly.
|
||||
- Prefer pod-first topology over preserving Compose bridge networks mechanically.
|
||||
- If the source uses a default network only, you often do not need a `.network` unit at all.
|
||||
- If the source uses bridge networking for containers that can reasonably live in one pod, collapse that topology into one `.pod` so the containers share one network namespace.
|
||||
- Create a `.network` unit only when services must be split across pods, or when explicit network isolation or custom network management is materially required.
|
||||
- Containers in the same `.pod` can communicate over `127.0.0.1` / `localhost` because they share a network namespace.
|
||||
- Containers in different pods must not be treated as reachable via `127.0.0.1` / `localhost`.
|
||||
- When splitting services across multiple pods, use container networking and service-level addressing, or publish ports to the host boundary when that is the intended access pattern.
|
||||
- When splitting services across multiple pods, use container names, pod names, or service-level addressing across the shared network, or publish ports to the host boundary when that is the intended access pattern.
|
||||
|
||||
### `environment`
|
||||
|
||||
@@ -84,11 +88,6 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
||||
- Translate to `Requires=` and `After=` when that reflects intent.
|
||||
- State clearly that this controls startup ordering, not application readiness.
|
||||
|
||||
### `restart`
|
||||
|
||||
- Map common cases to `[Service] Restart=`.
|
||||
- If the source policy has no direct systemd equivalent, choose the nearest safe mapping and explain it.
|
||||
|
||||
### `healthcheck`
|
||||
|
||||
- Prefer dedicated Quadlet health fields such as `HealthCmd=`, `HealthInterval=`, `HealthTimeout=`, `HealthRetries=` when representable.
|
||||
@@ -98,6 +97,7 @@ Use this file when converting `docker-compose.yml` or `compose.yaml` into Quadle
|
||||
|
||||
- `entrypoint` typically maps to `Entrypoint=`.
|
||||
- `command` typically maps to `Exec=`.
|
||||
- If an entrypoint or helper script is repo-local, treat it as a support file that must be copied or preserved in the generated layout.
|
||||
|
||||
### `user`
|
||||
|
||||
@@ -136,7 +136,7 @@ Image=docker.io/library/nginx:latest
|
||||
PublishPort=8080:80
|
||||
```
|
||||
|
||||
Use this when the deployment is truly a simple single-service case and pod semantics add little value.
|
||||
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
|
||||
|
||||
@@ -160,7 +160,7 @@ Reasonable result shape:
|
||||
- `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
|
||||
|
||||
Use this when shared networking and a grouped lifecycle make the deployment easier to operate.
|
||||
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
|
||||
|
||||
@@ -168,10 +168,15 @@ Choose the simplest topology that preserves the source deployment intent.
|
||||
|
||||
Prefer a single `.pod` for multi-container applications when practical.
|
||||
|
||||
If the project is a simple single-container deployment with no real need for pod semantics, a standalone `.container` is acceptable.
|
||||
If one logical service contains multiple containers, default to putting them in the same `.pod` so they share networking and lifecycle.
|
||||
|
||||
If shared networking, shared published ports, or tightly coupled service lifecycle make pod semantics useful, prefer one or more `.pod` units.
|
||||
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 other service-level addressing 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,20 +2,61 @@
|
||||
|
||||
Use this file when the user wants deployment-ready instructions alongside generated Quadlet units.
|
||||
|
||||
## Directory choice
|
||||
## Delivery flow
|
||||
|
||||
1. Generate the reviewable artifacts in the current working directory.
|
||||
2. Review 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 unit files into the chosen Quadlet directory. Copy env files and any other required runtime support files into the correct host-side paths the deployment expects.
|
||||
4. Use `reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` to manage the deployed services.
|
||||
|
||||
## Apply target directory
|
||||
|
||||
### Rootless
|
||||
|
||||
- primary default: `~/.config/containers/systemd/`
|
||||
- default apply target: `~/.config/containers/systemd/`
|
||||
- user-scoped management commands use `systemctl --user`
|
||||
|
||||
### Rootful
|
||||
|
||||
- primary default: `/etc/containers/systemd/`
|
||||
- default apply target: `/etc/containers/systemd/`
|
||||
- system-scoped management commands use `systemctl`
|
||||
|
||||
See `podman-systemd.unit.5.md` for the full search-path matrix.
|
||||
|
||||
## Helper scripts
|
||||
|
||||
- `install.sh`: canonical apply script; copy only reviewed Quadlet unit files into the selected Quadlet target directory, and copy env files plus any other required runtime support files into the correct host-side paths
|
||||
- do not generate a separate `apply.sh` by default; reserve that alternate name only when the user explicitly asks for it
|
||||
- `reload.sh`: run the appropriate `daemon-reload` command after installation changes
|
||||
- `start.sh`: start the generated units
|
||||
- `stop.sh`: stop the generated units
|
||||
- `restart.sh`: restart the generated units after reload or config changes
|
||||
|
||||
Keep installation separate from service-management scripts so the user can review generated files before applying them.
|
||||
`install.sh` should copy reviewed Quadlet unit files into the chosen Quadlet target directory and place required runtime support files into their correct host-side destinations only, and should not start, stop, restart, or reload services as a side effect.
|
||||
`reload.sh`, `start.sh`, `stop.sh`, and `restart.sh` should not silently install or overwrite reviewed files.
|
||||
|
||||
## Review checklist before install
|
||||
|
||||
Review not only the Quadlet unit files but also:
|
||||
|
||||
- env files referenced by `EnvironmentFile=`
|
||||
- repo-local mounted config files and directory trees
|
||||
- initialization files such as `init.sql`, seed data, or bootstrap assets
|
||||
- repo-local entrypoint and helper scripts referenced by `Entrypoint=`, `Exec=`, docs, or wrapper scripts
|
||||
|
||||
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
|
||||
- [ ] unit files map to the intended Quadlet directory
|
||||
- [ ] support files map to the correct host-side runtime paths for mounts and scripts
|
||||
- [ ] startup-critical env keys are present in the final env sources
|
||||
- [ ] any unresolved values are clearly marked as intentionally non-runnable placeholders
|
||||
- [ ] service-management scripts operate on the same reviewed artifact set that will be installed
|
||||
|
||||
## Rootless operational notes
|
||||
|
||||
- Bind mounts may hit UID/GID mismatches.
|
||||
@@ -32,6 +73,7 @@ sudo loginctl enable-linger <username>
|
||||
- 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.
|
||||
- Explain the resolved absolute path if the source used `./...`.
|
||||
- If the source project bind-mounts repo-local files or directories, make sure the installed artifact set preserves the required contents and places them at the correct host-side paths expected by the mounts.
|
||||
|
||||
## Recommended service defaults
|
||||
|
||||
|
||||
@@ -9,11 +9,23 @@ Use this file whenever the migration includes `.env`, `env_file`, Compose interp
|
||||
- keep resulting units readable
|
||||
- report missing variables explicitly
|
||||
- reduce large upstream env templates into a small set of user decisions
|
||||
- validate env completeness before claiming runnable output
|
||||
|
||||
## Default rules
|
||||
|
||||
The agent should actively interpret the env template and its comments. Do not offload the entire env review back to the user.
|
||||
|
||||
Runnable output requires an env completeness check, not just env summarization.
|
||||
A variable is not considered satisfied unless it is present in one of the actual final output sources:
|
||||
|
||||
- `Environment=` in generated Quadlet
|
||||
- the final `EnvironmentFile=` contents
|
||||
- a documented default that is intentionally preserved in the runnable result
|
||||
- an explicit placeholder, but only when the result is intentionally not yet runnable
|
||||
|
||||
If a variable is still absent from the actual output sources, keep it unresolved.
|
||||
Do not silently downgrade a startup-critical variable into an informational note.
|
||||
|
||||
### Prefer `Environment=` when
|
||||
|
||||
- there are only a few variables
|
||||
@@ -59,6 +71,23 @@ Strategy:
|
||||
|
||||
Do not fabricate values.
|
||||
|
||||
## Env completeness validation
|
||||
|
||||
Before producing runnable artifacts:
|
||||
|
||||
- compare variables referenced by Compose, interpolation, docs, startup scripts, and image-specific setup guidance against the variables present in the final output
|
||||
- verify that every `EnvironmentFile=` referenced in the final result actually contains the required keys the service depends on
|
||||
- treat missing bootstrap credentials for common stateful services as unresolved required variables, not optional omissions
|
||||
- if a high-similarity near-match exists, flag it as a likely typo instead of silently accepting it
|
||||
|
||||
Examples of suspicious mismatches:
|
||||
|
||||
- `POSTGRES_PASSWRD` vs `POSTGRES_PASSWORD`
|
||||
- singular/plural mismatches such as `ALLOWED_HOST` vs `ALLOWED_HOSTS`
|
||||
- prefix mismatches where the docs and final env disagree on the canonical key name
|
||||
|
||||
If a required key is mentioned in the source docs, image guidance, or startup scripts but is absent from the final output sources, stop before claiming runnable output.
|
||||
|
||||
## Agent responsibility
|
||||
|
||||
When the source project ships a large `.env.example` or multiple env templates:
|
||||
@@ -67,6 +96,7 @@ When the source project ships a large `.env.example` or multiple env templates:
|
||||
- determine which values can safely stay at documented defaults
|
||||
- determine which values are true deployment decisions and must be confirmed with the user
|
||||
- prepare a candidate `.env` or env delta instead of asking the user to read the whole template manually
|
||||
- verify that the final env output still contains the variables needed for minimal startup
|
||||
|
||||
The user should only need to answer the small number of high-impact questions that cannot be discovered locally.
|
||||
|
||||
@@ -123,6 +153,21 @@ Recommended behavior:
|
||||
- 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
|
||||
|
||||
### Required variable still missing
|
||||
|
||||
Source intent:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
EnvironmentFile=/home/nite/pod/dify/dify.env
|
||||
Environment=POSTGRES_USER=postgres
|
||||
Environment=POSTGRES_DB=dify
|
||||
Environment=PGDATA=/var/lib/postgresql/data/pgdata
|
||||
```
|
||||
|
||||
If `dify.env` does not contain `POSTGRES_PASSWORD`, do not treat this as runnable output.
|
||||
Report `POSTGRES_PASSWORD` as unresolved and stop before final runnable generation.
|
||||
|
||||
## Output patterns
|
||||
|
||||
### Small inline set
|
||||
@@ -150,6 +195,25 @@ Environment=APP_ENV=production
|
||||
EnvironmentFile=/opt/myapp/myapp.env
|
||||
```
|
||||
|
||||
## Finalize checklist template
|
||||
|
||||
Before freezing the env plan, confirm:
|
||||
|
||||
- which keys are satisfied by `Environment=`
|
||||
- which keys are satisfied by the final `EnvironmentFile=`
|
||||
- which keys are preserved via documented defaults
|
||||
- which keys remain unresolved and therefore block runnable output
|
||||
- which keys look like typo candidates and need human confirmation
|
||||
|
||||
## Execution checklist template
|
||||
|
||||
Before writing runnable artifacts, confirm:
|
||||
|
||||
- the final env file contains every required startup key
|
||||
- every `EnvironmentFile=` path in the generated Quadlet matches an actual generated or preserved file
|
||||
- placeholder values are clearly marked and do not masquerade as confirmed production values
|
||||
- typo-suspect keys are either corrected or explicitly surfaced in the output
|
||||
|
||||
## Missing-variable reporting
|
||||
|
||||
When variables cannot be resolved, report them as a concrete checklist.
|
||||
@@ -159,6 +223,7 @@ Example:
|
||||
- missing `DB_PASSWORD`
|
||||
- missing `IMMICH_VERSION`
|
||||
- missing `UPLOAD_LOCATION`
|
||||
- likely typo: `POSTGRES_PASSWRD` should probably be `POSTGRES_PASSWORD`
|
||||
|
||||
If the user asks for scaffolding, generate a sample env file with obvious placeholders.
|
||||
|
||||
|
||||
@@ -29,15 +29,18 @@ Discover the canonical self-hosting assets before attempting any Quadlet convers
|
||||
- `.devcontainer/`
|
||||
6. Read deployment-specific README files in those directories.
|
||||
7. Identify helper scripts that generate or sync compose files.
|
||||
8. Identify repo-local companion files required at runtime, such as mounted config, templates, initialization files, seed data, bootstrap assets, entrypoint scripts, and bind-mounted directory trees.
|
||||
|
||||
## What to extract
|
||||
|
||||
- canonical compose file path
|
||||
- companion env template path
|
||||
- additional compose files used for middleware or optional services
|
||||
- repo-local companion files required for runtime, such as config, templates, initialization files, bootstrap assets, entrypoint scripts, or mounted directories
|
||||
- whether the compose file is generated
|
||||
- whether the source relies on profiles
|
||||
- whether startup requires preparatory steps such as copying `.env.example` to `.env`
|
||||
- whether those companion files must be copied, rendered, or kept in a specific relative layout for the deployment to work
|
||||
|
||||
## Heuristics
|
||||
|
||||
@@ -46,12 +49,30 @@ Discover the canonical self-hosting assets before attempting any Quadlet convers
|
||||
- If the repo has both a template and a generated compose file, treat the generated file as the runnable source and the template as explanatory context.
|
||||
- If profiles control optional databases or vector stores, decide which profile set the user actually wants before generating Quadlet.
|
||||
- If env management is mandatory, preserve that pattern rather than flattening hundreds of variables into inline `Environment=` values.
|
||||
- If the source mounts or references repo-local config, templates, initialization assets, entrypoint scripts, or directory trees, treat them as first-class deployment inputs rather than incidental files.
|
||||
- If a Compose bind mount points to a repo-relative file or directory, treat that path as a candidate support-file source rather than only recording the mount string.
|
||||
- If docs or startup scripts say to copy, edit, mount, or render a repo-local file before startup, include that asset in the deliverable review set.
|
||||
- If a whole directory is mounted, inspect the directory contents and preserve the required files instead of only naming the directory root.
|
||||
- Do not reduce runnable output to only Quadlet plus env when the source project depends on additional repo-local assets.
|
||||
- If several candidate compose files exist, explain which one you selected and why.
|
||||
|
||||
## Support-file checklist template
|
||||
|
||||
Before choosing the final source of truth, confirm:
|
||||
|
||||
- which repo-local files are mounted directly
|
||||
- which repo-local directories are mounted as whole trees
|
||||
- which startup docs require copying, editing, or rendering companion files
|
||||
- which entrypoint or helper scripts refer to additional local assets
|
||||
- which companion files are mandatory for minimal startup versus optional extras
|
||||
|
||||
Use this checklist to prevent reducing the deliverable to Quadlet plus env when the source project depends on more than that.
|
||||
|
||||
## Migration posture for GitHub-sourced projects
|
||||
|
||||
When converting a GitHub-hosted project, report:
|
||||
|
||||
- which files you chose as source of truth
|
||||
- which required repo-local companion files must ship with the result
|
||||
- which optional files or profiles you ignored
|
||||
- which variables still require user decisions
|
||||
|
||||
@@ -4,6 +4,13 @@ Use this file when the user asks how to verify or troubleshoot generated Quadlet
|
||||
|
||||
## Basic deployment flow
|
||||
|
||||
1. Review the generated files in the current working directory and confirm the expected Quadlet units, env files, helper scripts, and required repo-local support files exist.
|
||||
2. Run `install.sh` to copy only the reviewed unit files into the target Quadlet directory and place required runtime support files into the correct host-side paths.
|
||||
3. Run the appropriate reload command.
|
||||
4. Start the relevant units and inspect their status.
|
||||
|
||||
If the user requested an alternate apply script name explicitly, substitute that name where needed, but treat `install.sh` as the default documentation path.
|
||||
|
||||
### Rootless
|
||||
|
||||
```bash
|
||||
@@ -46,12 +53,37 @@ For user units:
|
||||
systemd-analyze --user verify <unit>.service
|
||||
```
|
||||
|
||||
## Support-file and env checks
|
||||
|
||||
Before calling the result runnable, verify that:
|
||||
|
||||
- every referenced `EnvironmentFile=` exists at the installed path
|
||||
- required env keys are actually present in the final env sources
|
||||
- bind-mounted files and directories exist after installation
|
||||
- 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
|
||||
|
||||
Runnable-output gate checklist template:
|
||||
|
||||
- [ ] the support-file set is complete
|
||||
- [ ] env completeness check passed against the actual final env sources
|
||||
- [ ] unit files are installed in the intended Quadlet directory
|
||||
- [ ] support files are installed at the host-side runtime paths expected by mounts and scripts
|
||||
- [ ] service-management scripts operate on the same artifact set that was reviewed
|
||||
- [ ] no required support file, env key, or typo-suspect mismatch remains unresolved
|
||||
|
||||
Do not call the result runnable until every item above is checked.
|
||||
|
||||
## Common failure causes
|
||||
|
||||
- unsupported Quadlet option for the installed Podman version
|
||||
- bind-mount source directory missing
|
||||
- wrong rootless or rootful unit directory
|
||||
- files were generated but `install.sh` has not yet copied the unit files into the target rootless or rootful unit directory and the required runtime support files into their host-side paths
|
||||
- wrong rootless or rootful apply target directory
|
||||
- unresolved env file path
|
||||
- required env key missing from the final env file
|
||||
- likely env-key typo or mismatch between source docs and final env output
|
||||
- required repo-local config, init assets, or helper scripts missing from the installed artifact set
|
||||
- permissions on rootless bind mounts
|
||||
- readiness assumptions hidden behind `depends_on`
|
||||
|
||||
@@ -60,11 +92,12 @@ systemd-analyze --user verify <unit>.service
|
||||
When validation fails, report:
|
||||
|
||||
- what generated successfully
|
||||
- what failed to generate or start
|
||||
- whether the issue is syntax, unsupported feature, path resolution, or permissions
|
||||
- what was applied successfully
|
||||
- what failed to generate, apply, or start
|
||||
- whether the issue is syntax, unsupported feature, path resolution, installation path, missing support files, missing env keys, or permissions
|
||||
|
||||
## Relationship to execution phase
|
||||
|
||||
Validation belongs after the files are written in the execution phase.
|
||||
Validation belongs after the files are written in the execution phase and applied to a valid Quadlet directory and the correct host-side runtime paths.
|
||||
|
||||
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