Skip to content

Commit

Permalink
example: add Docker Compose example
Browse files Browse the repository at this point in the history
This commit adds a new Docker Compose example for users to quickly test
running Alloy either in a Docker container or locally, sending data to
databases in a Docker container.

By default, the following are deployed:

* Visualization
  * Grafana 10.1.9
  * A one-shot container to deploy the Alloy mixin to Grafana
  * A container which watches the Alloy mixin folder and deploys changes
    automatically

* Databases
  * Mimir 2.12.0
  * Loki 3.0.0
  * Tempo 2.4.1
  * Pyroscope 1.5.0

Grafana Alloy can also be deployed by passing the `--profile=alloy`
command to Docker Compose when starting and stopping:

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

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

Alternatively, Alloy can be run locally using the config file in
example/config/alloy/config.alloy.

The default Alloy configuration used in the Docker Compose environment
configures Alloy to self-collect metrics, logs, traces, and profiles,
and send them to the backend databases.
  • Loading branch information
rfratto committed Apr 11, 2024
1 parent aca2f0f commit 47f1e28
Show file tree
Hide file tree
Showing 9 changed files with 367 additions and 0 deletions.
52 changes: 52 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Docker Compose example

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

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`)
* 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


2 changes: 2 additions & 0 deletions example/images/grizzly/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM golang:1.22-alpine
RUN go install github.com/grafana/grizzly/cmd/[email protected]

0 comments on commit 47f1e28

Please sign in to comment.