Skip to main content

README Structure

All template READMEs should follow this standard structure. This ensures a consistent experience for users across all templates.

Required Sections

These sections must be present (checked by validate-docs.sh):

SectionPurpose
Quick StartNumbered copy-paste steps to install, configure, and run the template
PrerequisitesWhat needs to exist before the template works (DCT, UIS provision-host running, services deployed in cluster)
Project StructureDirectory tree showing the layout the user sees after dev-template <id>

Optional Sections

These are recommended but not enforced:

SectionPurpose
DevelopmentHow to edit, test, and debug the app
CI/CDHow the GitHub Actions workflow works
Try this withCross-references to related/companion templates
VS Code tipOne-line workspace setting the user can paste into their existing .vscode/settings.json (see "VS Code settings pattern" below)

The Environment card

Every non-overlay template detail page on the website renders an Environment card below the TemplateHeader. The card is auto-generated by <TemplateEnvironment> from the template's template-info.yaml, vendored DCT/UIS data, and the template's manifests/deployment.yaml. Contributors don't write any of this by hand — it reads existing files.

The card has up to four numbered sub-sections:

Sub-sectionWhen it showsSource
① What gets set upAlways when there's anything to showtools field (DCT) + requires/provides (UIS services) + init SQL files
② ConfigureWhen the template requires: servicesRead from requires: and params:
③ SetupWhen quickstart.setup has commandsFrom quickstart.setup
④ RunWhen quickstart existsFrom quickstart.run and quickstart.title

For deeper details on what each sub-section renders and the full prop interface, see project-dev-templates.md → Auto-generated documentation sections.

The auto-generated Architecture section

Below the Environment card, non-overlay template pages render an Architecture section with per-diagram collapsible dropdowns. Today each sub-section has two diagrams:

  • Components — a mermaid flowchart showing the named nodes (Developer, DCT, UIS, K8s, app, browser) and how they connect
  • Flow — a mermaid sequence diagram showing the ordered steps at runtime (configure call, UIS provisioning, port-forward, .env write, app run)

Both are auto-generated from the template's template-info.yaml, the vendored DCT/UIS registry data, and the template's manifests/deployment.yaml. Contributors don't write any mermaid by hand. Click any diagram on the rendered docs page to enlarge it in an overlay.

The dropdowns are collapsed by default so developers who just want to run the template aren't confronted with a wall of SVGs. Section headings (### Local development / ### Deployment for app templates; ### Overview for stack templates) stay visible as signposts.

Adding a third diagram (e.g. Errors, Data flow, Network) to an existing section is a pure data change in scripts/lib/build-architecture-mermaid.ts's buildArchitectureModel function — push one { name, mermaid } entry onto the section's diagrams array. The emitter and the rendering path are unchanged.

The auto-generated Files dropdown

Inside the Getting Started card, every template page renders a collapsed Files (N) dropdown. When expanded, it shows a tree of every tracked file in the template, with each file linking to its source on GitHub. The list is auto-generated from git ls-files at build time — no curation, no file patterns to maintain.

  • New files you git add appear automatically on the next docs build
  • To exclude a file from the dropdown, add it to .gitignore
  • Overlay templates show only files under their template/ subfolder (the installed content), not the metadata template-info.yaml that sits one level up

The dropdown is intentionally collapsed by default so it doesn't crowd the Prerequisites and Related-templates sub-sections.

The quickstart: block in template-info.yaml

Templates can declare a quickstart: block in template-info.yaml. It does two things:

  1. DCT's dev-template install prints the run command at the end of the install output as a "Run your app" step
  2. The website renders the Setup and Run sub-sections of the Environment card from the same data

The same data drives both surfaces — define it once, get it everywhere.

Schema

quickstart:
title: "Run the Flask app"
setup:
- uv venv
- uv pip install -r requirements.txt
run: "uv run python app/app.py"
note: |
Flask debug server starts on port 3000.
VS Code auto-forwards the port — click the globe icon in the Ports tab.
FieldTypeRequiredPurpose
titlestringyesOne-line label, e.g., "Run the Flask app". Becomes the heading on the Run sub-section.
setuplist of stringsyes (may be empty)One-time setup commands (e.g., uv venv, npm install). Empty array [] for templates with no setup step.
runstringyesThe single command that starts the app (e.g., uv run python app/app.py).
notemulti-line stringnoFree-form text after the run command (port info, what to expect, browser tips).

When to add it

Add quickstart: to any template that has runnable code where the user needs to know what to run after dev-template install finishes. Skip it for overlay templates that just add files (like plan-based-workflow) — there's nothing to run.

Examples per language

# Python (uses uv from DCT)
quickstart:
title: "Run the Flask app"
setup:
- uv venv
- uv pip install -r requirements.txt
run: "uv run python app/app.py"
note: |
Flask runs on port 3000.

