# Deploying the Relay client on Linux

> This page covers production setup details specific to Linux. For cross-platform prerequisites, networking requirements, see [Deploying the Relay client](deploying-relay-client.md).

This page covers production setup details specific to Linux. For cross-platform prerequisites, networking requirements, see [Deploying the Relay client](deploying-relay-client.md).

## Operating system requirements

The Relay client requires **systemd 229 or later**. To verify: `systemctl --version`.

| Distribution | Minimum version |
|---|---|
| Ubuntu | 20.04 LTS (Focal) |
| Debian | 10 (Buster) |
| Red Hat Enterprise Linux | 8 |
| Amazon Linux | 2023 |
| SUSE Linux Enterprise Server | 15 |
| Oracle Linux | 8 |

Any Linux distribution with systemd 229+ is expected to work. For environments without systemd, the Relay client can run in foreground mode (`--detach=false`), but you are responsible for process management, auto-start, and recovery.

**Required privileges:** `sudo` (root) access is needed to install systemd services (`/etc/systemd/system/`), create default data and log directories, and copy the binary to `/usr/local/bin/`. For rootless installations, see [User mode](#user-mode).

## Pre-installation checklist

### System

- [ ] Supported Linux distribution with systemd 229+
- [ ] `sudo` (root) access — or plan to use `--user-mode`
- [ ] Minimum 200 MB free disk space

### Network

- [ ] Outbound HTTPS (port 443) to `cloud.uipath.com` is allowed
- [ ] Outbound TLS (port 443) to `<region>-relay.uipath.com` is allowed
- [ ] TLS passthrough configured for the relay endpoint (no TLS inspection)
- [ ] Relay node has network access to all on-premises services you plan to expose

### Security

- [ ] SELinux / AppArmor / fapolicyd exclusions configured (if applicable) — see [Security frameworks](#security-frameworks)

### Configuration

- [ ] Relay Group created and client configuration string ready — see [Configuring a Relay group](configuring-relay-group.md)

#### Validation commands

```
# Check systemd version (must be 229+)
systemctl --version

# Verify sudo access
sudo -v

# Check available disk space
df -h /var/lib
```

## Install

### 1. Download and extract

| Architecture | Archive |
|---|---|
| x86_64 | [relay-linux-amd64.zip](https://download.uipath.com/relay/26.4.0/relay_linux_amd64.zip) |
| ARM64 | [relay-linux-arm64.zip](https://download.uipath.com/relay/26.4.0/relay_linux_arm64.zip) |

```
unzip relay-linux-amd64.zip && chmod +x relay
```

### 2. Start

You can provide the client configuration string (from UiPath Administration — see [Configuring a Relay group](configuring-relay-group.md)) in two ways:

**Option A — Inline.** Pass the configuration string directly. No file to create or clean up:

```
sudo ./relay start --config "<your-config>"
```

**Option B — File.** Save the configuration to a file, then reference it. Recommended — keeps the secret out of shell history:

```
sudo ./relay start --config-file /path/to/config.txt
```

> The `--config` and `--config-file` flags are mutually exclusive. To run in the foreground instead of as a background service (useful for debugging), pass `--detach=false`.

The Relay client validates connectivity, authenticates with OAuth, registers with Test Cloud, downloads proxy configuration, encrypts credentials, and installs a systemd service — all in a single command.

Expected output:

```
Running prerequisite checks...
  ✓ Directory permissions: OK
  ✓ Cloud portal connectivity: OK
✓ All prerequisite checks passed
Waiting for service to start...
  ✓ Service is running

✓ Relay is now running in the background.
Check status: systemctl status relay-<id>
```

> During startup, the Relay client automatically copies the binary to `/usr/local/bin/relay`. All relay groups on the machine share this single binary. Override the install directory with `--bin-dir`.

### 3. Verify

```
relay list
```

A healthy client shows `● running` in the STATUS column. The `ID` value shown is used in all subsequent commands (`relay stop <id>`, `relay logs <id>`, and so on). You can also find it in UiPath Administration under the relay group details page.

Confirm the tunnel is established by checking the logs for `login to server success`:

```
sudo relay logs <id> -f
```

## Manage

### List

Shows all installed relay groups on this machine with status and version. Does not require `sudo`.

```
relay list
relay list --json
```

### Stop

Stops the relay service. Configuration and logs are retained — the relay can be restarted later.

```
sudo relay stop <id>
```

### Restart and upgrade

Restarts the relay service and fetches the latest proxy configuration from Test Cloud.

```
sudo relay restart <id>
```

**Binary upgrade:** download the new `relay` binary and run `sudo ./relay restart <id>` from it. The restart command compares the running binary against the installed copy by SHA256 hash and updates the installed binary automatically if they differ.

| Scenario | Command |
|---|---|
| Endpoints added or removed in Test Cloud | `sudo relay restart <id>` |
| Client secret rotation — inline | `sudo relay restart --config "<new-config>"` |
| Client secret rotation — file | `sudo relay restart --config-file /path/to/new-config.txt` |
| Binary upgrade | Download new binary, then `sudo ./relay restart <id>` |

> When `--config` or `--config-file` is provided, the `<id>` argument is optional — it is extracted from the configuration.

### Delete

Stops the service, deregisters from Test Cloud, and removes all local configuration and log files.

```
sudo relay delete <id>
```

To force local cleanup without cloud deregistration — for example, if credentials are lost or the cloud-side relay group has already been deleted:

```
sudo relay delete <id> --force
```

### Version

```
relay version
```

> There is no auto-upgrade. To update, download the new binary and run `sudo ./relay restart <id>` for each group.

## Directory structure

All directories are created automatically on first run.

```
/usr/local/bin/
  relay                                      # Shared binary (755)

/var/lib/uipath-relay/                       # Data root (755)
  groups/<id>/
    client_config                            # OAuth credentials (encrypted, 600)
    metadata.json                            # State, PID, install timestamps (644)
    .credentials.key                         # AES-256-GCM encryption key (600)

/var/log/uipath-relay/                       # Logs root (755)
  logs/<id>/
    relay.log                                # Current log (644)
    relay.YYYYMMDD-HHMMSS.log                # Rotated logs (644)

/etc/systemd/system/
  relay-<id>.service                         # Systemd unit file
```

### File permissions

| Path | Mode | Reason |
|---|---|---|
| Directories | `755` | Relay read/write access |
| `client_config` | `600` | Contains encrypted OAuth credentials |
| `.credentials.key` | `600` | AES-256-GCM encryption key |
| `metadata.json` | `644` | Service metadata (state, PID, install timestamps) |
| `relay.log` | `644` | Readable for troubleshooting |
| Binary | `755` | Executable by systemd |

### Custom paths

Override the default directories at install time:

```
sudo ./relay start --config-file /path/to/config.txt \
  --bin-dir /opt/mycompany/bin \
  --data-dir /opt/mycompany \
  --logs-dir /opt/mycompany
```

| Flag | Default | Description |
|---|---|---|
| `--bin-dir` | `/usr/local/bin` | Directory for the shared binary |
| `--data-dir` | `/var/lib` | Root for configuration data |
| `--logs-dir` | `/var/log` | Root for log files |

The Relay client appends `uipath-relay/` under the custom data and log roots:

```
--bin-dir  /opt/mycompany/bin  =>  /opt/mycompany/bin/relay
--data-dir /opt/mycompany      =>  /opt/mycompany/uipath-relay/groups/<id>/
--logs-dir /opt/mycompany      =>  /opt/mycompany/uipath-relay/logs/<id>/
```

> `--bin-dir`, `--data-dir`, and `--logs-dir` are only accepted by the `start` command. Other commands (`stop`, `restart`, `delete`, `list`) derive paths automatically from the installed service configuration.

## Proxy configuration

If your network routes outbound traffic through a proxy, export the proxy environment variables **before** running `relay start`. Use `sudo -E` to preserve the environment when elevating:

```
export HTTPS_PROXY="http://proxy.corp.example.com:8080"
export NO_PROXY="localhost,127.0.0.1,.corp.example.com"
sudo -E ./relay start --config "<your-config>"
```

Without `-E`, `sudo` resets the environment and proxy settings are lost.

The Relay client writes the captured proxy variables as `Environment=` directives in the systemd unit file, so the background service uses them — not system-wide `/etc/environment`.

**To update the proxy after installation:** export the new values and run `sudo -E relay restart <id>`.

**To remove the proxy:** `unset HTTPS_PROXY HTTP_PROXY NO_PROXY`, then `sudo relay restart <id>`.

**To verify what the service uses:** `systemctl cat relay-<id> | grep -i environment`.

For supported proxy schemes and authentication, see the proxy section in [Deploying the Relay client](deploying-relay-client.md#configure-a-proxy-if-applicable).

## Security frameworks

If your environment uses SELinux, AppArmor, or fapolicyd, ensure the Relay client binary and its data directories are permitted.

### SELinux

```
# Check enforcement mode
getenforce

# Relabel the binary if a custom policy blocks it
sudo semanage fcontext -a -t bin_t '/usr/local/bin/relay'
sudo restorecon -v /usr/local/bin/relay
```

## AppArmor

Ensure no profile restricts `/usr/local/bin/relay` from network access or file writes to `/var/lib/uipath-relay/` and `/var/log/uipath-relay/`. If you use custom paths, substitute accordingly.

## fapolicyd

```
sudo fapolicyd-cli --file add /usr/local/bin/relay
sudo fapolicyd-cli --update
```

## Paths to allow

| Type | Default path |
|---|---|
| Binary | `/usr/local/bin/relay` |
| Data | `/var/lib/uipath-relay/` |
| Logs | `/var/log/uipath-relay/` |

If you used `--bin-dir`, `--data-dir`, or `--logs-dir`, allow those custom paths instead.

## User mode

User mode (`--user-mode`) installs the Relay client as a **systemd user service** instead of a system service, allowing it to run without `sudo`. This is suitable for shared machines and restricted environments where root access is unavailable.

### Requirements

| Requirement | Details |
|---|---|
| systemd 229+ | Verify: `systemctl --version` |
| Home directory | Must exist and be owned by the target user |
| systemd user session | Verify: `systemctl --user is-system-running` returns `running` or `degraded` |
| SSH login | Required — `su` / `sudo su` do not provide the D-Bus session that user services need |
| `loginctl linger` | Required for the service to persist after logout and start at boot |

**Enable linger** (one-time, requires admin):

```
sudo loginctl enable-linger <username>
```

Without linger, user services stop when you log out and do not start at boot.

### Start in user mode

```
./relay start --user-mode --config-file /path/to/config.txt
```

### User mode directory layout

```
~/.local/bin/
  relay                                      # Shared binary (755)

~/.local/share/uipath-relay/
  groups/<id>/
    client_config                            # OAuth credentials (encrypted, 600)
    metadata.json                            # Service metadata (644)
    .credentials.key                         # Encryption key (600)
  logs/<id>/
    relay.log
    relay.YYYYMMDD-HHMMSS.log

~/.config/systemd/user/
  relay-<id>.service                         # Systemd user unit file
```

The `~/.config/systemd/user/` path cannot be overridden. Binary, data, and log paths can be customized with `--bin-dir`, `--data-dir`, and `--logs-dir`.

### Management commands in user mode

All commands work without `sudo`:

```
relay list
relay stop <id>
relay restart <id>
relay delete <id>
relay logs <id> -f
```

### When to use user mode

| Scenario | Recommended |
|---|---|
| Production server with root access | System mode (default) |
| Shared machine, no root access | User mode |
| Development or testing | User mode |
| Security-sensitive environments | System mode (tamper-proof binary path) |

## Uninstall

1. Delete all Relay clients (use `relay list` to see installed groups):

   ```
   sudo relay delete <id>
   ```

2. Remove the shared binary:

   ```
   sudo rm /usr/local/bin/relay
   ```

3. Remove remaining data and log directories:

   ```
   sudo rm -rf /var/lib/uipath-relay /var/log/uipath-relay
   ```

For user mode, replace the commands with the user-mode equivalents (no `sudo`) and remove `~/.local/bin/relay` and `~/.local/share/uipath-relay`.

## Troubleshooting

| Symptom | Cause | Resolution |
|---|---|---|
| Service fails to start | Insufficient permissions | Run with `sudo` |
| `permission denied` | Cannot create directories | Verify `sudo` access, or use custom paths to a writable location |
| `systemctl: command not found` | systemd not installed | Use foreground mode (`--detach=false`) or install systemd |
| Service starts then stops immediately | Configuration or network error | Check `relay.log` for startup errors |
| Service running but tunnel not established | Network or authentication issue | Check `relay.log` for `login to server` errors; verify TLS passthrough |
| SELinux or AppArmor blocking execution | Security framework policy | See [Security frameworks](#security-frameworks) |
| `XDG_RUNTIME_DIR not found` (user mode) | Not logged in via SSH | Log in via SSH, or enable linger |
| `D-Bus session bus unreachable` (user mode) | Not logged in via SSH | Log in via SSH, or enable linger |
| Proxy not used by service | Variable not captured at start | Re-run with `sudo -E`, or verify with `systemctl cat relay-<id> \| grep -i environment` |
| High CPU or memory | Log level set to `trace` or `debug` | Set log level to `info` or higher |

### Diagnostic commands

```
# Real-time logs
sudo relay logs <id> -f

# Systemd journal
journalctl -u relay-<id> -f

# Service status
systemctl status relay-<id>

# Connectivity test
nc -zv <region>-relay.uipath.com 443

# Check if binary is blocked by SELinux
sudo ausearch -m AVC -ts recent

# Check AppArmor status
sudo aa-status
```

For authentication and connectivity errors shared across platforms, see [Troubleshooting](relay-troubleshooting.md).

## Quick reference

| Action | Command |
|---|---|
| Start | `sudo relay start --config-file config.txt` |
| Stop | `sudo relay stop <id>` |
| Restart / upgrade | `sudo relay restart <id>` |
| Delete | `sudo relay delete <id>` |
| Delete (force) | `sudo relay delete <id> --force` |
| List | `relay list` |
| Logs | `relay logs <id> -f` |
| Service status | `systemctl status relay-<id>` |
| Systemd journal | `journalctl -u relay-<id> -f` |
