Self-hosting
vauly runs on your own Cloudflare account. A deploy creates two things:
- vauly, a Worker that serves the web app and its API
- vauly, a D1 database for your items, encrypted before they arrive
A small team fits in Cloudflare’s free plan.
Deploy with one click
Section titled “Deploy with one click”- Click the button, sign in to Cloudflare, and connect GitHub or GitLab. Cloudflare copies vauly into a new repository of yours and builds it from there.
- When it asks for
SETUP_CODE, choose a code only you know, for example fromopenssl rand -hex 16. It keeps a fresh vauly from being claimed by whoever finds it first. - Deploy. When it’s done, open your vauly’s address followed by
/setup?code=and your code, and create the workspace. You become its owner. Invite your team from Members; each invite link works once, for one email address.
That’s all the setup there is. The Worker applies the database migrations on its first request, and makes the secret that signs sessions on first start, keeping it in the database. Without a SETUP_CODE, whoever opens your vauly first creates the workspace, so don’t leave such a deploy unclaimed.
Updating
Section titled “Updating”In your copy of vauly on GitHub, open Actions → Update vauly → Run workflow. It replaces the files with the latest vauly and pushes, and Cloudflare deploys the update. The Worker applies any new migrations on its first request. Check CHANGELOG.md before you update.
The update keeps your wrangler.jsonc, which names your Worker and its database, and the files in .github/workflows, which GitHub’s default token can’t change. To let updates replace the workflows too, add a repository secret named VAULY_UPDATE_TOKEN: a fine-grained token for that repository with read and write access to Contents and Workflows.
Deploy from your machine
Section titled “Deploy from your machine”You need Bun 1.3 or later.
git clone https://github.com/jotyy/vauly.gitcd vaulybun installbunx wrangler loginecho "SETUP_CODE=$(openssl rand -hex 16)" > .dev.varsbun run buildbun run deploy -- --secrets-file .dev.vars.dev.vars keeps your setup code; git ignores it. Wrangler prints your vauly’s address, and you claim it the same way, at /setup?code= followed by the code.
To update, run git pull, bun install, bun run build and bun run deploy.
Your own domain
Section titled “Your own domain”In the Cloudflare dashboard, open the vauly Worker, then Settings → Domains & Routes → Add → Custom domain. The app and the API move together, so there’s nothing else to change. The domain’s DNS has to be on Cloudflare.
Settings
Section titled “Settings”| Setting | What it does |
|---|---|
SETUP_CODE |
Secret. Creating the workspace takes this code until someone has. It no longer matters once the workspace has an owner. |
BETTER_AUTH_SECRET |
Secret, optional. Signs sessions. Without it, vauly makes one and keeps it in the database. Changing it signs everyone out. |
VITE_BRANDFETCH_CLIENT_ID |
Build variable, optional: for a one-click deploy, under the Worker’s Settings → Build → Variables and secrets. Where website logos come from: by default the web app and the extension load them from Brandfetch with the vauly project’s client ID. Use your own Brandfetch client ID, or off to show plain icons and never contact Brandfetch. |
Add secrets in the dashboard under the Worker’s Settings → Variables and Secrets, or with bunx wrangler secret put.
Backups
Section titled “Backups”- The database. D1 keeps a point-in-time history you can restore from (Cloudflare calls it Time Travel; how far back depends on your plan). Everything sensitive in it is encrypted, so a database copy is only useful together with your team’s master passwords.
- Decrypted backups. Any member can download every item they can open from Settings → Download a backup. The file is plain text: store it encrypted.
Removing an instance
Section titled “Removing an instance”Delete the vauly Worker and the vauly D1 database in the Cloudflare dashboard, or run bunx wrangler delete and bunx wrangler d1 delete vauly. Deleting the database deletes every item in it, so download backups first.
If the owner is locked out of two-step login
Section titled “If the owner is locked out of two-step login”An admin can reset two-step login for anyone except the owner. If the owner loses both their phone and their recovery codes, open the instance’s D1 database in the Cloudflare dashboard and run this in its console, with the owner’s email:
UPDATE member SET totp_secret = NULL, totp_pending = NULL, totp_step = NULL, recovery_codes = NULLWHERE user_id = (SELECT id FROM user WHERE email = 'owner@example.com');Their master password alone signs them in again. It changes nothing about encryption: the master password is still the only key to their items.
Deploying with Alchemy
Section titled “Deploying with Alchemy”The repository’s development stack uses Alchemy (packages/infra/alchemy.run.ts), which can also deploy, as two Workers: one for the web app and one for the API. bun run deploy:stack -- --stage production does that. It needs BETTER_AUTH_SECRET, and CORS_ORIGIN set to the web app’s address; the one-Worker deploy above needs neither and is the simpler choice.
Good to know
Section titled “Good to know”- The test suite’s stacks add a route that wipes the database, guarded by
E2E_RESET_TOKEN. It only exists when that variable is set; never set it for a real deploy. bun run devkeeps its state on disk and never touches your Cloudflare account.