# Node / TypeScript
quickstart:
title: "Run the Express server"
setup:
- npm install
run: "npm run dev"
note: |
Server runs on port 3000 with hot reload via nodemon.

# Go (no setup commands needed)
quickstart:
title: "Run the Go server"
setup: []
run: "go run main.go"
note: |
Server runs on port 3000.

# Java (Spring Boot — no setup commands needed)
quickstart:
title: "Run the Spring Boot app"
setup: []
run: "mvn spring-boot:run"
note: |
Spring Boot runs on port 3000.

The auto-generated Configure section

Templates with requires: get a Configure sub-section in the Environment card automatically — no schema fields needed. The section reads requires: and params: from template-info.yaml and tells the user:

  • Which UIS services the template uses (from requires[].service)
  • Which params they must edit before running configure (from params: keys with empty default values)
  • The configure command to run (from configure_command)
  • A collapsible template-info.yaml dropdown with the full raw file so readers can see the editable surface without opening the source
  • A collapsible Expected output dropdown auto-generated from registry data — a sample of what DCT prints when the developer actually runs the configure step. Every value (app name, database, K8s secret, port-forward path) is derived from the template's own template-info.yaml, so the sample matches the template's real defaults and stays in sync when metadata changes. Do not write a hand-authored Expected output mock in the README — it will drift from reality and duplicate this auto-generated content.

Stack templates (those with provides.services:) get a parallel Install sub-section instead of Configure — same shape, just with the stack's uis template install command and stack-flavoured Expected output.

The card auto-adapts based on which yaml blocks are present:

Template hasCard shows
No tools, no requires/provides, no quickstartNo card
Only tools① What gets set up
tools + quickstart① What gets set up, ② Setup (if any), ③ Run
tools + requires + quickstart (app with services)① What gets set up, ② Configure, ③ Setup (if any), ④ Run
tools + provides.services + quickstart (stack)① What gets set up, ② Install, ③ Run

What this means for template authors

If your template has requires: services, you don't need to write any configure documentation in the README — the Configure section is auto-generated. You just need to make sure:

  1. Your params: block has the keys the user needs to edit
  2. The default value is "" (empty string) for params the user MUST set, or a sensible default if optional

Example:

params:
app_name: "" # Required — user must set
database_name: "" # Required — user must set
log_level: "INFO" # Optional — has a default

requires:
- service: postgresql
config:
database: "{{ params.database_name }}"
init: "config/init-database.sql"

The auto-generated Configure section will list params.app_name and params.database_name as the params to edit. params.log_level won't appear because it has a default.

VS Code settings pattern (do not ship .vscode/ files)

Templates must not ship .vscode/settings.json or .vscode/extensions.json files. Per 12MSG in INVESTIGATE-improve-template-docs-with-services.md, DCT does not implement JSON merge for template files. A template that ships .vscode/settings.json would risk overwriting the user's existing VS Code config (including the devcontainer extension recommendation in extensions.json that the project needs to start).

If your template benefits from a specific VS Code workspace setting, document it in the README under a "VS Code tip" section. The pattern (used by python-basic-webserver-database):

**VS Code tip (optional):** if you see "Error refreshing packages" from VS Code's Python extension, add this to your workspace `.vscode/settings.json`:

`​``json
{
"python-envs.alwaysUseUv": true
}
`​``

The error happens because <one-sentence reason>. The setting tells <which extension> to <what it does instead>. If your project's `.vscode/settings.json` already exists with other keys, just add this one — don't replace the file.

The three rules:

  1. One sentence explaining the symptom — what error/problem the user might see
  2. One sentence explaining the fix — what the setting does
  3. The literal one-line addition — copy-pasteable JSON
  4. A "don't replace the file" reminder — protects users with existing VS Code config

If a setting becomes universally needed across many templates, the right home is DCT's base devcontainer image (extension recommendations + workspace defaults), not template-level files. That's a DCT investigation, not a template change.

Required Sections for templates with requires

If your template declares requires: in template-info.yaml (i.e., it needs UIS services like PostgreSQL, Redis, Authentik), the README must include these additional sections:

SectionPurpose
What this isBrief description of the app — what it does, what endpoints it has, what the user will see when it runs
Prerequisites (UIS-aware)Verify the UIS provision-host container is running. Mention that DCT v1.7.34+ provides the uis shim so commands like uis status and uis connect work from inside DCT.
Inline file contentEmbed template-info.yaml (at minimum the params: and requires: sections) and the init file(s) (e.g., config/init-database.sql) directly in the README so users see the format without opening files
Verify it workedA DB-level (or service-level) verify command that doesn't require running the app — for PostgreSQL, uis connect <service> <db> is the canonical pattern

Removed sections

