---
title: Deploy a site to your server
description: "Put a website on a server you run yourself, through a gateway: from an empty folder to a page that answers."
new_in: "2.2"
---

**Deploying a site to your server** means Ysra builds the site on a gateway,
deploys it to a [machine](overview.md), configures nginx and checks the page
answers — started by one sentence such as *serve our landing page on web-01*.
Before you start you need:

| You need | Where to set it up |
|---|---|
| A **gateway**: an always-on computer in the network, with Ysra installed and `ysra serve` running | [Machines and gateways](../gateways/overview.md) |
| The web server added as a machine on that gateway, in change mode, with nginx installed | [Add a machine](overview.md#add-a-machine) |
| The **desktop app** on your own computer, to sign an approval | [Sign an approval](approvals.md#sign-an-approval) |

## Steps

1. On the gateway, share a folder where sites are built:

    ```bash
    ysra serve --folder /srv/sites
    ```

2. On the gateway, add the web server and allow changes there. Name it
   `web-01`, kind `linux`, via `ssh`, and confirm its host key:

    ```bash
    ysra machines add
    ysra machines mode web-01 change
    ```

    Many servers at once: [Add many machines at once](../gateways/overview.md#add-many-machines-at-once).

3. On the gateway, trust your approval key and turn on approved runs (your
   public key is under **Settings → Approvals**, with **Copy the commands**):

    ```bash
    ysra approvers add <your public key> --name "My laptop"
    ysra approvers runs on
    ```

4. Start a thread on the gateway’s folder (**New thread on…** → the gateway →
   `sites`) and ask:

    ```text
    serve our landing page on web-01
    ```

5. Answer Ysra’s questions. If there is nothing to serve yet, it asks what to
   build; if the destination isn’t clear, it offers only ones that exist. The
   thread shows **Needs your input** until you reply.
6. Sign the approval when asked: “I need your signed approval to go on: …”.
   On the card **Approve changes on web-01: …**, choose **Approve with this
   computer’s key** and confirm. It covers **config** (the files) and
   **service** (reloading nginx), never delete, power, SSH access or shells.

Ysra then builds and deploys without asking again:

| Step | What Ysra does |
|---|---|
| Build | Into the gateway’s folder |
| [Deploy the folder](deploy-folder.md) | To `/var/www/sites/<name>` on web-01, keeping the previous version as a backup |
| [Write](write-file.md) nginx’s site file | The real file; it won’t write through a symbolic link |
| Test | `nginx -t` |
| Reload | `nginx -s reload` |
| Check | That the site answers |

The thread ends with what was done and where the site is. Each command is
under **What ran** when you open the machine in the
[Machines panel](../desktop/machines-panel.md), and in the gateway’s log under
the signed approval.

<!-- media: machines-deploy-site | One sentence to a live page on your own server | Gateway with /srv/sites served and web-01 in change mode; thread "serve our landing page on web-01"; Ysra asks what the page should contain; sign approval card (config, service); timeline shows build, deploy, write nginx file, nginx -t, reload, check; final message with the URL -->

## Where Ysra deploys

Ysra chooses from what you said, then from what the project already has. It
never asks for passwords or makes up credentials.

| The project has | Ysra deploys by |
|---|---|
| A machine you named, on your own server | Building into a folder on the gateway, then deploying it to the machine |
| A CI file | A git push that your pipeline deploys |
| A hosting provider’s configuration | That provider’s command-line tool, if it is installed and signed in |
| None of these | It asks, offering only destinations that exist now (your machines, signed-in tools, your git remote), or says what is missing and the simplest way to add it |

## nginx and approval kinds

| Command | Kind |
|---|---|
| `nginx -t`, `nginx -T`, `nginx -v`, `nginx -V` | **read** |
| `nginx -s reload`, starting nginx | **service** |

An approval with **config** and **service** covers a typical site deploy.

## If it doesn’t work

| Symptom | What happens / what to do |
|---|---|
| The deploy fails before the switch | The old site stays exactly as it was |
| The new site is wrong | Move the backup folder back into place, or ask Ysra to; it asks first |
| `nginx -t` fails | Ysra doesn’t reload, and shows what the test said |
| The approval doesn’t cover a step | Ysra stops and asks for one that does; see [Approvals](approvals.md#nobody-signs-approval-ignored) |
| “… isn’t connected right now. Run `ysra serve` there.” | The gateway is offline; start `ysra serve` on it |
| *web-01 is in observe mode …* | `ysra machines mode web-01 change` on the gateway |

## Related

- [Deploy a folder to a machine](deploy-folder.md) — the card, the backup and what is left out.
- [Approvals and automatic runs](approvals.md) — signing ahead of time.
- [Machines and gateways](../gateways/overview.md) — setting up the gateway.
