docs
GitHubNL
Getting started

Quickstart

Run Appsweet on your own infrastructure in about five minutes.

Appsweet ships as a single container. Point it at a Postgres database and an OIDC issuer and you have the workspace running on hardware you control.

What it needs first

Two things, both required while the process is still booting:

  • Postgres with the vector extension available. Appsweet has no embedded database, and its first migration runs CREATE EXTENSION IF NOT EXISTS vector. The stock postgres image does not carry it; pgvector/pgvector:pg16 does.
  • A Zitadel instance. APPSWEET_OIDC_ISSUER and APPSWEET_OIDC_CLIENT_ID are read during startup, not on the first sign-in. Without them the container exits before it binds a port, so /ready never answers at all. Zitadel is the only provider that works: the backend requests a Zitadel-specific scope and reads Zitadel's organisation claims to resolve a workspace, so another OIDC provider signs the user in and then fails on /v1/me. Docker Compose has the details.

If you have Postgres but no issuer, Docker Compose explains what to point Appsweet at and what the repository's own stack bundles for you — its two-service example brings up Appsweet and Postgres, but no identity provider, so read that page before assuming it is a complete deployment.

Run it

With a database and an issuer in hand, the container on its own is one command.

terminal
# exact version + digest from the release manifest — there is no :latest tag
docker run -p 3000:3000 \
  --add-host host.docker.internal=host-gateway \
  -e APPSWEET_DATABASE_URL=postgres://appsweet:secret@host.docker.internal:5432/appsweet \
  -e APPSWEET_BIND_ADDR=0.0.0.0:3000 \
  -e APPSWEET_PUBLIC_BASE_URL=http://localhost:3000 \
  -e APPSWEET_OIDC_ISSUER=https://auth.example.com \
  -e APPSWEET_OIDC_CLIENT_ID=your-client-id \
  ghcr.io/blendable-dev/appsweet-backend:0.1.0-beta.1@sha256:<digest-from-the-release-manifest>

Images are selected by exact version plus digest, taken from the validated release manifest for that version. There is no latest tag, and no mutable tag is accepted as the source of truth — substitute the version and digest for the release you are deploying.

NOTE

The appsweet-backend package is private for the duration of the controlled beta. Pulling it needs a registry credential scoped to read packages — until your Docker daemon is logged in to ghcr.io with one, the pull fails as if the image did not exist.

APPSWEET_BIND_ADDR matters: the default is 127.0.0.1:3000, which inside a container means the port mapping reaches nothing.

--add-host host.docker.internal=host-gateway is what makes that database address resolve. The host.docker.internal alias is supplied automatically by Docker Desktop on macOS and Windows, but not by Docker Engine on Linux — which is where most self-hosted installs run. Without the flag the name does not resolve there, the connection fails while the process is still booting, and the container exits. The flag is harmless on Docker Desktop, so the command above is the same everywhere. If your Postgres is somewhere other than the Docker host — a managed service, another machine — use its real hostname and drop the flag.

NOTE

That address also assumes Postgres is listening on an interface the container can reach, not only on localhost. A distribution default of listen_addresses = 'localhost' refuses the connection even once the name resolves.

Check it came up

Appsweet applies its migrations on boot, then reports readiness once the database pool is attached.

terminal
curl http://localhost:3000/ready

Next steps

TIP

The command above leaves out object storage, so file uploads are disabled — fine while you are trying Appsweet out, not something to deploy. The repository's bundled stack wires storage up for you; Configuration lists the variables if you are assembling it yourself.

Back to appsweet.appEdit this page on GitHub