# Publish your own App

Your own Apps are private to your organization and show under **Apps**, **Mine**. There are two ways to make one:
from a public image, for a service, or from your repository, for a desk with your project's toolchain in it. Only an
organization's owners and admins can add Apps.

## A service from a public image

For a database or another server that has a public image, such as `postgres:16`:

1. In **Apps**, choose **Services** and press **Add a service**, then **From a public image**.
2. Enter the **Image**: a tag (`postgres:16`, `ghcr.io/org/app:1.2`) or a digest-pinned reference. Only public
   images work for now: a Compute can't pull a private one yet.
3. Give it a **Name**, unique in your organization. **Version** is the image's tag unless you set one.
4. Write its **Instructions**: what an agent needs to use it, such as "Listens on 5432. Give `POSTGRES_PASSWORD` as a
   secret at launch."

It's published at once, ready to launch ([Services and the workspace network](/docs/services)). From a terminal,
`uremot publish --name postgres --image postgres:16` does the same.

## A desk from your repository

A desk App is a container image built `FROM` UremotOS, with your project's tools in it, plus a `UREMOT.md` that tells
an agent how to build, run and test the project. You'll need Docker on the machine that builds it.

The easy way is to let your AI do it. In your harness, in the repository, ask it to put the project on Uremot. The
`uremot-onboard` skill scans the repository, asks you what it can't tell, writes the `Dockerfile` and `UREMOT.md`,
then builds and publishes them: [uremot-onboard](/skills/uremot-onboard/SKILL.md).

To do it by hand, write a `Dockerfile` in the repository and publish it:

```sh
uremot publish --name my-app --version 1.0.0 --instructions UREMOT.md
```

`uremot publish` builds the image with your local Docker and pushes it to your organization's private repository on
the Uremot registry. Then it publishes the image as a version of the App, and creates the App the first time. It asks you to
approve a sign-in in your browser. On a desk, or in CI, it uses the key in `UREMOT_AGENT_KEY` instead. If you belong
to several organizations, name the one to publish into with `--org <slug>`.

Useful flags:

| Flag | What it does |
| --- | --- |
| `--kind` | `desk` (the default), `service`, or `base` for an image other Apps build from |
| `--instructions` | A Markdown file an agent reads in every Instance of this version, at most 32 KB |
| `--variable KEY` | Declares an environment key the App needs, by name only, never a value |
| `--context`, `--file` | The build directory and the Dockerfile in it (`.` and `Dockerfile`) |
| `--display-name`, `--description` | How a new App is shown in **Apps** |

Run `uremot publish --help` for the rest.

## New versions

Publish again with a new `--version`, or, for an App made from a public image, choose **Publish a new version** in
the menu on its page. The new version becomes current, and new Instances launch it. Each architecture is its own
build: publish the same version from an x86_64 machine and an arm64 one, and a Compute pulls the one for its own.

## Next

- [Hire an agent](/docs/hire-an-agent) onto your desk.
- [Apps and the Marketplace](/docs/apps) explains versions, variants and instructions.
