Relay Last verified:

Run Relay with Docker

Deploy Viaalink Relay and Caddy reverse proxy using Docker Compose with automatic HTTPS.

Container deployment overview

The Viaalink Relay container image (viaalink/relay, for amd64 and arm64) is published with the first release — ask contact@viaalink.com for early access. The Docker Compose setup below is what you will run once the image is published.

In production, running Viaalink Relay behind Caddy provides automatic Let’s Encrypt certificate issuance, wildcard subdomain management, and HTTP/3 support while Relay manages SSH reverse tunnels and routing.

Prerequisites

  • Docker Engine 24.0+ and Docker Compose v2.0+.
  • Domain with DNS pointing to your host server (see DNS Configuration):
    • relay.example.com (A / AAAA)
    • *.relay.example.com (A / AAAA or CNAME)
  • Open ports on your firewall or router: 80/tcp, 443/tcp, 2222/tcp, and optionally 3478/udp.

Deployment files

Create a dedicated directory on your server (for example /opt/viaalink-relay) containing the following configuration files:

bash

1. Caddy build with DNS-01 provider plugins (Dockerfile.caddy)

Issuing Let’s Encrypt wildcard certificates (*.relay.example.com) requires ACME DNS-01 validation. Because the stock caddy:2-alpine image does not bundle DNS provider plugins, build a small Caddy image with xcaddy including the five supported DNS providers:

Create Dockerfile.caddy:

dockerfile

2. Docker Compose file (docker-compose.yml)

Create docker-compose.yml (note that ./data/config.yml is mounted writable so changes saved in /_relay/dashboard persist to disk, and VIAALINK_RELAY_LICENSE_KEY_FILE points to /app/deploy/license/license.jwt):

yaml

3. Caddy reverse proxy configuration (Caddyfile)

Create Caddyfile in the same directory with the tls DNS-01 challenge block for your DNS provider (Cloudflare shown below):

nginx

4. Initial Relay configuration (data/config.yml)

Create data/config.yml:

yaml

Starting the stack

Build and start both containers in detached mode:

bash

Check the status of running containers:

bash

View the Relay server logs to verify startup and retrieve the initial setup code:

bash

Open the setup dashboard at https://relay.example.com/_relay/dashboard?x-authorization=<setup-code> (or http://<server-ip>:8080/_relay/dashboard?x-authorization=<setup-code> if port 8080 is exposed on your LAN).

Persistent volumes and storage

All critical persistent state is preserved in the ./data directory on the host:

Host DirectoryContainer PathPurpose
./data/keys//app/deploy/keysServer SSH private host keys (generated on first boot)
./data/pubkeys//app/deploy/pubkeysAuthorized client SSH public keys
./data/ssl//app/deploy/sslCustom SSL certificates and keys
./data/license//app/deploy/licenseLicense file (license.jwt) and setup-token.txt
./data/config.yml/app/config.ymlWritable Relay configuration file (updated by /_relay/dashboard)
caddy-data volume/dataCaddy Let’s Encrypt certificates and account keys

DNS-01 provider credentials

When configuring the tls { dns ... } directive in Caddyfile (or when Relay drives a bundled Caddy binary with --caddy-https-enabled=true), use the environment variables for your provider:

ProviderCaddyfile dns directiveEnvironment Variables
Porkbundns porkbun { api_key {env.PORKBUN_API_KEY} api_secret_key {env.PORKBUN_API_SECRET_KEY} }PORKBUN_API_KEY, PORKBUN_API_SECRET_KEY
Cloudflaredns cloudflare {env.CLOUDFLARE_API_TOKEN}CLOUDFLARE_API_TOKEN
AWS Route53dns route53 { access_key_id {env.AWS_ACCESS_KEY_ID} secret_access_key {env.AWS_SECRET_ACCESS_KEY} region {env.AWS_REGION} }AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
DigitalOceandns digitalocean {env.DIGITALOCEAN_API_TOKEN}DIGITALOCEAN_API_TOKEN
GoDaddydns godaddy {env.GODADDY_API_TOKEN}GODADDY_API_TOKEN

Upgrading

To update Viaalink Relay and Caddy to the latest releases:

bash

Existing client connections will automatically reconnect when the new container starts.

Verifying health

Operational health is verified when:

  1. Port 2222 responds to SSH connections:
    bash
  2. Your browser reaches https://relay.example.com/_relay/dashboard or a published test application over HTTPS.

Next steps