How to deploy Mimir on Juju¶
This guide deploys Grafana Mimir on Kubernetes using Juju, Canonical’s operator lifecycle manager, without pulling in the full Canonical Observability Stack (COS) bundle. It targets readers who already know upstream Mimir and want the Juju-native path to a working, Mimir-focused deployment.
If you are new to Juju, skim the Juju documentation first — especially Juju: get started and the Juju reference for the meaning of terms like model, application, unit, and relation. The runtime you get from this guide is upstream Mimir; the charms just handle configuration, storage wiring, ingress, and inter-component relations.
For a full COS deployment (Grafana, Alertmanager, Loki, etc.) instead of a Mimir-focused one, see Getting started with COS on Canonical Kubernetes.
Note
Mimir on Juju guides
Important
This guide uses the Juju CLI because it is the clearest way to see how the deployment fits together. For repeatable environments and production-oriented rollouts, prefer the Mimir Terraform module.
What this guide deploys¶
Mimir infrastructure (required for Mimir to run):
mimir-coordinator-k8s: the public API and coordinator for the Mimir cluster.mimir-worker-k8s: a single worker application configured to run all Mimir roles (role-all=true). In production, split this into dedicatedmimir-write,mimir-read, andmimir-backendapplications and scale each role independently.s3-integrator(deployed asmimir-s3): supplies Mimir with an S3 endpoint and credentials. Mimir requires S3-compatible object storage; the charm does not provide the object store itself, only the connection details.
Supporting infrastructure (not part of Mimir itself, but used here for a usable end-to-end flow):
traefik-k8s: gives Mimir a stable URL for ingestion and querying from outside the cluster.opentelemetry-collector-k8s(otelcol): used only in the validation step to scrape a test workload and push metrics to Mimir overprometheus_remote_write. Note, however, that in most production deployments, Otelcol is the component responsible for scraping metrics provided by other workloads and remote writing them into Mimir.avalanche-k8s: a synthetic metrics generator used only in the validation step.
Prerequisites¶
Juju 3.6 or later, with a Kubernetes cloud added and a controller bootstrapped. See Juju: install Juju, Juju: add a Kubernetes cloud, and Juju: bootstrap a controller.
A Kubernetes cluster ready to host the Mimir model. For a local option, see Canonical Kubernetes: get started.
An S3-compatible object store that already exists, with an endpoint, bucket, access key, and secret key. If you do not have one, see How to deploy Minio and S3 Integrator for a disposable test store. For the connection steps in more detail, see How to connect object storage to Mimir on Juju.
A routable ingress address for Traefik if you want to query Mimir from outside the cluster. See the networking best practices.
1. Create a model¶
A Juju model is a workspace on the controller that holds a set of related applications. Create one dedicated to Mimir:
juju add-model mimir
juju switch mimir
2. Deploy Mimir and its supporting charms¶
Deploy the Mimir coordinator, one worker application, an S3 integrator, and Traefik:
juju deploy mimir-coordinator-k8s mimir --trust
juju deploy mimir-worker-k8s mimir-worker \
--trust \
--config role-all=true
juju deploy s3-integrator mimir-s3 --channel latest/stable --trust
juju deploy traefik-k8s traefik --trust
--trust grants the charm access to the Kubernetes API on the host cluster,
which the Mimir, S3 integrator, and Traefik charms need to create the
resources they manage.
3. Point the S3 integrator at your object storage¶
The mimir-s3 application starts in blocked status until it has both
credentials and a target bucket. Create a Juju secret with the S3
credentials, grant that secret to mimir-s3, then configure the endpoint
and bucket.
Replace the placeholders with your existing S3-compatible storage details:
juju add-secret mimir-s3-credentials \
access-key=<access-key> \
secret-key=<secret-key>
juju grant-secret mimir-s3-credentials mimir-s3
juju config mimir-s3 \
credentials=mimir-s3-credentials \
endpoint=<s3-endpoint> \
bucket=<bucket-name>
If your object store needs additional settings such as a custom CA chain, region, or path-style addressing, see How to connect object storage to Mimir on Juju.
4. Integrate the deployment¶
Connect storage first, then join the worker and ingress relations:
juju integrate mimir:s3 mimir-s3:s3-credentials
juju integrate mimir:mimir-cluster mimir-worker:mimir-cluster
juju integrate traefik:ingress mimir:ingress
Watch the model until every application reaches active/idle. That is the
Juju status meaning the charm has finished reconciling and is running as
configured; other transient statuses (waiting, maintenance, blocked)
indicate the deployment is still converging or missing something:
juju status --relations --watch=5s
At this point Mimir should expose at least:
receive-remote-writefor metrics ingestioningressfor external accessself-metrics-endpointfor scrape-based validation flows
5. Validate metric ingestion with OpenTelemetry Collector¶
For a minimal smoke test, deploy:
avalanche-k8s, which is a small synthetic metrics generator.opentelemetry-collector-k8s, which is a scraper and forwarder charm that collects Avalanche’s metrics and pushes them to Mimir overprometheus_remote_write.
Neither of these is required for Mimir itself. They only exist here to prove the ingestion path works end-to-end:
juju deploy opentelemetry-collector-k8s otelcol --trust
juju deploy avalanche-k8s avalanche --trust
juju integrate avalanche otelcol:metrics-endpoint
juju integrate otelcol:send-remote-write mimir:receive-remote-write
Wait for the applications to reach active/idle:
juju status --relations --watch=5s
6. Query Mimir¶
Use the Traefik action to get the Mimir URL:
juju run traefik/0 show-proxied-endpoints --format=yaml \
| yq '."traefik/0".results."proxied-endpoints"' \
| jq
The output includes a mimir entry similar to:
{
"mimir": {
"url": "http://10.43.8.34:80/mimir"
}
}
Save that URL and query Mimir’s Prometheus-compatible API:
MIMIR_URL=http://10.43.8.34:80/mimir
curl -sG "$MIMIR_URL/prometheus/api/v1/query" \
--data-urlencode 'query=count({__name__=~"avalanche_metric_.+"})' \
| jq
You should see a successful query response with a value greater than 0.
Next steps¶
For storage details and production-oriented caveats, see How to connect object storage to Mimir on Juju.
For more ways to send metrics into Mimir, including cross-model relations and direct
remote_writeclients, see How to send metrics to Mimir on Juju.To grow this into a full Canonical Observability Stack with Grafana, Loki, Alertmanager, and correlated telemetry, see Getting started with COS on Canonical Kubernetes.