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:
ACME mode (recommended for public internet)
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
| File | Goes to |
|---|---|
ca.crt | Both server and boat |
server.crt, server.key | Cloud server only |
boat-001.crt, boat-001.key | Boat 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 /healthzfor health checks (includes instance counts)GET /metricsfor Prometheus metrics (per-instance lag, cursor, holes)GET /instances/{id}/replication/eventsfor diagnostic event log