No description
  • TypeScript 92.1%
  • Nix 6.5%
  • Dockerfile 1.4%
Find a file
2026-03-09 00:33:01 +02:00
test-app fix: bun build and dockerfile 2026-03-09 00:26:07 +02:00
.envrc Initial commit 2026-03-08 20:21:02 +02:00
.gitignore Initial commit 2026-03-08 20:21:02 +02:00
devenv.lock Initial commit 2026-03-08 20:21:02 +02:00
devenv.nix Initial commit 2026-03-08 20:21:02 +02:00
devenv.yaml Initial commit 2026-03-08 20:21:02 +02:00
README.md chore: readme 2026-03-09 00:33:01 +02:00

Spacetime TanStack start docker compose

This is for TanStack spacetime application,

Note

Please read everything carefully before continuing the deployment
To avoid data loss.

everything from the beginning

Install spacetimedb cli tool and add it to your path https://spacetimedb.com/install

curl -sSf https://install.spacetimedb.com | sh
# .bashrc
export PATH="~/.local/bin:$PATH"
spacetime init --template tanstack-ts --local
# SKIP SPACETIME LOGIN (N)
# Select bun as package manager
cd your-project
bun install
# generate typescript bindings
spacetime generate --lang typescript --out-dir src/module_bindings --module-path spacetimedb

Copy the docker-compose files and Dockerfile to the project src folder

Update your database name and address in .env.local

Setting up authentication keys

Start with making a spacetime-config.toml file

mkdir -p ./spacetime-config
nvim spacetime-config/config.toml

With the following contents

[certificate-authority]
jwt-priv-key-path = "/etc/spacetimedb/id_ecdsa"
jwt-pub-key-path = "/etc/spacetimedb/id_ecdsa.pub"

Generating keys

For dev

cd test-app
mkdir -p ./spacetime-keys
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ./spacetime-keys/id_ecdsa
openssl pkey -in ./spacetime-keys/id_ecdsa -pubout -out ./spacetime-keys/id_ecdsa.pub
echo "spacetime-keys/" >> .gitignore

Now the keys persist and you dont to generate new keys after every docker restart

For prod

mkdir -p ./spacetime-keys-prod
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ./spacetime-keys-prod/id_ecdsa
openssl pkey -in ./spacetime-keys-prod/id_ecdsa -pubout -out ./spacetime-keys-prod/id_ecdsa.pub
echo "spacetime-keys-prod/" >> .gitignore

For more control on who can do what with the database, consider using SpacetimeAuth

Dev setup

Clear your web browser localstorage

localStorage.clear();

Start everything up

cd test-app
bun install
# generate typescript bindings
spacetime generate --lang typescript --out-dir src/module_bindings --module-path spacetimedb
# Start spacetimedb as a docker container
docker compose -f docker-compose.dev.yml up -d --build

spacetime logout
spacetime server add local-docker --url http://localhost:3000
spacetime login --server-issued-login http://localhost:3000

spacetime publish -s local-docker

bun run dev
# TanStack dev using bun development server for frontend

server is up in http://localhost:5173

TanStack changes hot-reload automatically. Module changes require republishing.

incase you need to relogin

spacetime logout
spacetime login --server-issued-login http://localhost:3000

spacetime publish -s local-docker

After any spacedb module changes

spacetime generate --lang typescript --out-dir src/module_bindings --module-path spacetimedb
spacetime publish -s local-docker

Prod setup

Change build configs for bun to use nitro/vite

// vite.config.ts
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tsConfigPaths from "vite-tsconfig-paths";
import { nitro } from "nitro/vite";

export default defineConfig({
  server: {
    port: 5173,
  },
  plugins: [
    tsConfigPaths({
      projects: ["./tsconfig.json"],
    }),
    tanstackStart(),
    nitro({ preset: "bun" }),
    react(),
  ],
});
bun install
# generate typescript bindings
spacetime generate --lang typescript --out-dir src/module_bindings --module-path spacetimedb
docker compose -f docker-compose.yml up -d --build
spacetime server add production --url https://your-database-domain.com
spacetime login --server-issued-login https://your-database-domain.com
spacetime publish -s production
# Code change to TanStack
docker compose -f docker-compose.prod.yml up -d --build

