Dedicated instances
A dedicated instance is one complete Ophiolite for one organisation: its own server, its own PostgreSQL database and
its own volumes, reached at its own address NAME.DOMAIN. One host runs several of them behind one host proxy, which
obtains each address’s certificate and sends each request to the instance it names. Every instance starts with the
public NLOG sample (well headers and a gamma-ray log) and one person, who receives a single-use sign-in link.
ophiolite-ops instance does all of it. The same commands this page shows are the ones the release’s qualification
runs.
The host rule
Section titled “The host rule”A trial host runs nothing else. The instances, their databases and the host proxy are the only services on it. No firewall is built between an instance and the host: an instance’s containers can reach its own database, the host proxy and DNS, and they could reach any other service listening on the host’s network addresses. On a host that runs nothing else there is nothing to reach. Instances cannot reach each other’s networks or databases.
init checks the rule: it asks, from a container on the host, whether any of the host’s listeners answers, and
refuses while one does. Stop that service, or, when it must stay (an SSH server, say), record it as an exception:
python3 ophiolite-ops instance init --base-domain DOMAIN --proxy-image REF --allow-listeners 22check asks again and names any listener that answers and is not an exception.
What you need
Section titled “What you need”- A Linux server with an x86_64 processor that runs nothing else (the host rule above), with at least 16 GB of memory and 40 GB of free disk.
- Docker Engine with the Compose plugin, or rootless Podman 4.9 or later with Docker Compose 2.
- Python 3.10 or later.
- A domain for the instances, and a wildcard DNS A record (
*.DOMAIN) that points at the server. - Ports 80 and 443 reachable from the internet, so the proxy can obtain certificates and people can reach their instance.
- The Ophiolite release image on the server, by its digest (
REGISTRY/ophiolite-server@sha256:DIGEST).
Each instance holds up to 3 GiB of memory (2 GiB for the server, 1 GiB for its database). The host refuses a new
instance when the limits of all its instances would pass the memory budget (12 GiB by default, memory_budget_mib
in host.json), or when its disk has less than 10 GiB free (disk_floor_mib).
Prepare the host
Section titled “Prepare the host”Copy the tool out of the image, then claim the engine for one set of instances and start the proxy:
docker run --rm --network none --entrypoint cat REF /opt/ophiolite/package/host/ophiolite-ops > ophiolite-opspython3 ophiolite-ops instance init --base-domain DOMAIN --proxy-image REF --allow-listeners 22REF is the release image by its digest; DOMAIN is the domain of the wildcard record. --allow-listeners 22
records the SSH server you reach the host by as the one exception to the host rule; leave it out when nothing listens. The instances live under
~/ophiolite-instances (--root chooses another folder). One engine holds one such folder: a second init on the
same engine is refused. On rootless Podman, give the proxy high ports (--http-port 8080 --https-port 8443) and
forward 80 and 443 to them. Without that forwarding, people reach an instance at https://NAME.DOMAIN:8443, and that
port is part of its address: the sign-in link and the message carry it. Choose the ports before the first instance;
an instance keeps the address it was made with, and check reports one the proxy no longer serves.
Create an instance
Section titled “Create an instance”python3 ophiolite-ops instance create alpha --email person@partner.example --organisation "Partner name" --image REFThis makes alpha.DOMAIN with the public sample and one person, and prints the message for that person: the
address, the line “It is for public data only”, how long the trial runs (30 days) and a sign-in link that works once
within 72 hours (--hours, at most 168). Send the message yourself, or add --send to send it through the host’s
mail relay. The link is never stored: if it is lost or expires, make a new one:
python3 ophiolite-ops instance link alphaA trial project’s name starts with “Trial, public data only”. --kind managed makes a workspace without that line.
A create takes about two minutes. The first time a name is served, the proxy also obtains its certificate, which
can add up to three minutes; the create waits for it. When the certificate cannot be obtained, the create stops with
“the proxy did not take the new configuration”: check that alpha.DOMAIN resolves to this host and that ports 80 and
443 are reachable from the internet. The proxy’s own log says which: docker logs on the container whose name ends
in -proxy-proxy-1.
When a create stops
Section titled “When a create stops”A create that stops leaves the instance unfinished; list shows it with the phase it reached. Remove it (as under
“Remove an instance” below), then create it again:
python3 ophiolite-ops instance remove alpha --confirm alphapython3 ophiolite-ops instance create alpha --email person@partner.example --organisation "Partner name" --image REFSee the instances
Section titled “See the instances”python3 ophiolite-ops instance listOne line per instance under a header: its name, kind (trial or managed), state, the last step a create reached
(linked when it finished), its release, its address and the next step when one is needed (a create that stopped,
an upgrade that failed, a removal to finish). Every instance command first checks that the proxy serves
exactly the instances that should be reachable, and corrects it.
Operate one instance
Section titled “Operate one instance”Every operator command of a single deployment works inside one instance:
python3 ophiolite-ops instance run alpha -- backup before-reviewpython3 ophiolite-ops instance check alphacheck compares the instance’s sources with the sample it was created with and reports what changed.
Upgrade
Section titled “Upgrade”python3 ophiolite-ops instance upgrade alpha NEW-REFpython3 ophiolite-ops instance upgrade --all NEW-REFpython3 ophiolite-ops instance proxy NEW-REFAn upgrade asks the new image whether it can start from the installed release, backs the instance up with the old
image, switches its files and starts the server with the new image, then checks that the new release is installed.
If the backup fails nothing changes. If the start fails, list shows it and the backup holds the instance as it
was. --all upgrades one instance at a time and stops at the first failure; list then shows each instance’s
release. The host proxy keeps running on the image it was started with; proxy moves it to the new image too, which
is optional and can come later.
Hand over the work: export
Section titled “Hand over the work: export”python3 ophiolite-ops instance export alphaThis makes the partner’s take-away: portable bundles of everything the first person can read, each checked after it
is made, with MANIFEST.json naming every item as bundled or omitted, and why. Bundles hold the current revision of
each item, not its history. The SDK opens them and another Ophiolite imports them. The bundles go to
~/ophiolite-instances/exports/alpha-TIME, which the tool prints; hand that folder to the partner, then delete it.
A removal makes its own bundles for the archive, so an export is not needed before one.
Remove an instance
Section titled “Remove an instance”python3 ophiolite-ops instance remove alpha --confirm alphaThe name is typed twice. The removal first writes what it will remove, then stops answering anyone but the operator,
makes the bundles, takes a complete backup and checks it, and only then withdraws the address, stops the containers
and deletes the volumes, the files this tool wrote and the instance’s line. The archive
(~/ophiolite-instances/archive/alpha-TIME) holds the bundles, the backup and ARCHIVE.json, and is kept for 30
days. If anything fails before the archive is complete, nothing is deleted. If the removal is interrupted, run the
same command again: it continues from where it stopped.
An instance that never started holds no data and is removed without an archive. Deleting an instance that holds data
without an archive needs both --no-archive and --destroy-data.
The certificate of alpha.DOMAIN stays in the proxy’s volume and in public certificate logs.
Archives
Section titled “Archives”python3 ophiolite-ops instance restore-archive ~/ophiolite-instances/archive/alpha-TIME alpha2python3 ophiolite-ops instance prune-archivesrestore-archive makes a new instance from an archive’s backup and gives its first person a new sign-in link.
prune-archives deletes the archives past their 30 days and names each one. The archives kept are the folders in
~/ophiolite-instances/archive (ls ~/ophiolite-instances/archive); each one’s ARCHIVE.json says when its instance was removed.
