Run Weldall and the discovery proxy from the published Docker Hub images, and upgrade them safely.
Weldall is published as two independent Docker images. Most installations run only the Weldall image next to a PostgreSQL database. The discovery proxy is an optional second container for resource servers that cannot reach Weldall directly.
| Image | Contains | Needed by |
|---|---|---|
docker.io/seibertgroup/weldall |
The Weldall server: authorization server, administration interface, installer. | Every installation. |
docker.io/seibertgroup/weldall-discovery-proxy |
An unprivileged Nginx that forwards only the Weldall metadata and JWKS. | Only resource servers that cannot reach Weldall directly, see Discovery proxy. |
Both images are built for linux/amd64, run as non-root users, and have their own version numbers. A proxy release never changes the Weldall image, and vice versa.
Tags and versions
Section titled “Tags and versions”Each release publishes these tags:
| Tag | Points to |
|---|---|
X.Y.Z, e.g. 0.1.1 |
Exactly this release. Never moved. |
X.Y, e.g. 0.1 |
The newest patch release of this line. |
X, e.g. 0 |
The newest release of this major version, so every release that is not a major bump. |
latest |
The newest release overall. |
| Git commit SHA | The image built from this commit. Moves only when a failed release is published again. |
Pin a full X.Y.Z tag in production. X.Y, X and latest move with every release, so a plain container restart can start a newer version and run its database migrations. Before version 1.0, 0 is no safer than latest: a minor release may contain breaking changes.
The published tags are listed on Docker Hub: seibertgroup/weldall and seibertgroup/weldall-discovery-proxy.
Release notes are on the GitHub releases page under the tags @weldall/weldall@X.Y.Z and @weldall/discovery-proxy@X.Y.Z. Not every release listed there has an image; only the tags on Docker Hub can be run.
Weldall container
Section titled “Weldall container”Requirements
Section titled “Requirements”- PostgreSQL 16. Weldall stores its configuration, audit records and replay markers there. The image contains no database; you operate PostgreSQL yourself or use a managed service. Releases are tested against PostgreSQL 16.
- A database user that owns the Weldall database. The container applies migrations with this user on every start, see Start-up. A user with only read and write rights fails on the first start.
- A public HTTPS URL, set as
WELDALL_ISSUER. Terminate TLS in front of the container; the container itself listens on plain HTTP on port 3000. - The configuration from How to: Set up Weldall. The container refuses to start if a required variable is missing and names the variable in its log.
Generate the secrets
Section titled “Generate the secrets”The secrets only need Node.js. Without a repository checkout, run the generator in a Node container:
docker run --rm node:24-slim node -e 'const { generateKeyPairSync, randomBytes, randomUUID } = require("node:crypto");const { privateKey, publicKey } = generateKeyPairSync("ec", { namedCurve: "P-256" });console.log(`BETTER_AUTH_SECRET=${randomBytes(32).toString("base64url")}`);console.log(`WELDALL_SETUP_TOKEN=${randomBytes(32).toString("base64url")}`);console.log(`WELDALL_CREDENTIAL_ENCRYPTION_KEY=${randomBytes(32).toString("base64")}`);console.log(`WELDALL_CONNECTOR_KEK=${randomBytes(32).toString("base64")}`);console.log(`WELDALL_SIGNING_PRIVATE_JWK=${JSON.stringify(privateKey.export({ format: "jwk" }))}`);console.log(`WELDALL_SIGNING_PUBLIC_JWK=${JSON.stringify(publicKey.export({ format: "jwk" }))}`);console.log(`WELDALL_SIGNING_KID=${randomUUID()}`);'Store the output in your secret manager. Generate the values once and never replace them while the installation exists: a new signing key invalidates issued identity assertions, and a new encryption key makes the stored provider credentials unreadable. WELDALL_CONNECTOR_KEK is not checked at start-up: without it the server runs, but creating a connector fails.
docker run -d --name weldall \ -p 3000:3000 \ --env-file weldall.env \ docker.io/seibertgroup/weldall:X.Y.Zweldall.env holds POSTGRES_URL, WELDALL_ISSUER and the generated secrets. Run exactly one Weldall container, see Why exactly one Weldall container.
Start-up: migrations and initialization
Section titled “Start-up: migrations and initialization”Every start runs three steps in this order:
prisma migrate deployapplies all database migrations the database does not have yet. A fresh database receives all of them, an upgrade only the new ones. Prisma records applied migrations in the table_prisma_migrations.- Deployment initialization creates the required default records and refreshes the published skill catalogs.
- The server starts and answers on port 3000.
If step 1 or 2 fails, the container exits with a non-zero code and the server does not start. Typical causes are an unreachable database (Prisma error P1001), a user without schema permissions, or a database that already contains conflicting tables (P3005, P3018). The log names the failing migration. Fix the cause and start the container again; Prisma continues with the migrations that are still missing.
One case needs an extra step: after a migration failed while it was being applied (P3018), every later start stops with P3009, even when the cause is fixed. Mark the failed migration as rolled back with the Prisma CLI in the image, then start the container again:
docker run --rm --env-file weldall.env \ --entrypoint /app/packages/db/node_modules/.bin/prisma \ docker.io/seibertgroup/weldall:X.Y.Z \ migrate resolve --rolled-back MIGRATION_NAME \ --schema /app/packages/db/prisma/schema.prismaMIGRATION_NAME is the migration the log names.
Health check
Section titled “Health check”The image declares a Docker HEALTHCHECK on GET /.well-known/openid-configuration. The first start runs all migrations and can take longer than later starts; the check allows 30 seconds before it counts failures.
If your platform uses its own probes instead, point them at the same path and the container port, 3000 by default. The port opens only after the migrations, so give the startup probe enough time for an upgrade.
Upgrades and rollbacks
Section titled “Upgrades and rollbacks”An upgrade can change the database schema. Before every upgrade:
- Take a database backup. Do it directly before the upgrade; everything written after the backup is lost if you restore it.
- Change the image tag to the new
X.Y.Zand restart the container. The new version applies its migrations on start. - Check the log for
All migrations have been successfully applied.orNo pending migrations to apply., followed by the server start.
Upgrade the discovery proxy independently. It stores nothing, so you can switch its version back and forth without further steps.
Why exactly one Weldall container
Section titled “Why exactly one Weldall container”Part of the replay protection is kept in the memory of the Weldall process: DPoP proofs sent to the OAuth token and userinfo endpoints during CLI login and token refresh are remembered only there. A second Weldall container would not see the proofs the first one accepted, so a captured proof could be reused against the other container for the 60 seconds it stays valid. The proof alone does not yield a token, because authorization codes and refresh tokens are single-use in the database, but the protection is weaker than with one container.
Run exactly one Weldall container. Weldall does not enforce this itself. The consequences:
- While the container restarts, for example during an upgrade, Weldall is unavailable. Employees see failed logins, and resource servers cannot fetch new keys until the container is back.
- Platforms that start the new version before stopping the old one run two processes for a short time. The window is limited to the switch-over.
- High availability with several Weldall containers is not supported.
The discovery proxy keeps no state. Scale it as needed.
Discovery proxy container
Section titled “Discovery proxy container”docker run -d --name weldall-discovery-proxy \ -p 8080:8080 \ -e WELDALL_UPSTREAM=https://weldall.example.com \ docker.io/seibertgroup/weldall-discovery-proxy:X.Y.ZWELDALL_UPSTREAMis the public HTTPS URL of Weldall, without path, query or credentials. With a missing or invalid value, the container exits on start and names the variable.- The proxy listens on plain HTTP on port 8080. Terminate TLS in front of it; resource servers must reach it over HTTPS.
- It verifies the TLS certificate of
WELDALL_UPSTREAMagainst the public CA bundle of the image. - Only
GET /.well-known/oauth-authorization-serverandGET /api/oauth/jwksare forwarded, unchanged. Every other path answers404, other methods405. - It has no health endpoint of its own. Use a TCP check on port 8080; an HTTP check on a forwarded path would also fail whenever Weldall is down.
Next steps
Section titled “Next steps”- How to: Run the installer connects your identity provider after the first start.
