Deployment
Braised builds a self-contained dist/ directory of static HTML, CSS, and JS. Serve it with any static host, CDN, or reverse proxy. This page covers the options that affect how assets and links are generated at build time.
Root-hosted sites
No configuration needed. Build once, copy dist/ to your host:
braised build
rsync -av dist/ user@host:/var/www/html/
Sub-path deployment
When a site is served from a path prefix (e.g. /docs or /staging/my-branch) rather than a domain root, the default root-relative asset links (/assets/braised.css) will 404. Set base_url in braised.yaml to prefix all generated links:
site:
base_url: /docs
base_url is applied to every root-relative URL Braised outputs: asset tags, the home link, navigation, content links, braised:ref/ cross-references, and images. Relative links, fragment links, and external URLs are never changed. Write content paths relative to the site root — never include the prefix yourself.
Canonical URLs, og:url, and sitemap.xml use site.url instead, which is independent of base_url. For a sub-path site, set url to the full public address including the path. See url and base_url are independent.
Nginx example
location /docs/ {
alias /var/www/html/docs/;
try_files $uri $uri/ /docs/index.html;
}
# braised.yaml
site:
base_url: /docs
Multiple environments
For sites where the base path changes between environments (e.g. root in production, /staging/<branch> in PR previews), keep the production value in braised.yaml and override it per environment. Usually only base_url changes: keep url pointing at production so staging pages declare the production page as canonical.
Environment variable substitution
Any value in braised.yaml can reference environment variables using ${VAR} syntax. Unset variables resolve to an empty string and produce a build warning:
site:
title: My Docs
base_url: ${BRAISED_BASE_URL}
# production — BRAISED_BASE_URL unset → empty → root-hosted
braised build
# staging
BRAISED_BASE_URL=/staging/my-branch braised build
Alternate config file
For larger differences between environments (different output dirs, pipeline endpoints, etc.), maintain a separate config file and pass it with --config:
# braised-prod.yaml
site:
title: My Docs
url: https://docs.example.com
base_url: /docs
pipeline:
command: python3 scripts/ingest-prod.py
braised build --config braised-prod.yaml
When --config is given without an explicit site directory, braised uses the directory containing the config file as the site root (so docs/, nav.yaml, and dist/ are resolved relative to it).
GitHub Actions
jobs:
deploy-staging:
steps:
- uses: actions/checkout@v4
- run: braised build
env:
BRAISED_BASE_URL: /staging/${{ github.ref_name }}
- run: rsync -av dist/ user@staging:/var/www/html/staging/${{ github.ref_name }}/
deploy-production:
steps:
- uses: actions/checkout@v4
- run: braised build --config braised-prod.yaml
- run: rsync -av dist/ user@prod:/var/www/html/docs/