creating-taubyte-resources
Creating Taubyte Resources
When to use
- "Add a domain / website / library / function / database / storage / messaging / service"
- "Create an application for app-scoped resources"
- Building out a project after
bootstrapping-taubyte-projects - Reviewing or scripting non-interactive resource creation
Intent-first resource planning (agent behavior)
When a user asks to "create an app" (not just a resource), first infer the minimum Taubyte resource set required to make that app real, then create those resources with correct scope + wiring.
General heuristics:
- Web app UI → create a website (project-scoped if needed or mentioned) + a domain (project-scoped if mentioned) and attach the site to the domain and path(s).
- Persistent data → create a database (application-scoped if needed). create storage if needed ; choose only when implied by the intent.
- UI ↔ data/API glue → create at least one HTTP function that reads/writes the database and returns JSON for the website to consume. Attach the function to the same domain when a same-origin
/api/...pattern is implied.
Rules while doing this:
- Prefer the fewest resources that satisfy the intent, but do not omit the glue (e.g. database without a function is usually not an "app").
- Keep scopes correct: database/storage/messaging/service are application-scoped if needed or mentioned; website/domain are project-scoped if needed or mentioned.
- Use match strings as stable wiring keys (database
match, messaging channel, service protocol) and keep them consistent with Go calls and triggers (see enforcing-taubyte-constraints rule 16).
Preconditions
tau --defaults --yes json currentshows the correct Project (and the right Application, or none, depending on scope) — see selecting-taubyte-context.- Project has been created/imported — see bootstrapping-taubyte-projects.
Scope rule (project vs application)
| Resource | Scope |
|---|---|
domain |
Project |
website |
Project |
library |
Project |
function (HTTP) |
Project (default) or Application |
application |
Project (creates the application) |
database |
Application |
storage |
Application |
messaging |
Application |
service |
Application |
For app-scoped resources: tau --defaults --yes select application --name <app> first; for project-scoped, ensure no application is selected (tau --defaults --yes clear application).
Domains
Generated FQDN (Dream / quick demos)
tau --defaults --yes new domain <domain_name> \
--generated-fqdn \
--type auto \
--description "<desc>"
Result: a random FQDN of the form <random>.<universe>.localtau.
Custom FQDN (remote, controlled hostname)
tau --defaults --yes new domain <domain_name> \
--fqdn <fqdn> \
--type auto \
--description "<desc>"
Some remotes: *.gen.<cloud_fqdn> and the project CID suffix
Host policy can require that a generated-style hostname under *.gen.<cloud> embed the last eight characters of the project’s canonical CID from tau query project <name> --json → id. Compute: python3 -c "s='<cid>'; print(s[-8:])". Omitting this substring breaks config-compile with errors like does not contain last 8 of project id. When replacing a domain for this reason, reuse the same logical domain resource name (e.g. generated) if you can — so domains: on websites/functions stay valid without mass YAML edits.
Forbidden flag
Never pass --generated-fqdn-prefix (or --g-prefix) — it's not supported by policy. Use --generated-fqdn alone or use --fqdn with a controlled hostname.
Websites
tau --defaults --yes new website <site_name> \
--domains <domain_name> \
--paths / \
--template empty \
--generate-repository \
--repository-name tb_code_<project>_<site_name> \
--private \
--no-embed-token \
--branch main
tau --defaults --yes import website <site_name>
tau --defaults --yes list websites
Notes:
--generate-repositorycreates a separate GitHub repo for the website; pair with a deterministic--repository-name(recommended:tb_code_<project>_<site>).- After creation, run
import websiteso the local clone appears under<project>/websites/<repo>/. - Author build content under
.taubyte/build.shwriting to/out— see building-taubyte-websites.
To attach an existing website repo instead of generating one, use --repository-name <fullname> or --repository-id <id> and drop --generate-repository.
Libraries
tau --defaults --yes new library <lib_name> \
--path /libraries/<lib_name> \
--template empty \
--generate-repository \
--repository-name tb_code_<project>_<lib_name> \
--private \
--no-embed-token \
--branch main
tau --defaults --yes import library <lib_name>
tau --defaults --yes list libraries
--path is the path inside the library repo where sources live; it must match the actual layout in the cloned repo.
HTTP functions
tau --defaults --yes new function <fn_name> \
--type http \
--method GET \
--paths /<path> \
--domains <domain_name> \
--language Go \
--source . \
--memory 64MB \
--timeout 30s \
--call <ExportedHandler> \
--template empty
Or use a known-good ping_pong template:
tau --defaults --yes new function ping \
--type http --method GET --paths /ping \
--generate-domain \
--language Go --source . \
--memory 64MB --timeout 1s \
--call ping \
--template ping_pong --use-template
Function rules:
- One function per (path, method) — never comma-separated methods.
--callmust equal a//export <name>symbol in the source.- For Go, edit the function root
empty.go(next togo.mod) — never create alib/tree or hand-authormain.go.
Applications
tau --defaults --yes new application <app_name> \
--description "<desc>"
tau --defaults --yes select application --name <app_name>
tau --defaults --yes list applications
Databases (application-scoped)
tau --defaults --yes new database <db_name> \
--match <matcher> \
--min 1 --max 2 \
--size 1GB
Constraint observed: --min 1 --max 1 fails with min(1) cannot be greater than max(1). Use --min 1 --max 2 (or higher max).
The --match value is the runtime key: Go code must call database.New("<matcher>") with the identical string (including any leading /).
Storage (application-scoped)
tau --defaults --yes new storage <storage_name> \
--match <matcher> \
--size 1GB \
--bucket Object \
--public
Messaging (application-scoped)
tau --defaults --yes new messaging <msg_name> \
--match <channel_match> \
--mqtt --ws
The <channel_match> is the channel string. Producers in Go call pubsub/node's Channel("<channel_match>"), and PubSub-triggered functions set trigger.channel: <channel_match>.
Services (application-scoped)
tau --defaults --yes new service <svc_name> \
--protocol /api
On Git Bash / MSYS, prefix path-like flags with MSYS_NO_PATHCONV=1 to avoid path mangling.
Workflow checklist for a typical project
Resource creation progress:
- [ ] Verify selection (tau --json current)
- [ ] Create domain (project scope)
- [ ] Create website + import (project scope)
- [ ] Create library + import (project scope)
- [ ] Create application
- [ ] Select application
- [ ] Create database / storage / messaging / service
- [ ] Create functions (HTTP at project scope, others at app scope as needed)
- [ ] tau clear application
- [ ] tau push project --config-only --message "..."
- [ ] Wait for config build success before pushing website/library code
Gotchas
- Dream vs CLI vs remote WASM paths:
tau new function ... --source .with an application selected may scaffold undercode/applications/<app>/functions/<fn>/in your clone, while Dream or remote builders often expectcode/<app>/functions/<fn>/(noapplications/segment). A remote job may fail with couldn't find.taubyteunder.../<app>/functions/<fn>while your tree still has.../applications/<app>/functions/<fn>. Treat the path in the first failing build log as ground truth and move the function directory (and fix any relative references) so.taubyte/sits where the builder looks — do not guess a different layout. - Application bleed: forgetting
tau clear applicationcauses latertau new domain|website|libraryto land in the app instead of project scope. - Matcher = runtime string:
matchin YAML must equal the literal Go calls (database.New("..."),pubsubnode.Channel("..."),trigger.channel). Mismatched leading/is a frequent cause of "open failed" / silent producers. - Repo strategy must be explicit for websites/libraries — either
--generate-repositorywith a deterministic--repository-name, or--repository-name/--repository-idfor an existing repo. - Don't hand-edit domain YAML. Always use
tau new domain/tau delete domain/tau query domain. - Min/max on database:
--minmust be strictly less than--max.
Related skills
bootstrapping-taubyte-projectsselecting-taubyte-contextpushing-taubyte-projectsbuilding-taubyte-websitesverifying-taubyte-functions
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.
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.
11understanding-taubyte-architecture
Explains the Taubyte mental model — `tau` CLI vs `dream` local cloud, remote-vs-local cloud types, GitHub as the single source of truth, and the config/code/website/library repo layout that drives builds. Use when the user asks how Taubyte fits together, why pushes don't show up, what repos are needed, or whether to use Dream or a remote cloud.
11