# Deploying your app to an environment

> Builds your app on this machine and hands it to the zone one of its organization's environments runs on — `osy deploy --env prod --server https://osyrin.app` — which rebuilds it, brings the environment's database to it and serves it; `osy status` shows where it runs and how its deployments went. A deploy names its platform: without `--server` it is refused, and `osy launch` / `osy compile` run the app on this machine instead. No platform compiles your app to deploy it.

<!-- id: local-deploying-your-app · area: local · stability: preview · html: https://osysharp.com/reference/local/deploying-your-app/ -->

## Summary        {#summary}

`osy deploy --env <slug>` runs your app in one of its organization's environments, such as `prod`. There is **one way to
deploy**, whichever platform you deploy through: your app is **built on this machine** into a bundle, the platform is asked
with the bundle's hashes, the bundle is uploaded to the **zone** the environment runs on, and that zone **rebuilds** it,
brings the environment's database to it and serves it. `osy deploy` follows all of that until the version is served or
fails, and prints why when it fails. `osy status` shows where the app runs, which version its users are served, and how
its recent deployments went.

## Signature      {#signature}

```console
osy deploy --env <slug> --server <url> [path] [--version <version>] [--reason <text>] [--migration <file>] [--no-follow] [--onto-restore <restore>] [--json]
osy status [path] [--server <url>] [--app <slug>] [--devname <name>] [--json]
```

## Description    {#description}

**A deploy is a handover, never a compile on the platform.** It goes through the platform `--server` names, with your
stored sign-in: the platform checks you may deploy, records the version, chooses the zone behind the environment's
offering and lets you upload the bundle there; the zone builds it. A platform never compiles your app to deploy it.

