{"schemaVersion":1,"title":"Self-host Docsy","url":"https://appgram.github.io/docsy/guides/deployment/self-hosting","markdownUrl":"https://appgram.github.io/docsy/format-md/guides/deployment/self-hosting","jsonUrl":"https://appgram.github.io/docsy/agent/pages/guides/deployment/self-hosting.json","version":"current","locale":"en","markdown":"# Self-host Docsy\n\nDeploy static documentation or run locked mode on Node, Bun, or Docker.\n\nWritten by: [nedimf](https://github.com/nedimf), [AppGram](https://appgram.dev)\n\nDocsy supports public static hosting and a standalone server running on Node or Bun. Use Node 22.22 or newer to develop and build. Bun 1.3.5 or newer is an optional production runtime. Choose open mode with `agent.query: false` for public static documentation; locked mode or `agent.query: true` uses the server build.\n\n## Deploy an open static build\n\nConfigure open mode and the public URL:\n\n```yaml\nsite:\n  origin: https://docs.example.com\n  basePath: /\n\naccess:\n  mode: open\nagent:\n  query: false\n```\n\nBuild the project:\n\n```bash\nnpm ci\nnpm run build\n```\n\nAstro writes the static site to `dist/`. Docsy also stages a host-neutral copy under `release/`, including the mount-path directory when `site.basePath` is not `/`.\n\nUpload `dist/` when the hosting platform already mounts the project at the configured base path, as GitHub Pages does. Upload `release/` when the server expects the mount-path directory to exist inside the document root.\n\n## Run locked mode\n\nLocked mode needs the standalone server. Public sites can also use this runtime by setting `agent.query: true` to enable live JSON retrieval:\n\n```yaml\naccess:\n  mode: locked\n  provider:\n    type: header\n    tierHeader: x-docsy-tiers\n    userHeader: x-docsy-user\n```\n\nBuild and start it:\n\n```bash\nnpm ci\nnpm run build\nHOST=0.0.0.0 PORT=8080 npm run preview\n```\n\nPut the process behind the trusted authentication proxy described in the lock-mode guide. Do not expose a header-provider deployment directly to the internet.\n\n## Run the production build on Bun\n\nInstall and build with Node as above, then choose Bun for the production process:\n\n```bash\nHOST=0.0.0.0 PORT=8080 npm run start:bun\n# Or: HOST=0.0.0.0 PORT=8080 bun scripts/start.mjs\n```\n\nNo YAML runtime switch is required. `access.mode` and `agent.query` still select static versus server output; the command selects the runtime. `start:bun` also serves staged static output, so public sites can use the same entry point.\n\nThis is production-runtime support tested with Bun 1.3.5. Node remains required for the documented installation, generation, validation, and build commands. It does not imply that Bun's package manager, build toolchain, or test runner replaces those tools. The `npm run test:runtime:bun` integration check starts real Bun processes against generated static and server builds and checks page, Markdown, search, version/locale, permission-gate, and JSON query behavior.\n\nFor a Bun runtime container:\n\n```bash\ndocker build -f Dockerfile.bun -t docsy-bun .\ndocker run --rm -p 8080:8080 docsy-bun\n```\n\n`Dockerfile.bun` builds on Node and runs on a pinned Bun image. The default Dockerfile and Compose service remain Node-based.\n\n## Use Docker Compose\n\nThe repository includes a multi-stage Dockerfile and Compose service:\n\n```bash\ndocker compose up --build\n```\n\nThe container builds the configured site and starts the correct production shape. It works for the static preview server and for the standalone locked-mode server.\n\n## Supply environment-specific configuration\n\nUse environment placeholders for values that change by deployment:\n\n```yaml\nsite:\n  origin: ${DOCSY_ORIGIN:-http://localhost:4321}\n```\n\nSelect a completely different YAML file with `DOCSY_CONFIG`:\n\n```bash\nDOCSY_CONFIG=docsy.enterprise.yaml npm run build\n```\n\nRebuild after changing configuration, Markdown, OpenAPI, or SDK sources. These inputs are compiled into the output.\n\n## Health and exposure checklist\n\n* `npm run validate` and `npm run build` succeed in CI.\n* `site.origin` and `site.basePath` match the public URL.\n* Only `public/` assets are directly exposed as static source files.\n* Protected inputs remain outside `public/`.\n* Locked mode cannot be reached around the trusted proxy.\n* The proxy removes visitor-supplied identity headers before setting its own.\n* Search results and Markdown exports are tested for both authorized and unauthorized visitors.\n\n","contentLocale":"en","isFallback":false,"authorship":{"authors":[{"name":"nedimf","kind":"human","github":"nedimf","avatar":"/docsy/assets/authors/nedimf.png","role":"AppGram","id":"nedimf","url":"https://github.com/nedimf"},{"name":"AppGram","kind":"organization","github":"AppGram","url":"https://appgram.dev","avatar":"/docsy/assets/ag-logo.svg","id":"appgram"}],"contributors":[],"reviewedBy":[]},"editUrl":"https://github.com/AppGram/docsy/edit/main/content/deployment/self-hosting.md"}