Quickstart
This guide takes you from zero to live telemetry on a single Linux host in about 10 minutes. By the end, you’ll have the LinkMesh server running, one enrolled collector reporting in, an active source, and a route forwarding events to the destination of your choice.
Prerequisites
Section titled “Prerequisites”- One Linux host with
sudo(Ubuntu 22.04 LTS, RHEL 9, or another systemd-based distribution) - 1 vCPU, 1 GB RAM, 5 GB disk is plenty for the server itself
- Outbound HTTPS access to
artifacts.saas.opensight.ch(for the install package) - Open port
8080on the host so you can reach the web UI from your browser - Optional: a Grafana Cloud Loki endpoint + write token if you want to verify end-to-end delivery
1. Install the LinkMesh server
Section titled “1. Install the LinkMesh server”Install runs in one shell session. The package ships a systemd unit, a default
admin account, and a gitops-backed config store. The server keeps its state in
an embedded database by default, so a single-host install needs no external
database. It serves plain HTTP on port 8080; TLS is terminated by a reverse
proxy or ingress in front (covered below).
curl -fsSL https://artifacts.saas.opensight.ch/binaries/linkmesh-server/latest/linkmesh-server_latest_amd64.deb -o linkmesh-server.deb
sudo apt install ./linkmesh-server.debcurl -fsSL https://artifacts.saas.opensight.ch/binaries/linkmesh-server/latest/linkmesh-server-latest.x86_64.rpm -o linkmesh-server.rpm
sudo dnf install ./linkmesh-server.rpmdocker run -d --name linkmesh-server \
-p 8080:8080 \
-e AUTH_ADMIN_PASSWORD='choose-a-strong-password' \
-v linkmesh-data:/data \
docker.io/opensight/linkmesh-server:latestSet AUTH_ADMIN_PASSWORD on that first run to choose the admin account’s
password up front — the container starts with it already in place.
Mount the whole /data directory, not a subpath — all durable state lives
under it: the embedded database (/data/linkmesh/state.db), the GitOps config
clones (/data/linkmesh-config/), and the auto-generated secrets encryption
key (/data/linkmesh/secrets.key). Persisting only a subdirectory loses your
destinations, users, and secrets on the next container recreate. Everything is
served on the single HTTP port 8080 — the web UI, the REST API, the agent
control channel (a WebSocket at /v1/agent), and OTLP ingest. In production,
TLS is terminated by your ingress / reverse proxy in front of it.
The install starts the server right away and creates an admin account whose
random password is deliberately never written to any log. For the package
installs above, set your own password with the recovery command — it needs no
prior login, and works whether or not the server is running:
sudo linkmesh-server reset-password --email admin --password 'choose-a-strong-password'
Omit --password to have a strong one generated and printed. Resetting a
password signs that account out of any sessions it already had. (The Docker
install already set AUTH_ADMIN_PASSWORD above, so you can skip this step
there.)
2. Tell LinkMesh its public URL
Section titled “2. Tell LinkMesh its public URL”Set externalUrl to the address collectors and browsers reach this server
on, then restart. This is the one post-install setting you should not skip.
Edit /etc/linkmesh/config.yaml:
# A DNS name (preferred — survives IP changes, and matches your TLS cert)
externalUrl: "https://linkmesh.example.com"# Or a bare IP, for a lab / flat-network install with no TLS in front
externalUrl: "http://192.0.2.10:8080"Then restart:
sudo systemctl restart linkmesh-serverSet it in the environment instead — LINKMESH_EXTERNALURL, or its shorter
alias EXTERNAL_URL:
docker run -d --name linkmesh-server \
-p 8080:8080 \
-e LINKMESH_EXTERNALURL='https://linkmesh.example.com' \
-e AUTH_ADMIN_PASSWORD='choose-a-strong-password' \
-v linkmesh-data:/data \
docker.io/opensight/linkmesh-server:latestUse the address collectors resolve — an Ingress hostname or a Service DNS
name like http://linkmesh-server.linkmesh.svc.cluster.local:8080, never a
pod IP.
3. Sign in
Section titled “3. Sign in”Open http://<your-host>:8080 in a browser. Sign in as admin with the
password you set in the previous step.
4. Enroll your first collector
Section titled “4. Enroll your first collector”Open Collectors in the sidebar. The list starts empty.
Click + Add Collector and pick a collector runtime — Grafana Alloy
(config via remotecfg) or otelcol-contrib + OpAMP (config pushed via
OpAMP). This walkthrough uses Alloy. The wizard creates an enrollment token and
shows the install commands to run on the host you want to monitor. Copy them,
SSH into the target host, and run them as root.
You install upstream Grafana Alloy from its OS package, then drop in a small
bootstrap config — a remotecfg block pointing at your server plus a
per-collector Bearer token from the wizard. On its first poll, Alloy enrols and
fetches its real pipeline config from the server directly; within ~10 seconds
the collector appears in the dashboard’s fleet table. See
Add a collector for the full per-runtime
templates and the otelcol-contrib + OpAMP alternative.
5. Activate a source
Section titled “5. Activate a source”Click into your new collector. Switch to the Inputs tab.
Click + Add Input to open the source library. Pick a receiver type that matches what you want to ingest — syslog, OTLP, file tail, journald, Kafka, or anything else in the library.
Pick Syslog for this walkthrough — it accepts UDP traffic on port 5514 with no further configuration. The activation is saved as soon as you confirm, and the collector picks up the new config on its next heartbeat (typically within a few seconds).
6. Add a destination
Section titled “6. Add a destination”Switch to the Destinations tab on the collector detail page, or open the Destinations library in the sidebar. Click + New Destination and pick an exporter type. Common choices:
- Debug — logs records to the collector’s own stdout. Zero credentials. Useful for the first end-to-end verification.
- Grafana Cloud Loki — push logs to a Loki tenant. Needs an endpoint and a write token (free tier works).
- OTLP — send to any OpenTelemetry-compatible backend.
For this walkthrough, Debug is the fastest path to “I can see events flowing.” Save the destination, then return to the collector detail page.
7. Wire a route
Section titled “7. Wire a route”Switch to the Routing tab. A route is the matcher that ties a source to a destination through an optional processing pipeline.
Click + Create new Route. Pick the syslog source as input, leave the pipeline empty (no transformation), pick the Debug destination as output. Save.
The collector picks up the change within a few seconds. Generate test traffic from any host that can reach the collector on port 5514:
logger -d -n <collector-host> -P 5514 "hello from quickstart"
8. See it work
Section titled “8. See it work”Back on the dashboard, the Throughput card ticks within ~30 seconds.
The Fleet Status table shows your collector with current status, type, and last-seen timestamp — refreshed live as heartbeats land.
If you wired a real backend (Loki, ClickHouse, OTLP), check your downstream
tool to confirm records are arriving. The Debug destination just logs to the
collector’s journal — sudo journalctl -u alloy on the collector host shows
the records as they flow through.
What’s next
Section titled “What’s next”- Install on Kubernetes — if your collector hosts live in a K8s cluster, use the DaemonSet flow instead of the VM install above
- Concepts — what each entity (Collector, Source, Pipeline, Route, Destination) actually means and how they relate
- Drop noisy logs — strip health-check noise before it reaches your destination
- Mask PII — redact email addresses, phone numbers, and card patterns with one processor step
- Route to Grafana Cloud Loki — wire the destination you most likely already have running
If something didn’t work, open the Events feed on the dashboard — every config push, heartbeat, and error is logged there with context.