**A deploy names its platform.** Without `--server`, `osy deploy` is refused, and the refusal names the server your
project's `osyrin.json` is linked to, when it is — so a project published to the cloud is never deployed to this machine
by a command that left the server out. To run the app here, use `osy launch` (it compiles the app and opens it in a
browser) or `osy compile` ([Compiling your app](https://osysharp.com/reference/local/compiling-your-app/)). The steps, and why the zone and not your
machine builds, are in [Deploying an application to a cloud platform — the zone builds it](https://osysharp.com/reference/zones/deploying-an-application/).

**It says when the access check is due.** Before it builds, a deploy prints one line when the access check has not
been run on this project, ran as an older version of the check, ran on other source, or found mismatches; it never
refuses for it ([Checking access](https://osysharp.com/reference/local/checking-access/)).

**The version is named by the sources.** `--version` names the version to deploy under. Left out, the platform reuses the
version it already recorded for exactly these sources, or names the next patch. A label already deployed from other
sources is refused, and so is a version a platform compiled itself.

**Your users get the version only once the zone runs it.** The deploy's build ends in a deployment, which moves through
these states:

| state | what it means |
|---|---|
| `Queued` | written by the platform once the zone built the version, not yet handed to the zone to run |
| `Rolling` | handed to the zone; the zone is starting it |
| `Succeeded` | the zone reported it running — and, in the environment the app is served from, its users now get this version |
| `Superseded` | a newer deployment of the same app and environment reached the zone first |
| `Failed` | the zone reported it failed, or it was not running within 30 minutes |
| `RolledBack` | it failed, and the platform put back the version that ran before |

**You are told how it ended.** `osy deploy` prints the zone's or the platform's own words when a deploy is refused or
fails at any step — the upload, the zone's build, the environment's database, the rollout — and exits non-zero. The
application's team is emailed when a deploy fails, and whoever deployed when it succeeds, fails or is rolled back. A
superseded deployment sends nothing — the newer one's outcome is the news. If the email cannot be sent, the deployment
still ends as it did, and `osy status` is always the record. The platform's operators are alerted about every failure.

**A failure puts the previous version back on its own.** When a deployment fails and the environment was running an
earlier version, the platform asks for that version again and says so on the new deployment ("automatic rollback"). A
failed rollback is not rolled back again.

**The environment users reach is the highest-ranked one.** An app placed in several environments is served from its
highest-ranked environment; a deployment into a lower one runs there and leaves what users are served alone. `osy status`
marks the serving environment.

**Each environment has its own data.** The first deploy into an environment gives it its own database — the zone creates
it while it builds the version, with every table the app stands on — and every deploy after that brings the database's
tables up to the version being deployed before the zone runs it. If the database cannot be created, the deploy fails,
nothing is served, and `osy deploy` says why. Rows written in `sandbox` are never seen in `prod`, and promoting a version to
`prod` moves the code, never the data.

**Each environment has its own address.** `<app>.<domain>` serves your app's highest-ranked environment, and
`<app>--<environment>.<domain>` serves any one of them — `billing--sandbox.<domain>` answers from sandbox's data, at the
version sandbox's last deployment put there. Work an environment starts runs in that environment too: a workflow, a
scheduled job or a background task started in `sandbox` reads and writes sandbox's data, and a callback link a workflow
sends out points back at `billing--sandbox`. An address naming an environment your app is not deployed to answers 404.

**An environment can follow your deploys.** Each environment is set to follow deploys never (the default), for patch
versions only, or for every version. When a deploy into another environment succeeds, every environment set to follow it
gets the same version from the bundle its zone already holds — no second `osy deploy` needed. See
[Deploying an application to a cloud platform — the zone builds it](https://osysharp.com/reference/zones/deploying-an-application/).

Who may deploy: the organization's Owner or Admin, and any member of the app. An environment that requires an approval
cannot be deployed to this way yet — the refusal says so.

- `--env` — the environment's slug. Required.
- `--version` — the version label to deploy under; left out, the platform names it.
- `--reason` — recorded on the deployment and shown by `osy status`.
- `--server` — the platform to deploy through. Required. When the deploy succeeds the project's `osyrin.json`
  records where it went — `osy link` reads it ([Publishing a project to Osyrin](https://osysharp.com/reference/local/publishing-to-osyrin/)).
- `--migration` — the `.migration` file the deploy carries to the zone.
- `--no-follow` — return once the bundle is handed to the zone; `osy status` follows it.
- `--onto-restore` — deploy onto the copy a restore made of the environment's database instead of the database it serves: an
  attempt you choose and are responsible for, which switches the environment onto the copy
  ([Restoring a backup taken on an older version](https://osysharp.com/reference/zones/restoring-a-backup-of-another-version/)).
- `path` — select the project, as for every `osy` verb (`--devname`, for `status`, the local platform).
- `--server` / `--app`, for `status` — the Osyrin and the app to ask. Left out, `status` asks the server and app this
  project's `osyrin.json` records from its last deploy, and the local platform when the project was never deployed
  anywhere else — so straight after `osy deploy --server https://osyrin.app` it answers about that deploy.
- `--json` — `deploy` prints how the deploy ended as JSON; `status` prints placements and deployments as JSON.

## Examples       {#examples}

```console
osy deploy --env prod --server https://osyrin.app      # built here, rebuilt and served by prod's zone
osy deploy --env prod --server https://osyrin.app --version 1.4.0 --reason "back to the last good one"
osy deploy --env prod                                   # refused: names the server to add, and osy launch / osy compile
osy status                                              # where it runs, what it serves, how deployments went
osy status --server https://osyrin.app --app billing-acme --json
```

## See also       {#see-also}

[Compiling your app](https://osysharp.com/reference/local/compiling-your-app/) — compile against the local platform while you build; a deploy does not need it.

[Deploying an application to a cloud platform — the zone builds it](https://osysharp.com/reference/zones/deploying-an-application/) — every step of a deploy, and why the zone builds it.

[Running a local platform](https://osysharp.com/reference/local/running-a-local-platform/) — the local platform these verbs talk to.

[Seeing what happened when your code ran](https://osysharp.com/reference/local/seeing-what-happened/) — look inside a run when a deployment's app misbehaves.
