Set up and update an existing installation.
For installations thinqOS has issued a token to. Self-hosting is available to existing installations by arrangement; it is not a general offer, and it is not part of the current offer for new customers. Your installation fetches signed releases from us and reports outward; we have no deploy access to your environment.
Before you start
Everything below runs on macOS or Linux. Check you have all five:
- A machine you control, with Docker and Docker Compose. Compose is the topology this installer ships; cloud targets are configured from the OpenTofu modules inside the release.
- curl, tar, jq, and shasum (or
sha256sum). All butjqship with macOS and every mainstream Linux;jqis onebrew install jqorapt install jqaway. The installer checks for all of them first and stops with a clear message if one is missing. - Outbound HTTPS to
github.comandghcr.io. The installer fetches its tools from the first and the release from the second, and verifies the release signature against Sigstore's public services. - Your install token. Every installation gets its own. It is the only credential involved, and it is what fetches releases.
- A name for this installation, such as Acme Production. This is required, shows up on the Admin Updates screen, and is capped at 120 characters with no
=or|.
Install
Set your token and installation name
Use environment variables rather than command-line arguments. Anything on a command line is visible in ps to every other user on the machine for as long as the install runs.
export THINQOS_INSTALL_TOKEN=your-token-here export THINQOS_INSTALL_NAME='Acme Production'
Run the installer
curl -fsSL https://thinqos.com/install.sh | bash
Prefer to read it first? For a security review you should, and the script is deliberately short enough to do that. Verify it against the published checksum, read it, then run it:
curl -fsSLO https://thinqos.com/install.sh curl -fsSL https://thinqos.com/install.sh.sha256 | shasum -a 256 -c - less install.sh bash install.sh
Just want to look? Add --dry-run. It fetches and verifies the release, tells you which version it resolved, and stops without writing anything.
Check what you got
The installer creates ./thinqos (change it with --dir) and prints each thing it verified as it goes: the tools it fetched, the version your channel resolved to, and signature verified. Inside you will find the release manifest and an unpacked compose/ directory holding the topology and a .env seeded from the template with your installation name already filled in.
Re-running is safe. If a compose/.env already exists, the installer leaves it exactly as it is rather than overwriting your configuration.
Configure and start it
The installer has already written thinqos/compose/.env for you, with your installation name and the exact release image pinned by digest. Fill in these values:
| Value | What it is |
|---|---|
POSTGRES_PASSWORD | Password for the bundled Postgres. Set it to something of your own. |
FERNET_KEY | The key that encrypts stored secrets. Generate one; the README gives the command. |
CLERK_ISSUERCLERK_SECRET_KEYCLERK_PUBLISHABLE_KEY | Your sign-in provider. Users authenticate against your instance, not ours. |
PUBLIC_APP_URL | The externally reachable origin for this installation. Defaults to http://localhost:8000; set it to your HTTPS origin behind a reverse proxy. The app derives its OAuth issuer and authorized-party boundary from this. |
Then start it:
cd thinqos/compose docker compose --env-file .env up -d
It comes up on http://localhost:8000. Email is wired to a bundled capture-only mailbox, so nothing leaves the host until you point it at a real relay, and Postgres and file storage are bundled too: there is no external database to provision for a single-machine install. Updating is the same command you started with.
Options
Everything above works with no flags at all. These are here when you need them:
| Flag | What it does |
|---|---|
--dry-run | Fetch and verify, report, and stop. Changes nothing on disk. |
--channel | stable (the default) is the tested release. canary gets changes sooner and is where problems surface first. |
--version | Pin to one exact release instead of following a channel. Versions look like 20260827.2309-c27a6aec0. Use this when you need the specific version you reviewed. |
--dir | Where to install. Defaults to ./thinqos. |
--name | The installation name, if you would rather pass it than export it. |
--token | For automation only, where the process table is not a concern. Prefer the environment variable everywhere else. |
--target | Which topology to unpack. compose is the default and the one this installer ships. |
bash install.sh --help # the full list, straight from the script
What the installer actually does
It is a trust-establishing script, and it earns the right to be piped into a shell by refusing anything it cannot prove. In order:
Fetches its own tools
Downloads the two utilities it needs and checks each against a fingerprint hard-coded in the script before running them. It will not use a copy already on your machine, because it cannot verify one, and a substituted verifier would defeat every other guarantee here.
Proves the release is ours
Checks the cryptographic signature before anything is unpacked. A release we did not sign is refused and nothing reaches your filesystem.
Downloads the software
Pulls the container images. You never receive our source code, and you do not need access to our code repository.
Hands you the controls
Unpacks the topology and stops. Every value that decides how your installation runs is one you supply, in a file on your machine.
Updating
Re-run the installer against the same directory. It fetches the newest release on your channel, verifies the signature exactly as it did the first time, and re-pins the image, leaving every value you set in .env untouched. Then recreate the stack.
export THINQOS_INSTALL_TOKEN=your-token-here export THINQOS_INSTALL_NAME='Acme Production' curl -fsSL https://thinqos.com/install.sh | bash -s -- --dir /path/to/thinqos cd /path/to/thinqos/compose && docker compose --env-file .env up -d
Cloud installs run this on a schedule instead, and every step is gated: the signature is verified, database changes run first, a new copy starts serving no traffic until it passes a health check, and only then does traffic move. If any step fails, the version you were already running keeps serving.
Inside thinqOS, under Admin, an Updates screen shows the version you are on, every update your install has attempted and what came of it, and three settings you control: whether updates install automatically, which lane you follow, and an optional window of hours during which updates may land. Turn automatic updates off and nothing installs until you turn them back on.
The same token installs and updates. Keep it. If it is ever revoked, your running install is untouched and keeps working; what stops is new releases arriving.
What your install reports back
In exchange for updates, your install reports a small, fixed set of facts about itself: which version it is on, whether its last few updates succeeded, whether its database is healthy, how fresh its reference data is, where it is deployed, and roughly how many seats it has, in broad bands.
It never sends your content. No messages, no prompts, no documents, no file names, and nothing identifying your users. You can see the exact payload on the Updates screen every time it is sent.
When something goes wrong
the registry refused that token
The token is wrong, has been revoked, or belongs to a different install. Each installation has its own and they are not interchangeable. Never share one or bake one into an image: a shared token cannot be revoked for one customer without breaking the rest.
SIGNATURE CHECK FAILED
Stop. This means the release was not signed by us. Nothing has been installed and nothing was written to disk. Tell us before trying again.
CHECKSUM MISMATCH
A tool the installer downloaded is not the one it expects, so it refuses to run it. Usually a corrupted or intercepted download. Retry once, and tell us if it persists.
no release for channel '...'
The lane you asked for has no published release, or your token cannot read it. Check the spelling: the only channels are stable and canary. For an exact release, use --version instead.
no installation name
The name is required. Export THINQOS_INSTALL_NAME or pass --name. It must contain a visible character, stay under 120 characters, and contain no = or |.
missing required command
One of curl, tar, jq, or shasum is not on this machine. The message names which. Nothing has been downloaded at that point.
New to thinqOS?
Self-hosting is by arrangement for existing installations. The hosted service is in private preview, with access by request.