Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example: add Docker Compose example #178

Merged
merged 3 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Docker Compose example

This directory contains a Docker Compose environment that can be used to test
Grafana Alloy.

> **NOTE**: This environment is not intended for production use, and is
> maintained on a best-effort basis.

By default, only Grafana and databases are exposed:

* Grafana, for visualizing telemetry (`localhost:3000`)
* Grafana Mimir, for storing metrics (`localhost:9009`)
* Grafana Loki, for storing logs (`localhost:3000`)
rfratto marked this conversation as resolved.
Show resolved Hide resolved
* Grafana Tempo, for storing traces (`localhost:3200`)
* Grafana Pyroscope, for storing profiles (`localhost:4040`)

Grafana is automatically provisioned with the appropriate datasources and
dashboards for monitoring Grafana Alloy.

To start the environment, run:

```bash
docker compose up -d
```

To stop the environment, run:

```bash
docker compose down
```

## Running Alloy

Alloy can either be run locally or within Docker Compose. The [example
configuration](./config/alloy/config.alloy) can be used to send self-monitoring
data from a local Alloy to the various databases running in Docker Compose.

To run Alloy within Docker Compose, pass `--profile=alloy` to `docker compose`
when starting and stopping the environment:

```bash
docker compose --profile=alloy up -d
```

```bash
docker compose --profile=alloy down
```

## Visualizing

To visualize Alloy data in Grafana, open <http://localhost:3000> in a web
browser and look at the dashboards in the `Alloy` folder.

> **NOTE**: It can take up to a minute for Alloy metrics and profiles to start
> appearing.
32 changes: 32 additions & 0 deletions example/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: alloy-example

include:
- ./grafana.yaml
- ./databases.yaml

services:
alloy:
image: grafana/alloy:v1.0.0
pull_policy: always
profiles: ["alloy"]
restart: on-failure
volumes:
- ./config/alloy:/etc/alloy
environment:
REMOTE_WRITE_HOST: mimir:9009
LOKI_HOST: loki:3100
TEMPO_HOST: tempo:4317
PYROSCOPE_HOST: pyroscope:4040
depends_on:
- mimir
- loki
- tempo
- pyroscope
command:
- run
- /etc/alloy/config.alloy
- --storage.path=/var/lib/alloy/data
- --server.http.listen-addr=0.0.0.0:12345
- --stability.level=experimental # Enable all functionality
ports:
- "12345:12345"
74 changes: 74 additions & 0 deletions example/config/alloy/config.alloy
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// This file serves as an example Alloy configuration to interact with the
// Docker Compose environment.
//
// This configuration works whether you are running Alloy locally or within the
// Docker Compose environment when the `alloy` profile is enabled.

logging {
level = "debug"

// Forward internal logs to the local Loki instance.
write_to = [loki.write.loki.receiver]
}

tracing {
// Write all spans. Don't do this in production!
sampling_fraction = 1.0

// Forward internal spans to the local Tempo instance.
write_to = [otelcol.exporter.otlp.tempo.input]
}

// Collect metrics from the local running Alloy instance and forward to
// Prometheus.
prometheus.exporter.self "alloy" {}
prometheus.scrape "alloy" {
targets = prometheus.exporter.self.alloy.targets
forward_to = [prometheus.remote_write.mimir.receiver]
}

// Collect profiles from the local running Alloy instance and forward to
// Pyroscope.
pyroscope.scrape "default" {
targets = [
{"__address__" = "localhost:12345", "service_name" = "alloy"},
]
forward_to = [pyroscope.write.pyroscope.receiver]
}

prometheus.remote_write "mimir" {
endpoint {
url = format(
"http://%s/api/v1/push",
coalesce(env("REMOTE_WRITE_HOST"), "localhost:9009"),
)
}
}

loki.write "loki" {
endpoint {
url = format(
"http://%s/loki/api/v1/push",
coalesce(env("LOKI_HOST"), "localhost:3100"),
)
}
}

otelcol.exporter.otlp "tempo" {
client {
endpoint = coalesce(env("TEMPO_HOST"), "localhost:4317")

tls {
insecure = true
}
}
}

pyroscope.write "pyroscope" {
endpoint {
url = format(
"http://%s",
coalesce(env("PYROSCOPE_HOST"), "localhost:4040"),
)
}
}
53 changes: 53 additions & 0 deletions example/config/grafana/datasources/datasource.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
apiVersion: 1

deleteDatasources:
- name: Mimir

