Run the web interface by hand
Dokumentace/Nasazení a údržba
Run the web interface by hand6 min čtení

Run the web interface by hand

Zdrojová dokumentace je zatím dostupná v angličtině. Ovládání čtečky odpovídá zvolenému jazyku.

Na této stránce

Previous: Docker Compose · Manual setup · Next: certificates and credentials

The web interface (apps/web) runs only in Docker, as a Compose project of its own beside a Scribe cluster. This guide starts it by hand and connects it to a cluster with auth: the Docker Compose guide's project, or services running on the host. scribe-ctl setup --runtime docker --web does the same for a cluster it runs (tutorial 5, what it wires up).

What it needs from the cluster:

From the clusterWhy
The storage or gateway endpoint, and the storage and gateway CA (pki/ca/ca.pem)Every request reaches repositories there, verified against that CA
The auth endpoint, and the auth CA (pki/auth-ca/ca.pem)Browser sign-in goes to Scribe auth; the web interface has no accounts of its own
A reader credential for the scribe-web service accountThe worker and the asset services index repositories as this account

It needs Docker Compose v2 and Node.js 26 or newer for the initialization script. Run every command from the checkout's apps/web directory. Compose builds the images from it, so the checkout must be the cluster's release.

1. Create the local files

sh
node deploy/init.mjs
text
Local secrets are ready. Configure /path/to/scribe/apps/web/.env, then run docker compose up --build -d.

It creates, once and never replacing an existing file, the ignored deploy/local/ directory: secrets/jwt.key and secrets/surreal.password (random, private), empty trust/, tls/ and worker/ directories, and .env from deploy/.env.example. It never copies a CA key or a credential.

2. Trust both CAs

Copy the two public CA certificates:

sh
cp /srv/scribe/pki/ca/ca.pem deploy/local/trust/ca.pem
cp /srv/scribe/pki/auth-ca/ca.pem deploy/local/trust/auth-ca.pem

The services see them read-only under /etc/scribe/trust. The web services use Node's TLS, which follows no CA handover: when a CA is rotated, give them both the old and the new CA for the overlap (certificates).

3. Issue the reader credential

Create the scribe-web service account, let it read every repository of each namespace the interface serves (including later ones), and issue its read-only credential. The credential records the auth address and CA the web services use, so name auth as they reach it. With the Docker Compose guide's project, that is the service name, which its administrator credential already carries; from /srv/scribe:

sh
docker compose run --rm auth-admin users add scribe-web --service
docker compose run --rm auth-admin namespace-readers set scribe-web studio
docker compose run --rm auth-admin credentials create scribe-web --service --name web-reader --days 365 --out /new/reader.credential
mv secrets/new/reader.credential /path/to/scribe/apps/web/deploy/local/worker/reader.credential

For a cluster on the host, run the same three commands with scribe-auth (the auth helper), naming the address containers reach the host at:

sh
auth users add scribe-web --service
auth namespace-readers set scribe-web studio
auth credentials create scribe-web --service --name web-reader --days 365 \
  --auth tls://host.docker.internal:7443 --auth-ca deploy/local/trust/auth-ca.pem \
  --out deploy/local/worker/reader.credential

The account has no password, never signs in and never administers; a namespace reader grant never writes (service accounts). To limit it to chosen repositories instead, skip namespace-readers set and grant it reader on each with grants set scribe-web NAMESPACE/REPOSITORY_ID --role reader.

On Linux the web services run as uid 1000 and see the host files' owner and mode. If your account is not uid 1000 (id -u), let that uid read the credential, the secrets and the CAs without making anything group- or world-readable, for example with ACLs (package acl):

