The dstack.ai site has three parts on one origin: the landing page (
/) is a React app inwebsite/; the docs (/docs) and blog (/blog) are built with MkDocs frommkdocs/. This guide covers the docs and blog (MkDocs). For the landing and for building everything together, see The landing page and Building the whole site below.
git clone https://github.com/dstackai/dstack
cd dstackhttps://docs.astral.sh/uv/getting-started/installation
curl -LsSf https://astral.sh/uv/install.sh | shWarning
Building documentation requires python_version >= 3.11.
uv sync --all-extrasdstack will be installed into the project's .venv in editable mode.
Code formatting and linting can be done automatically on each commit with pre-commit hooks:
uv run pre-commit installTo preview the docs and blog (MkDocs), run the follow command:
uv run mkdocs serve --livereload -sThe --livereload flag is required to work around live-reload bugs in recent mkdocs versions.
This serves the docs and blog only. The landing page (/) is a separate React app — when you
run mkdocs serve on its own, / simply redirects to /docs/. To work on the landing, see
The landing page below.
If you want to build static files, you can use the following command:
uv run mkdocs build -sThe landing page at / is a React (Vite) app in website/, not MkDocs. It has
its own package.json/node_modules. Preview it on its own (requires Node 20+):
just website-dev # Vite dev server on http://127.0.0.1:5173Docs/blog links on the landing resolve same-origin (/docs, /blog), which 404 in standalone
dev. Point them at a live site while iterating: just website-dev https://dstack.ai.
The /old route is kept as a template for building future product pages (reachable in dev; not
part of the production deploy). Google Analytics and the social/OG image reuse the same property
and MkDocs-generated card as the rest of the site.
CI builds the landing and the MkDocs docs/blog and overlays them into a single site/:
just site-build # website/dist + `mkdocs build` -> ./site (scripts/docs/build_site.sh)
just site-serve # preview the combined site on http://127.0.0.1:8001In the combined build the React index.html owns /, while MkDocs serves /docs, /blog, and
the shared /assets. This is what the Build & Deploy Site workflow deploys.
The documentation uses a custom build system with MkDocs hooks to generate various files dynamically.
Use these in .envrc to disable expensive docs regeneration, especially during mkdocs serve auto-reload. Set any of them to disable the corresponding artifact.
export DSTACK_DOCS_DISABLE_LLM_TXT=1
export DSTACK_DOCS_DISABLE_CLI_REFERENCE=1
export DSTACK_DOCS_DISABLE_YAML_SCHEMAS=1
export DSTACK_DOCS_DISABLE_OPENAPI_REFERENCE=1
export DSTACK_DOCS_DISABLE_REST_PLUGIN_SPEC_REFERENCE=1The build process is customized via hooks in scripts/docs/hooks.py:
Files in docs/reference/**/*.md can use #SCHEMA# placeholders that are expanded with generated schema documentation during the build.
Two files are generated for LLM consumption:
-
llms.txt: Structured overview of documentation with titles and descriptions
- Generated from mkdocs nav structure
- Includes sections: Getting started, Concepts, Guides, Examples
- Excludes: Reference section
- Configuration:
scripts/docs/gen_llms_files.py(INCLUDE_SECTIONS, EXCLUDE_SECTIONS)
-
llms-full.txt: Full concatenation of all pages from llms.txt
- Contains complete markdown content of all included pages
The generation logic is in scripts/docs/gen_llms_files.py and uses:
site_name,site_description,site_urlfrommkdocs.yml- Page titles from mkdocs nav structure
- Page descriptions from markdown frontmatter
Adding descriptions: To add descriptions to pages, add YAML frontmatter:
---
title: Page Title
description: Short description of what this page covers
---For examples, add frontmatter to the page files (e.g., mkdocs/docs/examples/training/trl.md).
The build creates .well-known/skills/ directory structure for skills discovery:
- Reads
skills/dstack/SKILL.md - Parses name and description from frontmatter
- Generates
.well-known/skills/index.json - Copies SKILL.md to both
.well-known/skills/dstack/and site root
The HTTP API reference is generated from the FastAPI OpenAPI schema:
scripts/docs/gen_openapi_reference.pywritesmkdocs/docs/reference/http/openapi.json, keeps the per-tag Markdown pages in sync, and updates the generated tag list in the HTTP API index page.- Tag pages use
!!swagger openapi.json tag="<tag>"!!. Keep tag names exactly as they appear in the OpenAPI schema. scripts/docs/hooks.pyexpands the!!swaggerdirective into the Swagger UI container and the hidden operation headings that MkDocs uses for the page table of contents.mkdocs/assets/javascripts/swagger.jsloads the sharedopenapi.json, filters it by tag on the client, and adapts Swagger UI markup to the docs layout.mkdocs/assets/stylesheets/swagger.csscontains Swagger-specific styling and should stay scoped under.dstack-swagger-ui.
Keep hook logic limited to build-time Markdown/page structure, generated assets, and data
attributes needed by the client. Small presentation changes belong in swagger.css; small
behavior changes belong in swagger.js.
If the HTTP API reference needs deeper structural customization, such as replacing major Swagger
UI panels, request/response rendering, model rendering, or "try it out" behavior, prefer moving
toward a dedicated local bundle or custom Swagger UI layout instead of adding more DOM patching.
That bundle can still use the single generated openapi.json and filter by tag on the client, so
we should not reintroduce per-tag OpenAPI files unless there is a concrete reason.
mkdocs/ # docs_dir for the mkdocs site
├── index.md # Redirects to /docs/ (the landing "/" is the React app in website/)
├── docs/ # /docs/ URL section
│ ├── index.md # Getting started
│ ├── installation.md
│ ├── quickstart.md
│ ├── concepts/ # Concept pages
│ ├── guides/ # How-to guides
│ ├── reference/ # API reference (schema expansion)
│ └── examples/ # Example pages (inline source code)
│ └── training/
│ └── trl.md # Page content with frontmatter
├── blog/ # Blog posts
├── overrides/ # Theme customization
├── layouts/ # Social card layouts
└── assets/ # Stylesheets, images, fonts
website/ # React (Vite) landing page — served at "/"
├── index.html # Entry; title, OG/meta, Google Analytics
├── src/ # App, pages (Home, Old), components, routes
└── public/static/ # Landing assets (namespaced to avoid clashing with /assets)
scripts/docs/
├── build_site.sh # Build landing + docs/blog and overlay into ./site
├── hooks.py # MkDocs build hooks
├── gen_llms_files.py # llms.txt generation
├── gen_schema_reference.py # Schema expansion
└── gen_cli_reference.py # CLI reference generation
skills/
└── dstack/
└── SKILL.md # Skills discovery content
When modifying the build system:
- Test local build:
uv run mkdocs build -s - Check generated files in
site/:site/llms.txtsite/llms-full.txtsite/.well-known/skills/index.json
- Verify example pages render correctly
- Check that descriptions appear in llms.txt