A standardized, self-hosted observability stack template for modern applications. Deploy your own cost-effective alternative to expensive SaaS solutions like Datadog or New Relic.
- π° Cost Effective: ~90% cheaper than SaaS alternatives at scale
- π― Standardized: Same observability setup across all RAVN projects
- π Data Ownership: Your metrics stay in your infrastructure
- π Full Featured: Logs, metrics, traces, and dashboards out of the box
- βοΈ Cloud Agnostic: Deploy anywhere Docker runs
- π Grafana - Dashboards and visualization
- π Loki - Log aggregation and search
- π Mimir - Metrics storage (Prometheus-compatible)
- π Tempo - Distributed tracing
- π Alloy - Telemetry collection (OpenTelemetry-compatible)
curl -sSL https://raw.githubusercontent.com/ravnhq/observability-stack/master/install.sh | bashThis will:
- Check for Docker and docker-compose
- Download the stack to
./observability - Generate secure passwords
- Start all services
- Show you the Grafana login credentials
# 1. Clone this template for your project
git clone https://github.com/ravnhq/observability-stack my-project-observability
cd my-project-observability
# 2. Configure environment
cp src/.env.example src/.env
# Edit src/.env - set GRAFANA_ADMIN_PASSWORD
# 3. Start the stack
cd src && docker-compose up -d
# 4. Access Grafana
open http://localhost:3030
# Login with admin / your-passwordYour apps send telemetry to the Alloy collector on port 4317 (gRPC) or 4318 (HTTP):
// Node.js Example
const { NodeSDK } = require('@opentelemetry/sdk-node');
const sdk = new NodeSDK({
serviceName: 'my-app',
// Point to your deployed observability stack
traceExporterUrl: 'http://your-stack-host:4317',
});See examples/ for language-specific integration:
The stack automatically collects system metrics when deployed. For additional monitoring:
# docker-compose.yml - Add node-exporter for system metrics
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"PostgreSQL monitoring is built-in. Configure with:
# .env
DB_DSN=postgresql://user:pass@your-db:5432/dbname?sslmode=requireEach project should deploy its own instance. Choose your platform:
# Build and push to ECR
aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_URL
docker build -t observability .
docker tag observability:latest $ECR_URL/observability:latest
docker push $ECR_URL/observability:latest
# Deploy with provided task definition
aws ecs create-service \
--cluster your-cluster \
--service-name observability \
--task-definition observability-task# Build and deploy
gcloud builds submit --tag gcr.io/PROJECT/observability
gcloud run deploy observability \
--image gcr.io/PROJECT/observability \
--platform managed \
--allow-unauthenticated \
--set-env-vars "STORAGE_TYPE=gcs,GCS_BUCKET_LOGS=my-logs"- Fork this repository
- Connect Railway to your GitHub
- Create new project from repository
- Add environment variables from
.env.example - Deploy
# On your server with Docker installed
git clone <your-fork> observability
cd observability
cp .env.example .env
# Edit .env with production values
docker-compose up -dBy default, uses local disk. For production, configure cloud storage:
# AWS S3
STORAGE_TYPE=s3
AWS_REGION=us-west-2
S3_BUCKET_LOGS=my-app-logs
S3_BUCKET_TRACES=my-app-traces
S3_BUCKET_METRICS=my-app-metrics
# Google Cloud Storage
STORAGE_TYPE=gcs
GCS_BUCKET_LOGS=my-app-logs
GCS_BUCKET_TRACES=my-app-traces
GCS_BUCKET_METRICS=my-app-metricsConfigure how long to keep data:
LOKI_RETENTION_HOURS=168 # 7 days of logs
TEMPO_RETENTION_HOURS=336 # 14 days of traces
MIMIR_RETENTION_HOURS=8760 # 1 year of metricsAdjust based on your load:
# For small projects (< 100 req/s)
LOKI_INGESTION_RATE_MB=4
TEMPO_INGESTION_RATE_MB=100
MIMIR_INGESTION_RATE=50000
# For larger projects
LOKI_INGESTION_RATE_MB=50
TEMPO_INGESTION_RATE_MB=500
MIMIR_INGESTION_RATE=500000Estimated monthly costs for a typical application:
| Solution | Logs (GB) | Metrics | Traces | Total/Month |
|---|---|---|---|---|
| Datadog | 100 | 1M series | 1M spans | ~$800 |
| New Relic | 100 | 1M series | 1M spans | ~$650 |
| This Stack (AWS) | 100 | 1M series | 1M spans | ~$50 |
| This Stack (GCP) | 100 | 1M series | 1M spans | ~$45 |
Costs include compute (1 vCPU, 2GB RAM) and storage. Actual costs vary by region and usage.
When properly integrated, you'll have:
- π Logs: Application logs, errors, structured events
- π Metrics: Request rates, latency, error rates, custom business metrics
- π Traces: Request flow across services, SQL queries, external API calls
- π» System: CPU, memory, disk, network metrics
- ποΈ Database: Query performance, connection pools, slow queries
- Change default passwords
- Use TLS in production (
TLS_ENABLED=true) - Restrict network access (firewall/security groups)
- Regular backups of Grafana dashboards
- See Security Guide
We need help with:
- Node.js Examples: Implement working examples for Express, Next.js 15, and NestJS
- Deployment Guides: Document and test AWS ECS, GCP Cloud Run, Railway deployments
- Dashboards: Create default Grafana dashboards for common scenarios
- Alerts: Add example alert rules for common issues
- Fork this repository
- Pick a task from issues or create one
- Make your changes
- Test locally with
docker-compose up - Submit a PR
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Internal: #observability Slack channel
MIT - Use this template freely for your projects.
Built with β€οΈ by RAVN