- Erste Schritte
- Datensicherheit und Compliance
- Organisationen
- Authentifizierung und Sicherheit
- Lizenzierung
- Über die Lizenzierung
- Einheitliche Preise: Lizenzierungsplan-Framework
- Aktivieren Ihrer Enterprise-Lizenz
- Migrieren von Test Suite zu Test Cloud
- Lizenzmigration
- Zuweisen von Lizenzen zu Mandanten
- Zuweisen von Benutzerlizenzen
- Freigegeben von Benutzerlizenzen
- Überwachung der Lizenzzuweisung
- Lizenzüberzuweisung
- Lizenzierungsbenachrichtigungen
- Benutzerlizenzverwaltung
- Mandanten und Dienste
- Konten und Rollen
- AI Trust Layer
- Externe Anwendungen
- Benachrichtigungen
- Protokollierung
- Tests in Ihrer Organisation
- Fehlersuche und ‑behebung
- Migration zur Test Cloud
Test Cloud-Administratorhandbuch
Run the Relay client as a container image to establish secure outbound tunnels to Test Cloud from containerized environments. Before you begin, configure a Relay Group and have the client configuration string ready from the Relay UI.
Voraussetzungen
- Container runtime: Podman, Docker, or a Kubernetes cluster.
- Relay client container image:
registry.uipath.com/relay-client:<tag>. - A base64-encoded configuration file generated from the Relay UI.
- License agreement acceptance: set
LICENSE_AGREEMENT=acceptas an environment variable, or append--accept-license-agreementto the start command. - (Optional) A custom CA certificate if your organization uses enterprise PKI.
For hardware and network requirements, refer to Deploying the Relay client.
Step 1: Get the configuration
- Open the Relay UI dashboard.
- Create or copy your relay configuration.
- Save the base64-encoded configuration string provided by the UI.
Step 2: Configure environment variables
Custom CA certificate
If your organization uses a corporate or self-signed CA, set the following variables together before starting the container:
| Variable | Zweck | Erforderlich |
|---|---|---|
RELAY_CUSTOM_CA_PATH | Path to the custom CA certificate | Nein |
RELAY_CA_BUNDLE_PATH | Path where the merged CA bundle is written | Yes, if using custom CA |
The Relay client merges the custom CA with the system certificate bundle before establishing any TLS connections. Both variables must be set together.
Proxy
To route outbound traffic through a proxy:
| Variable | Zweck | Erforderlich |
|---|---|---|
HTTP_PROXY und HTTPS_PROXY | Proxy URL | Nein |
NO_PROXY | Comma-separated hostnames, domains, or IP addresses that bypass the proxy | Nein |
Step 3: Deploy
Podman
For high availability, run two containers on separate nodes with distinct names. Replace <RELAY_ID> with the actual ID from the Relay UI — for example, run relay1-<RELAY_ID> on host1 and relay2-<RELAY_ID> on host2.
Quick start:
# Create a config file with the base64-encoded content from the Relay UI
echo "YOUR_BASE64_CONFIG_HERE" > /tmp/relay_config
# Run the container
podman run -it --name relay1-<RELAY_ID> --hostname relay1-<RELAY_ID> --rm \
--read-only --read-only-tmpfs \
-v /tmp/relay_config:/relay.config.b64enc:z \
-e LICENSE_AGREEMENT=accept \
registry.uipath.com/relay-client:<tag> \
start --config-file /relay.config.b64enc --accept-license-agreement
# Create a config file with the base64-encoded content from the Relay UI
echo "YOUR_BASE64_CONFIG_HERE" > /tmp/relay_config
# Run the container
podman run -it --name relay1-<RELAY_ID> --hostname relay1-<RELAY_ID> --rm \
--read-only --read-only-tmpfs \
-v /tmp/relay_config:/relay.config.b64enc:z \
-e LICENSE_AGREEMENT=accept \
registry.uipath.com/relay-client:<tag> \
start --config-file /relay.config.b64enc --accept-license-agreement
With a custom CA certificate:
podman run -it --name relay1-<RELAY_ID> --hostname relay1-<RELAY_ID> --rm \
--read-only --read-only-tmpfs \
-v /tmp/relay_config:/relay.config.b64enc:z \
-v /tls/custom-ca.crt:/custom-ca.crt:z \
-v /tmp/writable:/writable:z \
-e RELAY_CUSTOM_CA_PATH=/custom-ca.crt \
-e RELAY_CA_BUNDLE_PATH=/writable/merged-ca.crt \
registry.uipath.com/relay-client:<tag> \
start --config-file /relay.config.b64enc --accept-license-agreement
podman run -it --name relay1-<RELAY_ID> --hostname relay1-<RELAY_ID> --rm \
--read-only --read-only-tmpfs \
-v /tmp/relay_config:/relay.config.b64enc:z \
-v /tls/custom-ca.crt:/custom-ca.crt:z \
-v /tmp/writable:/writable:z \
-e RELAY_CUSTOM_CA_PATH=/custom-ca.crt \
-e RELAY_CA_BUNDLE_PATH=/writable/merged-ca.crt \
registry.uipath.com/relay-client:<tag> \
start --config-file /relay.config.b64enc --accept-license-agreement
Start command options:
| Option | Beschreibung | Beispiel |
|---|---|---|
--config | Inline base64 configuration string | --config "base64string..." |
--config-file | Path to the configuration file | --config-file /relay.config.b64enc |
--log-level | Logging verbosity: trace, debug, info, warn, or error | --log-level debug |
--heartbeat-interval | Heartbeat interval in seconds (minimum: 10) | --heartbeat-interval 10 |
--reconnect-interval | Reconnect interval in seconds (minimum: 1800) | --reconnect-interval 1800 |
Kubernetes
Create secrets:
# Configuration secret
kubectl create secret generic relay-config \
--from-file=relay.conf=/tmp/relay_config
# Custom CA certificate secret (optional)
kubectl create secret generic custom-ca \
--from-file=custom-ca.crt=./custom-ca.crt
# Headless service for the StatefulSet
kubectl create service clusterip relay-client-<RELAY_ID> --clusterip="None"
# Configuration secret
kubectl create secret generic relay-config \
--from-file=relay.conf=/tmp/relay_config
# Custom CA certificate secret (optional)
kubectl create secret generic custom-ca \
--from-file=custom-ca.crt=./custom-ca.crt
# Headless service for the StatefulSet
kubectl create service clusterip relay-client-<RELAY_ID> --clusterip="None"
Deploy a StatefulSet:
Use a StatefulSet when hostname restrictions are enforced. StatefulSets provide stable, predictable hostnames (relay-client-0, relay-client-1, and so on), which the Relay service uses to identify and validate clients.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: relay-client-<RELAY_ID>
spec:
serviceName: relay-client-<RELAY_ID>
replicas: 2
selector:
matchLabels:
app: relay-client-<RELAY_ID>
template:
metadata:
labels:
app: relay-client-<RELAY_ID>
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- relay-client-<RELAY_ID>
topologyKey: "kubernetes.io/hostname"
containers:
- name: relay
image: registry.uipath.com/relay-client:<tag>
args:
- start
- --config-file=/config/relay.conf
- --accept-license-agreement
- --log-level=info
- --heartbeat-interval=30
env:
- name: RELAY_CUSTOM_CA_PATH
value: "/tls/custom-ca.crt"
- name: RELAY_CA_BUNDLE_PATH
value: "/writable/merged-ca.crt"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1001
runAsNonRoot: true
runAsUser: 1001
readinessProbe:
httpGet:
path: /healthz
port: 9090
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 3
successThreshold: 1
failureThreshold: 2
resources:
requests:
cpu: 50m
memory: 100Mi
volumeMounts:
- name: relay-config
mountPath: /config/relay.conf
subPath: relay.conf
readOnly: true
- mountPath: /writable
name: writable
- name: custom-ca
mountPath: /tls/custom-ca.crt
subPath: custom-ca.crt
readOnly: true
volumes:
- name: relay-config
secret:
secretName: relay-config
- name: writable
emptyDir: {}
- name: custom-ca
secret:
secretName: custom-ca
restartPolicy: Always
terminationGracePeriodSeconds: 30
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: relay-client-<RELAY_ID>
spec:
serviceName: relay-client-<RELAY_ID>
replicas: 2
selector:
matchLabels:
app: relay-client-<RELAY_ID>
template:
metadata:
labels:
app: relay-client-<RELAY_ID>
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- relay-client-<RELAY_ID>
topologyKey: "kubernetes.io/hostname"
containers:
- name: relay
image: registry.uipath.com/relay-client:<tag>
args:
- start
- --config-file=/config/relay.conf
- --accept-license-agreement
- --log-level=info
- --heartbeat-interval=30
env:
- name: RELAY_CUSTOM_CA_PATH
value: "/tls/custom-ca.crt"
- name: RELAY_CA_BUNDLE_PATH
value: "/writable/merged-ca.crt"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsGroup: 1001
runAsNonRoot: true
runAsUser: 1001
readinessProbe:
httpGet:
path: /healthz
port: 9090
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 3
successThreshold: 1
failureThreshold: 2
resources:
requests:
cpu: 50m
memory: 100Mi
volumeMounts:
- name: relay-config
mountPath: /config/relay.conf
subPath: relay.conf
readOnly: true
- mountPath: /writable
name: writable
- name: custom-ca
mountPath: /tls/custom-ca.crt
subPath: custom-ca.crt
readOnly: true
volumes:
- name: relay-config
secret:
secretName: relay-config
- name: writable
emptyDir: {}
- name: custom-ca
secret:
secretName: custom-ca
restartPolicy: Always
terminationGracePeriodSeconds: 30
Verify the deployment:
kubectl get statefulset relay-client-<RELAY_ID>
kubectl get statefulset relay-client-<RELAY_ID>
Betrieb
Configuration details
The configuration file must contain the base64-encoded JSON string generated by the Relay UI. On startup, the Relay client reads the configuration, decodes it, validates it, and connects to the specified relay service endpoint.
- First run: Configuration is stored encrypted in the data directory.
- Subsequent runs: The encrypted configuration is automatically decrypted and used.
- Config file changes: Require a container restart to take effect.
Heartbeat interval
The heartbeat keeps idle TCP connections alive. Lower the interval if your firewall, proxy, or network address translation (NAT) drops idle connections before 30 seconds:
--heartbeat-interval=30 # Default
--heartbeat-interval=10 # For aggressive firewall or NAT environments
--heartbeat-interval=30 # Default
--heartbeat-interval=10 # For aggressive firewall or NAT environments
Reconnect interval
Proactive reconnect re-establishes the connection on a fixed schedule. Use this in environments where a proxy or load balancer has an idle-connection timeout:
--reconnect-interval=0 # Disabled (default)
--reconnect-interval=1800 # Reconnect every 30 minutes (minimum)
--reconnect-interval=0 # Disabled (default)
--reconnect-interval=1800 # Reconnect every 30 minutes (minimum)
Accessing logs
# Podman
podman logs -f relay1
# Kubernetes (current run)
kubectl logs -f relay-client-0
# Kubernetes (previous run, if the container restarted)
kubectl logs relay-client-0 --previous
# Podman
podman logs -f relay1
# Kubernetes (current run)
kubectl logs -f relay-client-0
# Kubernetes (previous run, if the container restarted)
kubectl logs relay-client-0 --previous
Sicherheit
Apply the following security settings in your container manifest:
readOnlyRootFilesystem: true— prevents modification of the container filesystem.runAsNonRoot: true— runs the process as a non-root user.allowPrivilegeEscalation: false— prevents privilege escalation.capabilities.drop: [ALL]— drops all Linux capabilities.privileged: false— disables privileged mode.
Store relay configuration in Kubernetes secrets and use role-based access control (RBAC) to restrict secret access. Do not embed the base64 configuration in the container image or pass it as a plain environment variable.
Fehlersuche und ‑behebung
| Symptome | Ursache | Resolution |
|---|---|---|
license agreement not accepted on startup | License flag or variable not set | Add --accept-license-agreement to the start command, or set LICENSE_AGREEMENT=accept |
| Configuration file not found | Incorrect volume mount path or secret | Run kubectl describe secret relay-config and kubectl describe pod <pod-name> to verify mounts |
| Cannot connect to relay service | Network or firewall issue | Check pod logs with kubectl logs <pod-name> and verify outbound connectivity to <region>-relay.uipath.com:443 |
| Custom CA merge failed | CA environment variables not both set | Set both RELAY_CUSTOM_CA_PATH and RELAY_CA_BUNDLE_PATH together |
| Hostname not recognized by relay service | Pod name is random (standalone Pod, not StatefulSet) | Use a StatefulSet instead of a standalone Pod |
| x509 certificate errors | Invalid or inaccessible CA certificate | Verify the certificate format with openssl x509 -in custom-ca.crt -text -noout and check file permissions |