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 affects:

  • CSS and JS asset <link> and <script> tags
  • The site-title home link

It does not affect fragment links (#heading), canonical <link rel="canonical"> (which uses site.url), or page URLs defined in nav.yaml — configure those with the full path directly.

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.

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/