Summary#
Runs a complete platform on your own machine, with a database it starts and manages itself. Nothing outside your computer can reach it, it needs no account and no cloud project, and the only difference from a hosted platform is which address you point at. It is what Running tests locally and Debugging tests locally run against.
Signature#
osyrin dev [--devname <name>] [--port <n>] [--keepalive <minutes>] [--reset] [--backup-held-admin]Description#
Starting it#
Run it from your project directory and leave it running in a terminal:
osyrin devThe first start downloads a small database bundle once; after that it is up in a few seconds. It binds to your machine
only, so nothing on the network can reach it. Your local data persists between runs — stop and restart and it is still
there. --reset throws that data away and rebuilds from your source.
A first start that is interrupted — stopped, or ended by another command, while it is still preparing its database — costs nothing but the retry: the next start recognises its own unfinished work, discards it and prepares the database again. It never refuses to start over something it left behind itself.
One server per project, on a stable address#
Each project gets its own local platform, and it always answers on the same address — the port is derived from the
project, so a bookmark keeps working across restarts and two projects (or two checkouts of the same repo) never fight
over a port. --port overrides that when you need a specific one. Because the address is derived, the other commands
find the running server on their own; you never have to tell them where it is.
Starting osyrin dev again for the same project reclaims the one already running rather than leaving it stranded:
there is only ever one server per project, and a restart takes the place of the old one instead of piling up beside it.
--devname <name> gives the server an explicit identity instead of deriving it from the project directory — its data,
its address and its one-per-identity reclaim all follow the name. Use it to run a second, separately-named platform
from the same directory, or one shared platform from several. Every other command takes the same --devname, so point
compile, test, launch or logs at a named server with the flag, or set OSY_DEVNAME once for the whole shell.
A name is the only way to say which platform you mean: a command never takes a data directory, so the path is always derived from the identity. That is deliberate — when two commands name the same identity they cannot reach different platforms, so a compile can never quietly land somewhere other than the app you are looking at.
Tests share one platform#
osy test does not need a platform per project. When your project has none running, its tests run on the shared
test platform of the build you are using: one local platform, and one database server, for every project you test
with that build — each project an app of its own on it, every run in throwaway copies of its own, so no project sees
another's data. Testing five projects at once, from five terminals or five checkouts, starts one platform rather than
five. A different build — a checkout testing its own change to the platform — gets one of its own.
It is named test-platform-… in Listing your local platforms, and it belongs to no project or checkout: starting a
project's own platform never stops it, and its start stops nothing. It stops itself after an idle hour like any
platform a command started, and osy stop --test-platform stops it at once (Stopping the local platform).
Running tests locally has the full order in which osy test picks a platform, and OSY_TEST_PLATFORM to
change it.
It stops itself when you walk away#
By default a server that has gone 60 minutes with no requests exits on its own, so an abandoned one does not keep a
whole platform and its database running until you notice. When it does, it says so plainly in its output — that it
exited because it was idle, and how to change the window — so a server that is gone when you come back is never a
mystery. --keepalive <minutes> sets the window, and can only shorten it: 60 is the most, and --keepalive 0 is refused,
naming the bound — restarting costs nothing, because the data lives in the instance directory. An attached debugger
keeps it alive: a paused breakpoint sends no requests, but the server will not be
reaped out from under you.
A page you have open keeps it alive too — when you opened the platform to look at it. A platform started by
osy launch or osy studio, or for an app opened from Studio, stays up for as long as one of its pages is open in a
browser, however long you only watch; its quiet hour starts when the last page closes. A platform that osy test,
osy compile or osy check started for itself does not get this: an open page there is not activity, and sixty
quiet minutes end it. Launching an app on a platform a test run started turns it into one that stays. osy instances
says why a quiet platform is still up — kept up: page open — beside it.
When the platform's own Admin would delete data#
The platform's Admin — the application that runs the platform itself — is deployed on start. When the new version would delete data (it drops an entity, a field or an enum member), it is never deployed silently. In a terminal the start asks, naming what would go:
Admin's new version would delete data — Dropped entity Invoice. Take a backup of Admin's database and continue? [y/N]Answer y and it backs up Admin's database first, then deploys with that backup recorded. Answer anything else and
nothing is deployed: the Admin you had keeps serving, when this build can serve it. A start with nobody to ask — one an
osy command brought up in the background — never deploys it; it says so, with the two ways to approve: start
osyrin dev in a terminal and answer y, or start it with --backup-held-admin, which backs up and deploys without
asking. If this build cannot serve the Admin you had either, the platform does not start until you choose.
Or let the loop start it for you#
You do not have to start it by hand. When you run Compiling your app or Launching your app and no local platform is running for the project (or Running tests locally and no shared test platform is running for this build), they start one for you in the background, wait for it to be ready, and leave it running so the next command is fast. The whole loop is one command — you never have to remember to start (or restart) a server. When you're done, Stopping the local platform shuts it down; its database stops with it, so nothing is left running.
A server keeps the build it started with, so after you rebuild the platform these commands replace an older server
rather than talk to it. Several commands arriving at once — compile and test fired together, say — produce one
restart: the first to arrive does it, and the others wait for the new server and say so, however long a first start
takes on a busy machine. The same holds for a server that is still starting when a command arrives, whoever started
it: the command waits for it instead of starting a second one beside it.
You are the administrator — no login#
On a machine-only platform the person at the keyboard is the administrator, so the operator commands need no
credentials: login, whoami and connect simply report that and continue. This applies only to the platform's
own operator commands. Your application's security is unchanged and behaves exactly as it does in production — a test
runs as an anonymous, secured caller, your app's own login works, and your access rules are enforced. Local is faster
and private; it is never a relaxed rulebook.
An organization is already there#
A local platform comes with a single ready-made organization, so there is no organization-and-user dance before you can
create an app. org list shows that one organization and org create reports it (there is nothing to create locally).
Apps you create belong to it, and are reachable by their plain name — an app named in your project is served at
http://<app>.localhost:<port>/.
What works, and what says so when it can't#
Everything the local loop needs works: validate and build, run and debug tests, create and compile an app, launch it, manage its users, read its logs, and set its secrets. A handful of commands describe operations a machine-only platform cannot perform — taking cloud backups, publishing or deploying a release, and the like. Those fail loudly with a clear reason and a non-zero exit; they never report success for something that did not happen. If a command can't do the thing here, it tells you plainly.
It is for development, not hosting#
A local platform is a fast, private place to build — not a place to run something for real. It has no backups, no sharing, and no durability, and it is deliberately unsuitable for hosting. Durability lives on a hosted platform; keep anything that matters there.
Examples#
The everyday loop — one platform, many runs, all offline:
# terminal 1
osyrin dev
# terminal 2
osy test
osy test --filter TotalsReset the local data and start fresh:
osyrin dev --resetExit after 15 idle minutes, on a port you choose:
osyrin dev --keepalive 15 --port 8099Back up and deploy a new Admin that deletes data, without being asked:
osyrin dev --backup-held-adminRun a second, separately-named platform from the same project, and point the other commands at it:
# terminal 1
osyrin dev --devname scratch
# terminal 2
OSY_DEVNAME=scratch osy compileSee also#
Running tests locally — run your app's tests against this local platform.
Debugging tests locally — debug a single test against it, with breakpoints in your editor.
Launching your app — open your app in a browser on this local platform.
Compiling your app — compile your source into your app on this local platform.
Stopping the local platform — stop the local platform serving your project.