How I Built a One-Command Observability Stack for Dokploy
Source: Dev.to

The Problem
Setting up proper observability is painful:
- Grafana, Tempo, Loki, and collectors each need separate configuration.
- Getting them to talk to each other requires networking magic.
- OpenTelemetry setup has a steep learning curve.
- Most tutorials assume you have infinite time to debug YAML.
- Dokploy’s Docker network adds another layer of complexity.
The Solution: Dokploy Grafana Compose
A pre‑configured monitoring stack that deploys alongside your Dokploy apps. Four services, one docker compose up, done.
# All four services on dokploy-network, pre‑wired
services:
alloy: # Collects traces, logs, metrics
tempo: # Stores traces
loki: # Stores logs
grafana: # Visualizes everything
Your apps send telemetry to Alloy, and everything flows to the right place automatically.
How It Works
- Alloy receives data – OTLP receiver on ports
4317/4318accepts traces, logs, and metrics from your apps. - Data routes automatically – Traces go to Tempo, logs go to Loki, metrics go to Prometheus.
- Grafana correlates everything – See a slow request? Jump from trace to related logs instantly.
- Faro captures frontend – Browser‑side Real User Monitoring included on port
12347.
No configuration files to edit. Just deploy and instrument your apps.
Get Started in 30 Seconds
git clone https://github.com/quochuydev/dokploy-grafana-compose.git
cd dokploy-grafana-compose
docker compose up -d
This deploys:
- Grafana Alloy v1.11.3 – Unified telemetry collector with OTLP and Faro receivers.
- Tempo v2.9.0 – Distributed tracing backend.
- Loki v3.5.8 – Log aggregation system.
- Grafana v12.2.1 – Pre‑provisioned dashboards for traces and logs.
Stack Components
| Service | Purpose | What It Does |
|---|---|---|
| Alloy | Data Collection | Receives OTLP (4317/4318) and Faro (12347) telemetry |
| Tempo | Trace Storage | Stores distributed traces, enables TraceQL queries |
| Loki | Log Storage | Aggregates logs, enables LogQL queries |
| Grafana | Visualization | Correlates traces, logs, and metrics in one UI |
Instrumenting Your App
The repository includes a Node.js example. Key dependencies:
pnpm add @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-http @opentelemetry/exporter-logs-otlp-http
Initialize the SDK pointing to Alloy:
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
const traceExporter = new OTLPTraceExporter({ url: 'http://alloy:4318/v1/traces' });
const logExporter = new OTLPLogExporter({ url: 'http://alloy:4318/v1/logs' });
Run the example:
(cd examples/node && pnpm start)
Why This Works
- Zero configuration – All services pre‑wired on
dokploy-network, just deploy. - Production versions – Uses stable releases of Grafana ecosystem tools.
- Auto‑restart – Containers use
unless-stoppedrestart policy. - Standard protocols – OTLP means any OpenTelemetry‑compatible app works.
- Frontend monitoring included – Faro receiver captures browser telemetry out of the box.
Try It
If you’re running Dokploy and want observability without the setup headache:
git clone https://github.com/quochuydev/dokploy-grafana-compose.git
cd dokploy-grafana-compose
docker compose up -d
Open Grafana at http://localhost:3000 and run the Node.js example to see traces flowing in.
GitHub:
Docs: Grafana • OpenTelemetry • Dokploy