Skip to main content

Self-Hosting lplex-cloud

Run your own cloud server to receive data from one or more boats.

Build

go build -o lplex-cloud ./cmd/lplex-cloud

Or use the Docker image:

docker pull ghcr.io/sixfathoms/lplex-cloud

Network modes

lplex-cloud supports two deployment modes:

A single port handles both gRPC (mTLS for boats) and HTTP (for clients). TLS certificates are automatically provisioned via Let's Encrypt.

listen = ":443"
acme {
domain = "lplex.example.com"
email = "admin@example.com"
}
tls {
client-ca = "/etc/lplex-cloud/ca.crt"
}
data-dir = "/data/lplex"

Dual-port mode (for private networks)

Separate gRPC and HTTP listeners. You provide your own TLS certificates.

grpc {
listen = ":9443"
tls {
cert = "/etc/lplex-cloud/server.crt"
key = "/etc/lplex-cloud/server.key"
client-ca = "/etc/lplex-cloud/ca.crt"
}
}
http {
listen = ":8080"
}
data-dir = "/data/lplex"

mTLS certificate setup

Both the server and each boat need TLS certificates signed by the same CA. The boat's certificate CN must match its replication-instance-id.

Create a CA

# Generate CA key
openssl ecparam -genkey -name prime256v1 -out ca.key

# Generate CA certificate (10 years)
openssl req -new -x509 -key ca.key -out ca.crt -days 3650 \
-subj "/CN=lplex CA"

Create server certificate

# Generate server key
openssl ecparam -genkey -name prime256v1 -out server.key

# Create CSR
openssl req -new -key server.key -out server.csr \
-subj "/CN=lplex.example.com"

# Sign with CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365 \
-extfile <(echo "subjectAltName=DNS:lplex.example.com")

Create boat certificate

The CN must match the instance ID:

# Generate boat key
openssl ecparam -genkey -name prime256v1 -out boat-001.key

# Create CSR (CN = instance ID)
openssl req -new -key boat-001.key -out boat-001.csr \
-subj "/CN=boat-001"

# Sign with CA
openssl x509 -req -in boat-001.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out boat-001.crt -days 365

Distribute certificates

FileGoes to
ca.crtBoth server and boat
server.crt, server.keyCloud server only
boat-001.crt, boat-001.keyBoat only

Data directory

The -data-dir directory stores instance state and journal files:

/data/lplex/
├── boat-001/
│ ├── state.json # Replication state (cursor, holes)
│ ├── nmea2k-20260306T101500Z.lpj
│ └── nmea2k-20260306T111500Z.lpj
├── boat-002/
│ ├── state.json
│ └── ...

Ensure the directory exists and has appropriate permissions.

Systemd

[Unit]
Description=lplex-cloud
After=network.target

[Service]
ExecStart=/usr/local/bin/lplex-cloud -config /etc/lplex-cloud/lplex-cloud.conf
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Retention and archival

lplex-cloud uses the same retention and archival system as lplex. A single JournalKeeper goroutine manages all instance directories.

See Retention & Archival for configuration details. The same flags and HOCON paths apply.

Monitoring

  • GET /healthz for health checks (includes instance counts)
  • GET /metrics for Prometheus metrics (per-instance lag, cursor, holes)
  • GET /instances/{id}/replication/events for diagnostic event log