The server is the product: a free, self-hosted engine that runs every recipe, holds your warehouse and credentials, and writes the audit record. It can run on a laptop, home server, supported single-board computer, or small VPS. For scheduled and reactive work, choose a machine that stays on.
#Choose an installation path
Use the current release surface to obtain a signed binary or the exact digest-anchored container image. If no verified artifact is offered for your platform, that release channel is not available there; do not bypass signature verification or guess an image tag.
| Path | Best for | Update owner |
|---|---|---|
| Binary | A Mac, Windows, or Linux machine you administer | The server can stage signed releases on its selected channel |
| Managed container | An always-on Docker host with persistent volumes | The server updates the verified binary on the data volume; the launcher stays fixed |
| Pinned container | Operators who want immutable, reproducible deploys | You pull and recreate from the next signed image digest |
| One-click VPS | An always-on server without hand-building the host | The template states whether it follows the managed or pinned container path |
| From source | Contributors and custom builds | You rebuild; the server only reports available releases |
All paths run the same server. The choice changes packaging and updates, not recipe behavior, grants, or where data lives. See Updates for channels and the safety model behind self-applying releases.
#Binary
Download the artifact matching your operating system and CPU from the signed
release. The installer verifies the release manifest, the binary signature,
and the declared SHA-256 before putting recued on your path. A verification
failure is a stop condition.
To keep a foreground server and its data together while testing:
mkdir -p ./recued-data
recued serve --db ./recued-data/recued.dbThe boot banner shows the actual database path, local URL, and first pairing code. For an always-on install, put the same command behind your operating system's service manager rather than relying on an open terminal.
#Containers
Both container paths need a persistent data mount. The managed image expects
the server data and its updatable binary under /data; an immutable image uses
the data path printed by its release command. Copy the complete command from
the release surface so the image name, digest, ports, user, and volume path stay
together.
Do not store state only in the container's writable layer. Recreating that container would otherwise create what looks like a fresh server and strand the old warehouse on the deleted layer.
#One-click VPS
The provider template creates the host, persistent volume, service, and minimum firewall rules. Choose a private/LAN-style template for pairing and outbound integrations only. Choose the HTTPS template only when you need webhooks, Reception, or a client outside your private network; have its DNS name ready before certificate enrollment.
The VPS belongs to you and the provider. It is not a Recued-hosted copy of your server, and deleting the VPS deletes its local data unless you have an archive or provider snapshot.
#From source
From an existing source checkout, Node.js 20 or newer and npm can build the same server entry point:
npm install
npm --workspace @recued/server run build
mkdir -p ./recued-data
node backend/server/dist/bin.js serve --db ./recued-data/recued.dbRun those commands from the repository root. Source builds use the source
update channel: they can report a newer release, but they never replace your
build automatically.
#The data directory
Everything the server knows lives in its data directory: the warehouse database, content-addressed files, connection records, installed recipes, update ledger, and audit history. Treat that directory as the server's identity:
- Put it on storage that survives a restart, upgrade, or container recreation.
- Restrict operating-system access to the account that runs Recued. The directory contains encrypted secrets and operational metadata even after at-rest encryption is enrolled.
- Back it up like anything you cannot re-download. There is no hosted Recued copy to restore from.
- Keep the recovery key from first pairing separate from the machine. The server unlocks with its local key file; the recovery key is the other route back into the same encrypted state.
The supported backup is the one-file encrypted archive described in Backup and restore. Copying a live database directory is not a substitute for an archive unless your platform also guarantees a consistent snapshot.
#Protecting the key file
The key file sits in the data directory, so it is worth deciding what protects it before the first start. The server seals it with the first factor available:
| Factor | When it applies | Where the secret lives |
|---|---|---|
RECUED_IDENTITY_PASSPHRASE |
You set the variable | Your environment or secret manager |
| A platform secret store | macOS login keychain, Windows DPAPI, or systemd-creds can hold a secret for this host | The platform store, outside the data directory |
| Unsealed | Neither of the above is available | Nothing: the key file is readable beside the database |
Set the passphrase before starting the server for the first time:
export RECUED_IDENTITY_PASSPHRASE='a long, random passphrase'
recued serve --db ./recued-data/recued.dbKeep it in the mechanism that starts the server — a systemd EnvironmentFile,
a compose env_file, or a secret manager — not in the config file, which lives
in the directory the passphrase protects. Once a key file is sealed with it,
the passphrase is required at every start; the server stops with an explicit
error rather than starting without it.
Containers usually need it. A host credential key is either on the ephemeral container layer, where recreating the container destroys it, or inside the data volume, where it travels with any copy of that volume. Both are worse than not sealing, so the platform rung declines and a containerised server runs unsealed unless you supply a passphrase.
Changing the passphrase later is cheap. Stop the server and run:
recued rotate-passphrase --db ./recued-data/recued.dbIt re-seals the same key file under a new passphrase, so the realm, the data and the server identity are untouched and nothing pairs again. Set the new value in the service environment before starting the server.
Changing which factor seals the key file is a different matter: that choice
is recorded when the file is created and is permanent for that realm. Before
the first pair the key file is disposable, so changing your mind costs a fresh
identity and nothing else — stop the server, delete the key file, set or unset
the variable, and start again. Afterwards it requires re-creating the server
identity with recued recover-keyfile and your recovery key, and then every
paired device pairs again, the publisher identity changes, and the account
binding is lost, though the data itself is untouched.
An unsealed server is still a working server, and its warehouse is still
encrypted. What sealing adds is that a copy of the whole data directory does not
carry the key that opens it. Run recued auth-status at any time to see which
factor is in use.
#Confirm health
The boot banner should say the server is running and print a local URL. From the same machine, probe the unauthenticated liveness endpoint:
curl --fail http://127.0.0.1:7717/healthA healthy listener returns HTTP 200 with a JSON body containing
"status":"ok". This proves the process is accepting requests; it does not
prove that a connection or recipe works. Next, read the active process's boot
log for its reachable addresses, webclient link, and pairing code. For a
container or service-manager install, use that platform's normal log viewer;
the code printed by a separate command process is not attached to the running
server.
The code is single-use and expires after 15 minutes. If it expires before the first pair completes, restart the server with the same database and configuration, then use the new code in the new boot log. A server that cannot write its data directory, bind its port, or print a boot pairing code is not ready for enrollment; fix that before continuing.
#Reachability is optional
A local-only server is a fully working server. Keep it bound to loopback or a private network unless another device needs it. Public reachability matters only for features that receive inbound traffic; read Reachability before opening firewall ports, DNS, or certificates.
#Next
Attach a client in Pairing and devices.