These sections used to be optional but should NOT be added to new templates:

  • Docker Build — manual docker build and docker run bypass the GitHub Actions pipeline. New templates should not document the manual flow.
  • Kubernetes Deployment — manual kubectl apply bypasses ArgoCD. New templates should use a single "Deploy" section that walks through git push → GitHub Actions → ArgoCD.

Template — basic app (no requires)

# Template Display Name

Brief one-line description of what this template provides.

## Quick Start

1. Create the project from this template:
`​``bash
dev-template <template-id>
`​``

2. Run the app:
`​``bash
<your run command here>
`​``

3. Open in browser: http://localhost:<port>

## Prerequisites

Development tools are installed automatically by the devcontainer.
If you need to reinstall, run: `dev-setup`

## Project Structure

After installation, your project contains:

`​``plaintext
├── app/
│ └── main.ext # Application entry point
├── manifests/
│ ├── deployment.yaml # K8s Deployment + Service
│ └── kustomization.yaml # ArgoCD configuration
├── .github/
│ └── workflows/
│ └── urbalurba-build-and-push.yaml # CI/CD pipeline
├── Dockerfile # Container build
├── template-info.yaml # Template metadata
└── README-<template-name>.md # This file
`​``

## Development

- Edit `app/main.ext` — the main application file
- Describe hot reload behavior if applicable
- The `/` endpoint returns "Hello World" with template name and time/date

## Deploy to your local cluster

1. `git push` — GitHub Actions builds and pushes the image
2. `./uis argocd register <app-name> <repo-url>` — register with ArgoCD (one-time)
3. Access the app at `http://<app-name>.localhost`

Template — app with requires (database, auth, etc.)

For templates that depend on UIS services, follow the pattern from python-basic-webserver-database:

# Template Display Name

Brief one-line description.

## What this is

A small but complete <framework> application:

| Endpoint | Method | Returns |
|---|---|---|
| `/` | GET | ... |
| `/items` | GET | ... |

The app **requires** `<ENV_VAR>` and exits if it's missing.

## Prerequisites

This template uses UIS to configure <service>. Verify the UIS provision-host container is running:

`​``bash
docker ps --filter name=uis-provision-host --format '{{.Status}}'
`​``

Inside DCT v1.7.34+ you also have the `uis` shim. If `<service>` isn't deployed, `dev-template-configure` will tell you what to run.

## Quick Start

### 1. Install the template
`​``bash
dev-template <template-id>
`​``

### 2. Edit `template-info.yaml`
Open `template-info.yaml`, find the `params:` section, set your values:

`​``yaml
params:
app_name: "my-cool-app"
database_name: "my_cool_app_db"
`​``

The full `template-info.yaml` declares the dependency:
`​``yaml
requires:
- service: <service>
config:
...
init: "config/init-<service>.<ext>"
`​``

### 3. (Optional) Customise `config/init-<service>.<ext>`
`​``<lang>
-- The init file content goes here, embedded in the README
`​``

All statements should be idempotent so re-running configure is safe.

### 4. Run `dev-template-configure`
`​``bash
dev-template-configure
`​``

### 5. Verify the database (or service)
`​``bash
uis connect <service> <db-or-resource>
`​``

### 6. Run the app
`​``bash
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
python app/app.py
`​``

### 7. Open in your browser
VS Code's Ports tab auto-forwards the port. Click the globe icon next to it.

## Project Structure

After installation, your project contains:

`​``plaintext
├── app/
├── config/
│ └── init-<service>.<ext> # Schema/config (applied by dev-template-configure)
├── manifests/
├── .vscode/
│ └── settings.json # IDE settings
├── .gitignore # Excludes .env*, .venv/, etc.
├── template-info.yaml # Template metadata
└── README-<template-name>.md # This file
`​``

## Development

...

## Deploy to your local cluster

1. `git push` — GitHub Actions builds and pushes the image
2. `./uis argocd register <app-name> <repo-url>` — register with ArgoCD
3. Access the app at `http://<app-name>.localhost`

The Kubernetes Secret containing service credentials is created automatically by `dev-template-configure` (via UIS) and referenced from `manifests/deployment.yaml` via `secretKeyRef`. You don't need to create it manually.

## Try this with

- [Companion or related templates](../<category>/<other-template>) — describe how they compose

Notes

  • The Quick Start section is the most important — users see it first after installation
  • Project Structure should show the layout the user sees after dev-template <id> runs, not the template source layout
  • Keep descriptions concise — the README is a quick reference, not a tutorial
  • Don't include tool installation instructions — dev-template <id> and dev-template-configure handle this via tools: in template-info.yaml
  • For templates with requires:, embed the file contents for template-info.yaml and init files in the README. Users need to see what they're editing.
  • Don't document manual docker build or kubectl apply workflows. They bypass GitHub Actions + ArgoCD and aren't the standard platform workflow.