Where does my data live?

In the infrastructure you point the container at. You supply the Postgres, the Redis and the bucket, and everything your agent reads or writes stays there.

The image boots on three values, and two of them are where your data goes. DATABASE_URL is the Postgres holding runs, sessions, secrets and your own tables. It must have the pgvector extension available, because the agent creates its own schema on first boot and one of those migrations needs it. WORKFLOW_REDIS_URL is the Redis backing the durable workflow engine. STACKBONE_SECRET_KEY is the key that encrypts every secret the runtime stores, so it is the one value that cannot live in the database it protects.

Files go to an S3-compatible bucket you configure through the STACKBONE_S3_* variables. Any provider works (AWS S3, Cloudflare R2, Azure Blob, Google Cloud Storage, Railway Buckets, MinIO). Create the bucket first: the agent never creates one. The runtime prefixes every key with the agent's identity, so two agents that pick the same logical bucket name never collide.

One variable controls the address form. STACKBONE_S3_FORCE_PATH_STYLE defaults to true, which puts the bucket in the path (https://host/bucket/key) and is what MinIO and Cloudflare R2 accept. Set it to false for a bucket that only answers to the subdomain form (https://bucket.host/key): AWS S3 and Railway Buckets are the common ones. The wrong value fails every call with NoSuchBucket or a 403 even though the credentials are right.

What Stackbone's control plane holds is the deployment record: which agent, its public address, its image tag, and its signing secret encrypted at rest. Studio and the CLI then talk to your box directly.

A deploy folder from stackbone package ships all three in its compose file so the whole thing starts with no accounts to create: a Postgres that already carries pgvector, a Redis, and a MinIO with a one-shot container beside it that creates the bucket. The agent waits for that container to succeed, so its first upload never lands on a bucket that does not exist yet. Point the same .env at managed services of your own when you want to run it that way.

The bundled MinIO publishes its port on the host, unlike the Postgres and the Redis. A presigned download link carries the endpoint it was signed with, so a link signed against the compose-internal address only resolves inside the compose network. That is why the port is published, and why .env mints a strong password for that service.

Read more

BUILT WITH ❤️ FROM CANADA AND SPAIN