# Code change to SpacetimeDB module
spacetime generate --lang typescript --out-dir src/module_bindings --module-path spacetimedb
spacetime publish -s production

# Update SpacetimeDB itself
docker compose pull spacetimedb && docker compose -f docker-compose.prod.yml up -d spacetimedb

For prod you can change key management for something more robust, like external secret management tools or environment variables, up to you

Prod addresses

# .env.local

# Generic / backend
SPACETIMEDB_DB_NAME=test-app-1tw1t
SPACETIMEDB_HOST=ws://localhost:3000
# Spacetimedb_host should be your spacetime docker container
# for example ws://spacetimedb:3000

# Vite
VITE_SPACETIMEDB_DB_NAME=test-app-1tw1t
VITE_SPACETIMEDB_HOST=ws://localhost:3000
# we use our spacetimedb domain 
# (separate api domain or sub-domain wss://spacetime.example.com for example)

Nginx proxy setup

first setup spacetime.example.com

spacetime.example.com
http tanstack:3000
websocket support
SSL on

Add custom nginx configuration to it

# Block publishes from outside of the machine
# Don't include this if you want to publish from outside
#----
location ~ ^/v1/publish {
    deny all;
    return 403;
}
#----

location /v1/ {
    proxy_pass http://spacetimedb:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
}

if you are running nginx in a docker container, add your spacetimedb and tanstack containers to the same network as nginx

docker network inspect nginx-proxy

then add in your docker-compose.prod.yml

  spacetimedb:
    # Remove ports if you route network with containers
    ...
    networks:
      - nginx-proxy

  tanstack:
    # Remove ports if you route network with containers
    ...
    networks:
      - nginx-proxy

networks:
  nginx-proxy:
    external: true

Clearing database

To clear database, you just need to use a docker compose command that removes volumes

docker compose down -v

Or if you prefer to clear without downtime

spacetime publish -s local-prod -c

Fixing spacetimedb openess

By default, spacetimedb is fairly open and the publishing is not being blocked from outside
to enable only ssh publishing, block /v1/publish with nginx

Heres recommended nginx setup from official self-hosted docs integrated to this setup

# Nginx custom config under spacetime.example.com
# Block publish
location ~ ^/v1/publish {
    deny all;
    return 403;
}

# Block SQL
location ~ ^/v1/database/[^/]+/sql$ {
    allow 127.0.0.1;
    deny all;
}

# WebSocket subscribe - required
location ~ ^/v1/database/[^/]+/subscribe$ {
    proxy_pass http://spacetimedb:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_set_header Host $host;
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
}

# Identity - required for TypeScript SDK
location /v1/identity {
    proxy_pass http://spacetimedb:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
}

and setup a local login from the server itself

spacetime server add local-prod --url http://127.0.0.1:3001 --no-fingerprint
spacetime login --server-issued-login http://127.0.0.1:3001
spacetime publish -s local-prod
# Code change to SpacetimeDB module
spacetime generate --lang typescript --out-dir src/module_bindings --module-path spacetimedb
spacetime publish -s local-prod

Note

If you do this after the setup, you need to wipe your database

docker compose -f docker-compose.yml down -v
docker compose -f docker-compose.yml up -d --build

spacetime login --server-issued-login http://127.0.0.1:3001
spacetime publish -s local-prod

Backing up owner identity

Everytime you relogin to the database, even in the same server your database is in, you generate new identity token for yourself. So if you logout from the owner identity YOU LOSE ACCESS TO THE DATABASE if you do logout, Use the backed up identity for the token.

Its important to backup the private/public keys AND your owner indentification. I suggest using something really secure, like encrypted secret manager or such.

cat spacetime-keys-prod/id_ecdsa
cat spacetime-keys-prod/id_ecdsa.pub

cat ~/.config/spacetime/cli.toml
# Grab the spacetimedb_token

Caution

This identity has owner access to your database keep It secure!

TanStack page routes

I have included a test.tsx in src/routes/test.tsx that shows an example of how to add a simple page to the app