sh
sudo setfacl -m u:1000:x deploy/local/worker deploy/local/secrets deploy/local/trust
sudo setfacl -m u:1000:r deploy/local/worker/reader.credential deploy/local/secrets/* deploy/local/trust/*

or hand the files to uid 1000 (sudo chown 1000 ..., keeping their modes). ls -l then shows -rw-r-----+: the group bits display the ACL mask. Docker Desktop on macOS and Windows maps ownership, and neither step is needed. Never chmod 644 a credential file: it holds a private key.

4. Point .env at the cluster

Edit .env. For the Docker Compose guide's project (named scribe), the web services join its network and reach the services by name, which their certificates carry:

sh
WEB_SCRIBE_NETWORK=scribe_default
WEB_SCRIBE_SERVER=tls://gateway:7557
WEB_SCRIBE_AUTH_SERVER=tls://auth:7443
WEB_SCRIBE_TLS_SERVER_NAME=
WEB_SCRIBE_AUTH_TLS_SERVER_NAME=
WEB_SCRIBE_CLONE_SERVER=tls://127.0.0.1:7557
WEB_SCRIBE_CLONE_AUTH_SERVER=tls://127.0.0.1:7443
WEB_SCRIBE_READER_CREDENTIAL_FILE=/etc/scribe/worker/reader.credential

For services on the host, keep the example's host.docker.internal endpoints: the containers connect there while verifying the certificate identity 127.0.0.1 (WEB_SCRIBE_TLS_SERVER_NAME, WEB_SCRIBE_AUTH_TLS_SERVER_NAME), and set only WEB_SCRIBE_READER_CREDENTIAL_FILE. That is validated on Docker Desktop for macOS. Native Linux Docker reaches the host's bridge address, not services bound only to host loopback: there, give Scribe a listener the container network can reach, or run it in Compose as above. Never disable TLS verification to fix routing.

WEB_SCRIBE_CLONE_* are the addresses the Clone menu shows people. Connection configuration describes every variable.

5. Prepare the database

A new database is prepared, and every release that requires it migrated, by the worker image's migrate.js; no process migrates on startup, and one that needs a migration refuses to start. Include compose.scribe.yaml whenever the services join the cluster's network:

sh
docker compose -f compose.yaml -f compose.scribe.yaml build
docker compose -f compose.yaml -f compose.scribe.yaml run --rm worker node apps/worker/dist/migrate.js --dry-run
docker compose -f compose.yaml -f compose.scribe.yaml run --rm worker node apps/worker/dist/migrate.js
text
...
{"event":"applied","id":"0001-stamp-shape-versions","counts":{}}
{"event":"applied","id":"0002-sign-out-bearer-sessions","counts":{}}
{"event":"done","dryRun":false,"migrations":["0001-stamp-shape-versions","0002-sign-out-bearer-sessions"]}

run starts the database, cache and object store it needs. The flags and the migration ledger are described in stored data versions.

6. Start it

sh
docker compose -f compose.yaml -f compose.scribe.yaml up -d --wait
curl --fail --show-error http://localhost:8080/api/v1/health
text
{"status":"ok","version":"v1"}

Open http://localhost:8080 and sign in with a Scribe user: tutorial 5, step 4 shows what to check, and its diagnosis table applies here with docker compose logs SERVICE. Only nginx publishes a port, on 127.0.0.1 by default (networks).

7. Serve HTTPS with your certificate

The web interface's certificate is yours: one browsers trust for the name people use, not one from Scribe's private CAs. Put the certificate chain and its key in deploy/local/tls/:

sh
cp /path/to/fullchain.pem deploy/local/tls/fullchain.pem
cp /path/to/privkey.pem deploy/local/tls/key.pem

and set, in .env, the exact origin and ports:

sh
WEB_TLS=1
APP_ORIGIN=https://scribe.example.com
WEB_BIND=0.0.0.0
WEB_PORT=443
WEB_HTTP_PORT=80

Run the same up again. nginx serves HTTPS on WEB_PORT and redirects HTTP on WEB_HTTP_PORT to APP_ORIGIN; missing certificate files stop it rather than falling back to HTTP. Replace the files and run up again to renew.

For an intranet name that exists in public DNS but is not reachable from the internet, deploy/issue-tls.sh obtains a Let's Encrypt certificate through Cloudflare DNS-01 and writes both files; rerun it to renew (deploy/issue-tls.sh --help lists its options):

sh
# Token with Zone/DNS/Edit and Zone/Zone/Read, kept in an ignored file:
# printf '%s\n' "$token" > deploy/local/secrets/cloudflare.dns.token
# chmod 600 deploy/local/secrets/cloudflare.dns.token
deploy/issue-tls.sh --email ops@example.com scribe.example.com

Afterwards

  • Stop and start: docker compose -f compose.yaml -f compose.scribe.yaml stop and up -d --wait. The database, search index and object store are Compose volumes (database, search, objects); never down -v.
  • Backups: the database and objects volumes, taken together while the services are stopped (the commands), and deploy/local/secrets/ with them; objects holds flow-run bundles that exist nowhere else, and the search index is rebuilt (what to back up).
  • Reader credential renewal: certificates and credentials; the services reread it on every use.
  • Upgrades migrate the database: upgrades.
  • Asset previews: the two sandbox containers need user namespaces; see sandbox containers on Ubuntu 23.10 and later.
Zdroj docs/manual/web-interface.mdVerze 2b8dcccb