datasources:
- name: Mimir
type: prometheus
access: proxy
orgId: 1
url: http://mimir:9009/prometheus
basicAuth: false
isDefault: false
version: 1
editable: true
jsonData:
# The recommended scrape interval is 60s.
timeInterval: '60s'
- name: Loki
type: loki
access: proxy
orgId: 1
url: http://loki:3100
basicAuth: false
isDefault: false
version: 1
editable: true
jsonData:
derivedFields:
- datasourceUid: tempo
matcherRegex: tid=(\w+)
name: TraceID
url: $${__value.raw}
- name: Tempo
type: tempo
access: proxy
orgId: 1
url: http://tempo:3200
basicAuth: false
isDefault: false
version: 1
editable: true
apiVersion: 1
uid: tempo
- name: Pyroscope
type: grafana-pyroscope-datasource
access: proxy
orgId: 1
url: http://pyroscope:4040/
basicAuth: false
isDefault: false
version: 1
editable: true
9 changes: 9 additions & 0 deletions example/config/grafana/grafana.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[analytics]
reporting_enabled = false
[auth.anonymous]
enabled = true
org_role = Admin
[explore]
enabled = true
[users]
default_theme = dark
63 changes: 63 additions & 0 deletions example/config/mimir/mimir.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Do not use this configuration in production.
# It is for demonstration purposes only.
multitenancy_enabled: false

activity_tracker: {}

alertmanager: {}

alertmanager_storage:
backend: local

server:
http_listen_port: 9009

# Configure the server to allow messages up to 100MB.
grpc_server_max_recv_msg_size: 104857600
grpc_server_max_send_msg_size: 104857600
grpc_server_max_concurrent_streams: 1000

distributor:
pool:
health_check_ingesters: true

ingester_client:
grpc_client_config:
grpc_compression: gzip
max_recv_msg_size: 104857600
max_send_msg_size: 104857600

ingester:
ring:
final_sleep: 0s
kvstore:
store: inmemory
min_ready_duration: 0s
num_tokens: 512
replication_factor: 1

blocks_storage:
backend: filesystem
bucket_store:
sync_dir: /tmp/mimir/tsdb-sync
filesystem:
dir: /tmp/mimir/blocks
tsdb:
dir: /tmp/mimir/tsdb

compactor:
sharding_ring:
kvstore:
store: inmemory

ruler:
enable_api: true

ruler_storage:
backend: filesystem
local:
directory: /tmp/mimir/rules

limits:
ingestion_burst_size: 500000
ingestion_rate: 250000
35 changes: 35 additions & 0 deletions example/databases.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
services:
mimir:
image: grafana/mimir:2.12.0
restart: on-failure
command:
- -config.file=/etc/mimir-config/mimir.yaml
volumes:
- ./config/mimir:/etc/mimir-config
ports:
- "9009:9009"

loki:
image: grafana/loki:3.0.0
restart: on-failure
ports:
- "3100:3100"

tempo:
image: grafana/tempo:2.4.1
restart: on-failure
command:
- "-storage.trace.backend=local" # tell tempo where to permanently put traces
- "-storage.trace.local.path=/tmp/tempo/traces"
- "-storage.trace.wal.path=/tmp/tempo/wal" # tell tempo where to store the wal
- "-auth.enabled=false" # disables the requirement for the X-Scope-OrgID header
- "-server.http-listen-port=3200"
ports:
- "3200:3200"
- "4317:4317"

pyroscope:
image: grafana/pyroscope:1.5.0
restart: on-failure
ports:
- "4040:4040"
47 changes: 47 additions & 0 deletions example/grafana.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
services:
grafana:
image: grafana/grafana:10.1.9
restart: on-failure
command:
- --config=/etc/grafana-config/grafana.ini
volumes:
- ./config/grafana:/etc/grafana-config
- ./config/grafana/datasources:/etc/grafana/provisioning/datasources
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"]
interval: 1s
start_interval: 0s
timeout: 10s
retries: 5

# Provision alloy-mixin after Grafana is healthy and running.
provision-dashboards:
build: images/grizzly
restart: on-failure
depends_on:
grafana:
condition: service_healthy
environment:
- GRAFANA_URL=http://grafana:3000
volumes:
- ../operations/alloy-mixin:/etc/alloy-mixin
working_dir: /etc/alloy-mixin
command: grr apply grizzly/dashboards.jsonnet

# Watch dashboards for changes and apply them to Grafana.
watch-dashboards:
build: images/grizzly
restart: on-failure
depends_on:
grafana:
condition: service_healthy
environment:
- GRAFANA_URL=http://grafana:3000
volumes:
- ../operations/alloy-mixin:/etc/alloy-mixin
working_dir: /etc/alloy-mixin
command: grr watch dashboards/ grizzly/dashboards.jsonnet


6 changes: 6 additions & 0 deletions example/images/grizzly/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM golang:1.22-alpine

# NOTE(rfratto): Versions of grr newer than v0.2.1 don't work with our Grizzly
# jsonnet files, reporting that the the Alloy dashboard folder "cannot be
# found" after creating it.
RUN go install github.com/grafana/grizzly/cmd/[email protected]