building-taubyte-websites
Building Taubyte Websites
When to use
- Creating a brand-new website repo and you need a working
.taubyte/build.sh - A website pushes and "builds" but the cloud serves nothing / 404s
- Adding a build script to a site that was generated with
--template empty - Migrating from another build to the Taubyte expected layout
Hard rule
The build script must write deployable static output into /out. The Taubyte cloud serves whatever ends up in /out after .taubyte/build.sh finishes.
Where the build script lives
<website_repo>/
├── .taubyte/
│ ├── build.sh # executed by the cloud build (and locally)
│ └── config.yaml # build/runtime config (image, env, etc.)
└── ... # source files (index.html, src/, etc.)
Minimal build.sh — static HTML
For a single-page or pure-static site whose source is already deploy-ready (e.g. index.html at the repo root):
#!/usr/bin/env bash
cp index.html /out
exit $?
That's it — no bundler, no build step. This is the pattern used by the bundled html website template and is the simplest known-good baseline.
Recommended starting point — html template
When creating a new website, generate from the bundled html template so you start with a working build.sh + index.html:
tau --defaults --yes new website <site_name> \
--domains <domain_name> \
--paths /<path> \
--template html \
--generate-repository \
--repository-name tb_code_<project>_<site_name> \
--private \
--no-embed-token \
--branch main
tau --defaults --yes import website <site_name>
The template produces:
- An
index.htmlwith simple content .taubyte/build.shthat already doescp index.html /out
This is the recommended baseline before customizing.
Migrating an existing --template empty site
If a site was created with --template empty, copy the html template's behavior into it:
- Add
index.htmlto the website repo root. - Create
.taubyte/build.shcontaining:cp index.html /out exit $? - Make it executable:
chmod +x .taubyte/build.sh. - Push the website repo.
Build script for stack-based sites (Vite / CRA / etc.)
The same rule holds: whatever the stack outputs must end up in /out.
Example shape for Vite:
#!/usr/bin/env bash
set -euo pipefail
npm install
npm run build # writes ./dist/
mkdir -p /out
cp -a dist/. /out/
exit $?
Adapt the build command and source dir to your stack (CRA → build/, Vite → dist/, etc.). Declare environment variables in .taubyte/build.sh itself — that's the only place server-side build env lives.
Verifying the build wrote to /out
When running locally (e.g. inside the Taubyte build container or via bash .taubyte/build.sh in a sandbox):
ls -la /out
Expect at least the entry document (e.g. index.html) and any required assets.
Workflow checklist
Website build progress:
- [ ] index.html (or build artifacts) present in source repo
- [ ] .taubyte/build.sh exists and is executable
- [ ] build.sh writes everything served into /out
- [ ] tau push website <site> -m "..."
- [ ] For Dream: dream inject push-specific for the website repo
- [ ] curl through gateway with Host header to confirm content (see verifying-taubyte-functions)
If the gateway responds but content doesn't route (e.g. no substrate match found), retry the curl with a Host header that includes the gateway port:
curl -i -H "Host: <fqdn>:<gateway_port>" "http://127.0.0.1:<gateway_port>/"
Gotchas
- Empty
/outafter build = blank cloud (or 404). Always confirmcp/cp -a/mvactually populated/out. .taubyte/build.shempty is a common failure when a site was created with--template emptyand never edited — it builds "successfully" but produces nothing.- Typos in
.taubyte/config.yamlcan silently break remote builds. Example:environment:misspelled asenviroment:can cause the cloud builder to ignore config or fail early. - Stack-specific env: don't put runtime env in
config.yaml's wrong section; declare build env inbuild.shonly. - Per-stack output dirs: copy the stack's output dir contents to
/out, not the dir itself.cp -a dist/. /out/is right;cp -a dist /out/puts files under/out/dist/. - Remote static
GET /vs APIs: on a public cloud, if/api/...works but/does not, the website repo likely never built — see deploying-to-remote-clouds / pushing-taubyte-projects (tau push website …,AssetCidcheck). This is not resolved by editingindex.htmlalone without a website job. - Corrupted
build.sh(shell mixed with HTML). A bad edit can mergeindex.html(or other markup) into.taubyte/build.sh, which then fails to parse as shell. Fix: remove the broken file and recreate a minimal script — for a single static page,mkdir -p /outthencp index.html /out/, thenchmod +x .taubyte/build.sh. Validate withbash -n .taubyte/build.shbefore push.
Related skills
creating-taubyte-resources—tau new websiteflag patternspushing-taubyte-projects—tau push websitetriggering-dream-builds—dream inject push-specificfor the website repoverifying-taubyte-functions— also covers gateway curl withHost:header
More from taubyte/skills
verifying-taubyte-functions
Verifies a Taubyte Go function locally via the `taubyte/go-wasi` Docker recipe (preferred over `tau build`, with tmpfs+bind-mount-ro to avoid root-owned artifacts in the source tree), and verifies a function actually serves on Dream by curling the gateway with the right `Host:` header (plus `/etc/hosts` mapping for `*.localtau`). Use when locally compiling a Go function to WASM, when smoke-testing a function before pushing, or when probing a Dream-hosted HTTP function from the laptop.
12creating-taubyte-resources
Creates Taubyte resources non-interactively via `tau new` for domain, website, library, function, application, database, storage, messaging, and service. Encodes the project-vs-application scope rule, the database `min < max` constraint, the website/library `--generate-repository` + import sequence, and the forbidden `--generated-fqdn-prefix` flag. Use when adding any resource to a Taubyte project's config repo.
12diagnosing-dream-builds
Diagnoses Dream local-cloud builds when `tau list/query builds` is empty or unreliable, by hitting the jobs HTTP endpoint directly (`GET /jobs/<project_id>`, `GET /job/<job_id>`) using the GitHub token from `~/tau.yaml`, then downloading logs with `tau query logs --jid`. Use when Dream builds appear silent, the build table is empty after `dream inject`, or you need raw job ids and logs for a failing build.
11taubyte-resource-creation
Scope-aware resource creation workflow. Uses non-interactive mode by default and references the shared flags catalog.
11taubyte-push-build-verify
Pushes config/code and verifies builds/logs. Includes website/library push handling with tau command first, git fallback.
11taubyte-scope-routing
Routes project-level vs application-scoped work; defaults to a website when a browser UI is logically appropriate; avoids unnecessary applications for simple website/function-only tasks unless needed.
11