Foundry logo Foundry Overview and setup

Core ideas

  • Content lives in Markdown files with frontmatter.
  • Routes are assigned from structured content and language-aware conventions.
  • Themes own presentation through layouts and partials.
  • Themes also own advanced custom-field contracts through theme.yaml.
  • Plugins extend behavior through explicit hook interfaces.
  • A dependency graph supports incremental rebuilds for both documents and taxonomy archive outputs.

Advanced custom fields are no longer declared in content/config/site.yaml. Themes declare field contracts in theme.yaml, page-specific values stay in frontmatter under fields:, and shared/global values live in content/custom-fields.yaml.

Key directories

/content      pages, posts, images, assets, uploads, config
/data         structured data files exposed to rendering
/themes       active theme layouts and assets
/plugins      installed plugins
/public       generated output
/docs         GitHub Pages content and generated coverage output

Foundry ships two Docker shapes. The default docker-compose.yml is local-development oriented: it bind-mounts the project root and keeps data/ and public/ on named Docker volumes. The stricter docker-compose.prod.yml uses an immutable-style runtime with required secrets, a read-only root filesystem, a tmpfs for /tmp, and named volumes for content, themes, plugins, data, and public output.

Docker start

For local Docker development:

sh scripts/docker-init.sh
docker compose up -d --build

That bootstraps a local .env file with random Docker secrets if one does not already exist.

For the stricter production-oriented Docker shape:

export FOUNDRY_ADMIN_SESSION_SECRET="$(openssl rand -hex 32)"
export FOUNDRY_ADMIN_TOTP_SECRET_KEY="$(openssl rand -base64 32)"
docker compose -f docker-compose.prod.yml up -d --build

Before using the production Docker overlay, update content/config/site.docker.prod.yaml so base_url matches the deployed HTTPS origin.

Common commands

foundry
foundry version
foundry build
foundry build --preview
foundry build --env preview --target production
foundry serve
foundry serve --debug
foundry serve-standalone
foundry serve-preview
foundry status
foundry restart
foundry stop
foundry logs -f
foundry service install
foundry service status
foundry service restart
foundry service uninstall
foundry release cut v1.3.3
foundry update check
foundry update apply
foundry plugin list --enabled
foundry theme list
foundry theme migrate field-contracts
foundry routes check
foundry admin hash-password your-password

If you want additional logging, run foundry serve --debug to log request timing, slow-render warnings, memory snapshots, goroutine counts, active request counts, connections, and process CPU time deltas. If admin.debug.pprof is enabled, the admin Debug page also surfaces runtime, content, storage, integrity, activity, and persisted build-report snapshots alongside authenticated pprof links.

If you want Foundry to keep running after the terminal closes, use foundry serve-standalone. Manage that background runtime with foundry status, foundry restart, foundry stop, foundry logs -f, and foundry update check. Foundry stores its runtime files under .foundry/run/ in the project root. If you launch standalone from source with go run, Foundry first builds a managed binary under that directory and keeps the managed binary running.

For a more durable self-hosted runtime, use foundry service install. That installs Foundry as a user-level OS service: systemd --user on Linux or a LaunchAgent on macOS. You can then manage it with foundry service status, foundry service restart, and foundry service uninstall.

Live reload supports two transport modes: stream uses Server-Sent-Events (sse) and is the default. poll checks a lightweight endpoint every 1.5 seconds and is the safer choice if your browser hits local connection limits while reloading.

Media files now live under dedicated collection roots such as content/images, content/videos, content/audio, and content/documents. Reference them from Markdown with the media: scheme, for example ![Hero](media:images/hero.jpg), ![Demo](media:videos/demo.mp4), ![Theme](media:audio/theme.mp3), or [Spec PDF](media:documents/spec.pdf). Static builds also write a frontend search index to public/search.json, and preview builds write public/preview-links.json.

Important config groups

  • Admin: admin.path controls the mount point for the themeable admin shell and defaults to /__admin; username/password login is backed by content/config/admin-users.yaml, browser sessions expire after 30 minutes of inactivity by default, and the default admin theme includes structured frontmatter editing, restore-preview workflows, media replacement, audit log browsing, user-security flows, a command palette, and keyboard shortcuts.
  • Security: security.allow_unsafe_html controls whether raw HTML is preserved in Markdown output.
  • Server: preview/admin serving uses read, write, and idle timeouts by default, and live reload can run in stream or poll mode.
  • Deploy: deploy.targets can override base URL, public dir, theme, preview mode, and related output settings; foundry build --env <name> also layers site.<name>.yaml over the base config when present, and deploy.default_target is applied automatically when no explicit --target is passed.
  • Taxonomies: default and custom taxonomies participate in rendering and incremental rebuild planning.
  • Plugins: enabled plugins are validated and synced into generated registration code.
  • Themes: themes must satisfy the minimum slot contract validated by foundry theme validate.

For the full key-by-key config reference, including all defaults and the exact meaning of each entry, see the Configuration guide.

Operations commands

  • foundry doctor reports timing breakdowns for plugin config, graph load, route assignment, route hooks, asset sync, renderer, and feed generation.
  • foundry validate checks broken links, broken media: references, missing templates, orphaned media, duplicate routes/slugs, and taxonomy inconsistencies.
  • foundry backup create and foundry backup list manage zip snapshots of the content tree, while foundry content export, foundry content import, and foundry content migrate cover portability and schema/layout migration workflows, including --dry-run support for layout and field-rename migrations.

Backup workflow

Foundry keeps backup archives simple and portable. The default backup target is .foundry/backups, and each managed backup is a zip file containing the current content/ tree plus a small manifest entry.

foundry backup create
foundry backup create ./archives/pre-launch.zip
foundry backup list
foundry backup git-snapshot "before launch"
foundry backup git-log 10

You can also enable debounced automatic backups during foundry serve or foundry serve-preview:

backup:
  enabled: true
  dir: ".foundry/backups"
  on_change: true
  debounce_seconds: 45
  retention_count: 20
  min_free_mb: 256
  headroom_percent: 125

Before Foundry writes a backup archive, it checks free disk space on the destination filesystem and fails early if the archive would not have enough headroom.

Foundry also keeps a local Git-backed snapshot history under .foundry/backups/git. That path is intended for versioned local history; it does not push to a remote Git provider yet.

Release updates

Foundry can check GitHub Releases and, for managed standalone installs, apply the latest release automatically:

foundry update check
foundry update apply

Self-update is intentionally limited to serve-standalone deployments. Docker and source installs still get update availability and release notes, but the actual rollout remains manual.

Version tags in this repository also trigger a GitHub Actions release workflow that publishes foundry-*.tar.gz archives and matching .sha256 files for supported platforms.

To cut a release locally, run foundry release cut v1.3.3 from the repository root. Add --push to push the tag immediately, or use scripts/release.sh v1.3.3 --push as a repo-local wrapper around the same command. Foundry requires a clean worktree and a vX.Y.Z version string.

Admin shortcuts

  • Cmd/Ctrl+S saves the current form.
  • Cmd/Ctrl+Enter previews the current document.
  • Cmd/Ctrl+K opens the command palette.
  • Shift+/ toggles shortcut help.
  • g d, g m, g u, and g a jump to Documents, Media, Users, and Audit.

Recommended reading order

  1. Read the architecture guide to understand the package layout and runtime flow.
  2. Use the configuration reference when you need the exact meaning or default for a site.yaml setting.
  3. Read the plugin guide or theme guide before extending those surfaces.
  4. Read the CLI contract before changing command UX.
  5. Open the coverage report if you want to see where tests are still thin.