# Bring a database

> Two variables move accounts, invites, settings, drafts, snapshots and sessions into Turso/libSQL — and make the container disposable. Entirely optional.

Source: https://editor.astrocraftthemes.com/docs/database/

Everything else in these docs is the default, and nothing on this page changes it. **If you never set these two variables, the store is the `.accounts/` directory and you can skip this page entirely.**

## What it moves

Set them and the same store — accounts, invites, settings, drafts, snapshots, and Astro's own sessions — moves into [Turso/libSQL](https://turso.tech) instead.

| Variable              | What it is                                                                                            |
| :-------------------- | :---------------------------------------------------------------------------------------------------- |
| `ASTROCRAFT_DB_URL`   | a libSQL URL: `libsql://<db>-<org>.turso.io` hosted, or `file:/data/state.db` for a local SQLite file |
| `ASTROCRAFT_DB_TOKEN` | the database auth token. Hosted Turso needs it; a `file:` URL does not                                |

Three commands to have one:

```bash
turso db create astrocraft
turso db show astrocraft --url          # → ASTROCRAFT_DB_URL
turso db tokens create astrocraft       # → ASTROCRAFT_DB_TOKEN
```

Nothing to migrate and no schema to apply — the table is created on first use.

## Put them in the environment, not in `.env`

These two are read from `process.env`, by `astro.config.mjs` when it loads and by [the accounts CLI](/docs/first-account/) under plain Node. **A `.env` file reaches neither** — Vite loads it into `import.meta.env`, which is where the Resend pair is read from and nowhere these are.

Verified by putting the URL in a `.env` and rebuilding: sessions stayed on the filesystem and the CLI wrote to `.accounts/`. A `.env` line would look like it worked and silently leave you on files.

Export them in the shell, or use your host's environment UI.

## Try it before an account is anywhere near it

```bash
ASTROCRAFT_DB_URL=file:/tmp/astrocraft.db \
  node --experimental-strip-types src/admin/js/accounts.cli.ts you@example.com "Your Name"
```

It prints where the record went, and it is not `.accounts/`.

## There is no third state

Unset means the directory. Set means the database. Nothing detects, guesses or falls back.

A URL that cannot be reached or authenticated **fails the first store touch** with a sentence naming the variable, and deliberately does not revert to files. That is not strictness for its own sake: a deployment running against an empty store looks exactly like a fresh install, and a fresh install re-opens [first-admin sign-up](/docs/first-account/) to whoever loads the page first.

An empty value counts as unset, and exactly one function owns both the read and that rule — so the store and the sessions can never disagree about whether there is a database.

A URL that does not even parse is reported as _an unparseable URL_ and never echoed back to the screen.

## What it actually buys

With the store in your database, the container's volume holds only the checkout — which the entrypoint re-clones anyway. **The machine becomes disposable:** rebuild it, move it, run it somewhere else, and the accounts, the settings and everybody's login survive. A redeploy no longer logs anybody out, and losing the volume costs you a clone rather than your accounts.

That is the whole of it, and it is why this is one variable rather than a feature.

## Any other backing store

The accounts store is an [unstorage](https://unstorage.unjs.io) namespace, so the same drivers Astro already uses for sessions — Cloudflare KV, Vercel KV, Netlify Blobs, Redis, S3 — drop in with one line in `src/admin/js/accounts.ts`. The database path above is the one that needs no line at all.

## Troubleshooting

**Set the variables and nothing changed.** They are in a `.env` file. See above.

**The CMS throws on first load naming both variables.** The URL is unreachable or the token is wrong. It will not fall back, on purpose.

**Sessions still reset on redeploy although accounts survive.** The session driver is wired in your `astro.config.mjs` rather than by the integration — adapters claim that slot in their own setup hook and run first, so it has to be host config. Check the session line is present.

**Everything works locally with a `file:` URL but not hosted.** Hosted Turso needs `ASTROCRAFT_DB_TOKEN`; a `file:` URL does not, so this is the variable that goes missing.