Set up
Set up the HUB
The HUB is the deployment's control plane and discovery authority. Every client and every service resolves through the HUB. The HUB's domain is the discovery URL. Choose it once for the whole deployment.
The HUB binary is appserv. Install it with the install pattern. Use the package mountos-appserv. The HUB needs its own admin database and its own
Hub vault. The vault holds the HUB's secrets, the database connection and the
signing and verification keys.
Database and dialect
Create an empty database. Then put two values in the Hub vault, DB_URL for the connection and DB_DIALECT for the
dialect. The dialect is a deployment choice between two values, postgresql and mysql. The mysql dialect
covers any MySQL-wire store. Use PostgreSQL when there is no database preference. The schema
ships for both dialects. The choice costs no capability.
Then run appserv db install once. It reads DB_URL and DB_DIALECT from the vault, downloads the schema for that dialect, and
applies it in the same step. appserv caches the schema locally and reuses it on
later runs.
db install is not idempotent. Once the schema
exists it exits non-zero with an already-installed error, on a restart, on a
replacement machine, and on a second appserv instance sharing the admin
database. If you write your own unit file, make it best-effort rather than a
hard start pre-condition. Under systemd, prefix the ExecStartPre= line with -. Use db migrate for every later change;
that one is idempotent.
./mountos-install --pkg mountos-appserv
mountos-appserv env -w .env # config template (the Hub vault serves the sensitive values)
set -a
. ./.env
# no license file needed: with none loaded the deployment runs the Free tier
mountos-appserv db install # download + apply the admin schema (dialect from the vault)
mountos-appserv # start the HUBConfiguration
appserv env prints the full template.
The Hub vault (key mountos/appserv) holds these values.
DB_URLis the admin database connection.DB_DIALECTpicks the schema,postgresqlormysql.DB_PROVIDER_VERSIONis the engine version for capability detection, like16or8.0.32.ED25519_SIGNING_KEYis the HUB's private signing key.ED25519_VERIFICATION_KEYis its matching public key.PROVIDER_VERIFICATION_KEYis the admin public key. appserv checks SDK-signed Admin API calls against it (see Admin API access).
The environment file carries these values.
VAULT_PROVIDERnames the secret store and carries its address and role credentials.HTTPS_PORTis the discovery and Admin API listen port.TLS_CERT_FILEis the TLS certificate path.TLS_KEY_FILEis the TLS private key path.MOUNTOS_LICENSE_PATHis optional and appserv-only. It seeds the first license once, from a file or a directory of stacked license files. Leave it unset to run the Free tier. Region services ignore it; their license arrives from the HUB over the heartbeat.ADVERTISE_ADDRis the address the HUB advertises to services and clients.
The template also includes optional connection-pool and rate-limit tuning.
ADVERTISE_ADDR is the one place this setting is usually correct.
Supplying it forces explicit-address mode, which serves the same address in
both the public and the private role, and the HUB is normally reached at one
address by everyone. On a machine that has a real public and private split and
is reached differently by each, leave it unset so the service detects both.
See Two addresses per node.
To upgrade an existing HUB later, run db migrate. It applies only the
new migrations in range for the binary. The command is idempotent. It is safe to
run from multiple instances at the same time.
mountos-appserv db migrate # apply pending schema changes, then restartPublish the HUB behind a stable domain. The HUB hands that domain to every client as the discovery URL. Choose the domain once and keep it fixed. See Control plane and Vault and handshake.
Admin API access
After the HUB is published, administration is performed through the Admin API.
Only trusted backends sign Admin API requests with the admin key. appserv verifies
those signatures against PROVIDER_VERIFICATION_KEY.
The Admin SDK and dashboard page describes the Admin SDK and the dashboard.
Create an account and a region
An account is the tenant. Do the following:
- Create the account.
- Add a user.
- Create a region.
// an account is the tenant
const { id: accountId } = await client.accounts.create({ name: 'mountOS' })
const { id: userId } = await client.users.add({
accountId, username: 'jason', email: 'jason@mountos.io', name: 'Jason Ryan',
})
// creating the region auto-creates its default metadata cluster, "uno"
const { id: regionId } = await client.regions.create({
accountId, name: 'us-east-1', dns: 'us-east-1.example.com',
})// an account is the tenant
acct, err := client.Accounts.Create(ctx, &sdk.CreateAccountRequest{Name: "mountOS"})
user, err := client.Users.Add(ctx, &sdk.AddUserRequest{
AccountID: acct.ID, Username: "jason", Email: "jason@mountos.io", Name: "Jason Ryan",
})
// creating the region auto-creates its default metadata cluster, "uno"
region, err := client.Regions.Create(ctx, &sdk.CreateRegionRequest{
AccountID: acct.ID, Name: "us-east-1", DNS: "us-east-1.example.com",
})// an account is the tenant
let acct = client.accounts.create(&CreateAccountRequest {
name: "mountOS".into(),
description: None,
icon_url: None,
provider_info: None,
}).await?;
let user = client.users.add(&AddUserRequest {
account_id: acct.id,
username: "jason".into(),
email: "jason@mountos.io".into(),
name: Some("Jason Ryan".into()),
provider_info: None,
}).await?;
// creating the region auto-creates its default metadata cluster, "uno"
let region = client.regions.create(&CreateRegionRequest {
account_id: acct.id,
name: "us-east-1".into(),
dns: "us-east-1.example.com".into(),
}).await?;The region includes its default metadata cluster, uno, from the start. These
calls write only records in the HUB's admin database. You set up the region's own
database, vault, storage, and servers separately. uno remains not
ready until a service registers into it.
How trust works
Region services self-register with the HUB. The HUB issues no passwords.
Each service starts with its own signing key in its vault. The HUB holds the matching public keys. A service joins by signing a hello message with its key. The HUB checks the signature against that set of public keys. A client carries no service credential. It discovers its region with an access key. It then opens an encrypted session to the metadata cluster. The Hub vault is the source of truth for the verifier set. See Vault and handshake.