---
title: Server mode
description: Run one Pipedash server and connect the web, desktop and mobile apps to it. Covers the hosts, pairing a device step by step, address rules, device management and common errors.
---

In server mode, one Pipedash Server makes every call to the CI/CD providers. The Pipedash Clients on the web, the desktop and the phone show what the server finds. A client needs no provider tokens of its own.

<Screenshot src="client-server" dir="docs/server-mode" variant="dialog" alt="Pipedash Client on web, desktop and mobile above the Pipedash Server, which sits above 12 CI/CD provider logos. Actions go down from the client to the server, live updates go up. Checks go down from the server to the providers, results go up" caption="The server checks the providers and sends each change to every open client. Reruns and cancels go back through the server." />

## How it works

- **Checks:** the server polls each provider on its own refresh interval and keeps the results in its database. The [Refresh](/docs/features/refresh) page covers the schedule.
- **Live updates:** each change reaches every open client at once. A client never polls the providers.
- **Actions:** a trigger, rerun, cancel or approval goes from the client to the server, and the server calls the provider.
- **Tokens:** provider tokens stay on the server. A paired device gets only its own device token.

## Hosts and clients

| Role | Runs on | How it connects |
|---|---|---|
| Server | A `pipedash-web` instance, usually in Docker | Serves the web app and the API on one port |
| Server | A desktop app with "Share on this network" on | Serves on its LAN address over plain `http` |
| Client | A browser | Opens the server address and signs in with the vault password |
| Client | The iPhone, iPad or Android app | Pairs with a code, then keeps one connection to the server |
| Client | The desktop app | Pairs with a code from Settings, Devices, "Connect to a server" |

A phone never acts as a server.

## Pair a device

The steps use a `pipedash-web` server and an iPhone. Android and the desktop app follow the same steps.

<Steps>
<Step>

### Start the server

Run `pipedash-web` and finish the setup wizard. The [Docker](/docs/deployment/docker) page has the Compose files. Behind a reverse proxy, the [Reverse proxy](/docs/deployment/reverse-proxy) page covers TLS and the WebSocket path.

Open the web app at the address the phone will use, such as `https://pipedash.example.com`. The pairing code carries the address of the open browser tab.

</Step>
<Step>

### Open Settings, Devices

Settings, Devices holds 2 cards on a server:

- **Push alerts:** the card "Push alerts for iPhone and iPad" with the switch "Send push alerts through relay.pipedash.app". It is off by default. The [Docker](/docs/deployment/docker#push-alerts-for-iphone-and-ipad) page covers it.
- **Paired devices:** the devices that show the pipelines of this server. It starts empty.

<Screenshot src="server-devices-empty" dir="docs/server-mode" alt="Settings, Devices on a server with the push relay switch on and an empty Paired devices card with an Add device button" caption="Settings, Devices before the first pairing." />

</Step>
<Step>

### Create a pairing code

Choose "Add device". The dialog shows these items:

| Item | What it holds |
|---|---|
| QR code | The pairing link, for the phone camera |
| Server address | The address of this server |
| Pairing code | 8 characters, such as `K7M2-Q9XA` |
| Pairing link | A link that starts with `pipedash://pair`, with a copy button |
| Countdown | "Code expires in 5:00" |

A code works once and expires after 5 minutes. The server keeps at most 8 open codes. Leave the dialog open while the phone connects.

<Screenshot src="server-add-device" dir="docs/server-mode" variant="dialog" alt="Add device dialog with a QR code, two instructions, the server address, the pairing code K7M2-Q9XA, a pairing link copy button and a 5 minute countdown" caption="The Add device dialog with the QR code and the code to type." />

</Step>
<Step>

### Choose Connect to a server on the phone

On the first start the app asks "Where should Pipedash run?". Choose "Connect to a server". "On this device" makes the phone poll the providers itself.

An existing install skips the question. Open Settings, Devices on the phone and choose "Connect to a server" there.

<Screenshot src="phone-welcome" dir="docs/server-mode" variant="mobile" alt="iPhone screen titled Where should Pipedash run with the options On this device and Connect to a server" caption="The first-run question on the iPhone." />

</Step>
<Step>

### Scan or type the code

Use one of these ways:

- Tap "Scan pairing code" and scan the QR code. The app asks for camera access the first time.
- Scan the QR code with the system camera. The link opens in Pipedash.
- Paste the pairing link into "Server address". The code field disappears.
- Type the server address and the pairing code.

Tap "Connect" to finish. On iOS, the first connection to a host on the local network also asks for Local Network access.

<Screenshot src="phone-connect" dir="docs/server-mode" variant="mobile" alt="Connect to a server screen with a Scan pairing code button, the server address https://pipedash.example.com, the pairing code K7M2-Q9XA and a Connect button" caption="The address and the code typed by hand, under the scan button." />

</Step>
<Step>

### Check the connection

The phone shows "Connected to pipedash.example.com" and the "Open dashboard" button. The dashboard then shows the pipelines of the server.

<Screenshot src="phone-connected" dir="docs/server-mode" variant="mobile" alt="Phone screen with a green check mark, the title Connected to pipedash.example.com and an Open dashboard button" caption="The phone after a successful pairing." />

At the same time the dialog on the server changes to "Ana's iPhone is connected." with a "Done" button. The name comes from the device.

<Screenshot src="server-device-paired" dir="docs/server-mode" variant="dialog" alt="Add device dialog with a green check mark, the text Ana's iPhone is connected and a Done button" caption="The server confirms the new device." />

</Step>
</Steps>

## Manage devices

Settings, Devices on the server lists each paired device with its platform, paired date and last connection. "Push alerts on" marks a phone that gets push alerts. The trash button removes a device after a confirmation. The server closes its connection at once, and the device shows "This device was removed".

<Screenshot src="server-devices" dir="docs/server-mode" alt="Paired devices card with Ana's iPhone, iOS, push alerts on, and build-mac-mini, macOS, each with a remove button" caption="Two paired devices on the server." />

On a paired phone, Settings, Devices shows "Shows pipelines from pipedash.example.com." and a "Disconnect" button. Disconnect tells the server to forget the phone. The phone marks its own row with "This device".

<Screenshot src="phone-devices" dir="docs/server-mode" variant="mobile" alt="Devices screen on a paired iPhone with Shows pipelines from pipedash.example.com, a Disconnect button, the unencrypted connections switch and the paired devices list" caption="Settings, Devices on a paired phone." />

A factory reset on the server removes every paired device.

## Share a desktop app

A desktop app can act as the server for phones and other computers on the same network.

1. Open Settings, Devices and turn on "Share on this network". The firewall can ask whether Pipedash may accept incoming connections. Allow it.
2. Choose "Add device" and follow the same steps as above.

The desktop app serves at `http://<lan-ip>:<port>` and shows the address next to "Sharing at". Keep the computer awake and Pipedash open. A new LAN address needs a new pairing. "Use a new port" changes the port, and every device must pair again. The [Desktop app](/docs/deployment/desktop#share-with-other-devices) page covers the details.

## Address rules

- `https` addresses always work.
- Plain `http` works only for a private network address, and only after "Allow unencrypted connections on private networks" is on in the app. The switch is off by default. Anyone on that network could read the pipelines and the access token of the device.
- A plain `http` address on the public internet is always refused.

The [Security](/docs/resources/security#private-http-policy) page lists the private address ranges.

## What a paired device can change

A paired device uses the providers, views and settings of the server. It cannot change the vault, setup, storage, push settings or factory reset of the server. The server answers `409` with `HOST_MANAGED`. A device can still remove itself and manage its own push registration.

## Alerts

The server records an alert when a pipeline fails or turns degraded, or when a run takes much longer than usual. A provider outage or recovery also raises one. The server records alerts only while at least one device is paired. Phones check for alerts in the background. With the push relay on, iPhone and iPad also get push alerts. The relay receives only an alert id, and the phone downloads the alert text from the server. The [Notifications](/docs/features/notifications#alerts-from-a-server) page covers the details.

## Troubleshooting

| Symptom | Cause | Fix |
|---|---|---|
| "Other devices can't reach this address" in the Add device dialog | The browser opened the server at `localhost` or another loopback address | Open the web app at its network address, or type that address on the phone |
| "This code expired." | 5 minutes passed | Choose "Create new code" |
| "This server doesn't use encryption" | The address uses plain `http` | Turn on "Allow unencrypted connections on private networks" for a trusted private network, or serve the server over `https` |
| "Couldn't connect" | The address or the code is wrong, or the code was already used | Check both and try again with a new code |
| "This device was removed" | The server removed the device | Choose "Set up again" and pair with a new code |
| The phone stops updating from a desktop | The desktop app closed, slept or changed its LAN address | Open Pipedash on the desktop. After an address change, pair again |
