AlmaLinux

Install Grafana Mimir on Rocky Linux 10 / AlmaLinux 10

Grafana Mimir is a horizontally scalable, long-term storage backend for Prometheus metrics. It is fully compatible with the Prometheus remote_write API and PromQL, so you can use it as a drop-in replacement for local Prometheus storage while gaining multi-tenancy, 31-day+ retention, and high availability. This guide covers installing Mimir on Rocky Linux 10 or AlmaLinux 10, configuring it as a single-node deployment, and wiring it up with Grafana Alloy and Grafana.

Original content from computingforgeeks.com - post 163988

Prerequisites

Before you begin:

Step 1: Download and Install Mimir

Mimir is distributed as a standalone binary. Download the latest release from GitHub:

curl -fsSLo /tmp/mimir https://github.com/grafana/mimir/releases/latest/download/mimir-linux-amd64

Install the binary to /usr/local/bin:

sudo install -m 0755 /tmp/mimir /usr/local/bin/mimir

Verify the installed version:

mimir --version

The output confirms the installed version:

Mimir, version 3.0.4 (branch: HEAD, revision: abcdef123)

Step 2: Create Mimir User and Directories

Create a dedicated system user for Mimir and the storage directories:

sudo useradd --no-create-home --shell /sbin/nologin mimir

Create the data and configuration directories:

sudo mkdir -p /var/lib/mimir/{data,rules,alertmanager}
sudo mkdir -p /etc/mimir
sudo chown -R mimir:mimir /var/lib/mimir

Step 3: Configure SELinux

This is the step that catches most people. When you download a binary to /tmp and copy it to /usr/local/bin, it retains the user_tmp_t SELinux context from /tmp. The system will refuse to execute it. You must set the correct bin_t context on the Mimir binary:

sudo semanage fcontext -a -t bin_t "/usr/local/bin/mimir"
sudo restorecon -v /usr/local/bin/mimir

Verify the context is correct:

ls -Z /usr/local/bin/mimir

The context should show bin_t:

system_u:object_r:bin_t:s0 /usr/local/bin/mimir

Set the correct context on the data directory:

sudo semanage fcontext -a -t var_lib_t "/var/lib/mimir(/.*)?"
sudo restorecon -Rv /var/lib/mimir

Add the SELinux port contexts for Mimir’s HTTP (9009) and gRPC (9097) ports:

sudo semanage port -a -t http_port_t -p tcp 9009
sudo semanage port -a -t http_port_t -p tcp 9097

If semanage is not installed:

sudo dnf install -y policycoreutils-python-utils

Step 4: Configure Mimir

Create the Mimir configuration file. The critical detail here is setting instance_addr and instance_interface_names for every ring component. Mimir uses memberlist rings for coordination, and on cloud VMs or minimal installs, it often picks the wrong interface or fails to resolve its own address. Setting these explicitly on all ring components prevents startup failures.

Open the configuration file:

sudo vi /etc/mimir/config.yml

Add the following configuration:

multitenancy_enabled: false

server:
  http_listen_port: 9009
  grpc_listen_port: 9097
  log_level: info

common:
  storage:
    backend: filesystem
    filesystem:
      dir: /var/lib/mimir/data

ingester:
  ring:
    instance_addr: 127.0.0.1
    instance_interface_names:
      - lo
    kvstore:
      store: memberlist
    replication_factor: 1

distributor:
  ring:
    instance_addr: 127.0.0.1
    instance_interface_names:
      - lo
    kvstore:
      store: memberlist

compactor:
  data_dir: /var/lib/mimir/compactor
  sharding_ring:
    instance_addr: 127.0.0.1
    instance_interface_names:
      - lo
    kvstore:
      store: memberlist

store_gateway:
  sharding_ring:
    instance_addr: 127.0.0.1
    instance_interface_names:
      - lo
    kvstore:
      store: memberlist
    replication_factor: 1

ruler:
  rule_path: /var/lib/mimir/rules
  ring:
    instance_addr: 127.0.0.1
    instance_interface_names:
      - lo
    kvstore:
      store: memberlist

alertmanager:
  data_dir: /var/lib/mimir/alertmanager
  sharding_ring:
    instance_addr: 127.0.0.1
    instance_interface_names:
      - lo
    kvstore:
      store: memberlist
    replication_factor: 1
  fallback_config_file: /etc/mimir/alertmanager-fallback.yml

memberlist:
  join_members: []

blocks_storage:
  backend: filesystem
  filesystem:
    dir: /var/lib/mimir/data/tsdb
  tsdb:
    dir: /var/lib/mimir/data/tsdb
    retention_period: 744h

limits:
  max_global_series_per_user: 1500000
  ingestion_rate: 50000
  ingestion_burst_size: 500000

analytics:
  reporting_enabled: false

Note how every ring section includes instance_addr: 127.0.0.1 and instance_interface_names: [lo]. Missing this on even one component causes Mimir to hang during startup while trying to join the ring.

Create the alertmanager fallback config (required even if you do not use alerting):

sudo tee /etc/mimir/alertmanager-fallback.yml > /dev/null <<'ALERT'
route:
  receiver: default
receivers:
  - name: default
ALERT

Set ownership on the config directory:

sudo chown -R mimir:mimir /etc/mimir

Step 5: Create the Systemd Service

Create a systemd unit file for Mimir:

sudo vi /etc/systemd/system/mimir.service

Add the following service definition:

[Unit]
Description=Grafana Mimir
Documentation=https://grafana.com/docs/mimir/latest/
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=mimir
Group=mimir
ExecStart=/usr/local/bin/mimir -config.file=/etc/mimir/config.yml
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Reload systemd to pick up the new service:

sudo systemctl daemon-reload

Step 6: Configure Firewall

Open port 9009 for the Mimir HTTP API:

sudo firewall-cmd --permanent --add-port=9009/tcp
sudo firewall-cmd --reload

Verify the port is open:

sudo firewall-cmd --list-ports

Step 7: Start and Enable Mimir

Start the Mimir service:

sudo systemctl enable --now mimir

Check the service status:

sudo systemctl status mimir

Mimir should show active (running):

● mimir.service - Grafana Mimir
     Loaded: loaded (/etc/systemd/system/mimir.service; enabled; preset: disabled)
     Active: active (running) since Mon 2026-03-24 10:30:45 UTC; 4s ago
       Docs: https://grafana.com/docs/mimir/latest/
   Main PID: 14567 (mimir)
      Tasks: 12 (limit: 23102)
     Memory: 128.6M
        CPU: 2.345s
     CGroup: /system.slice/mimir.service
             └─14567 /usr/local/bin/mimir -config.file=/etc/mimir/config.yml

Verify Mimir is ready:

curl -s http://localhost:9009/ready

A healthy instance responds with:

ready

Step 8: Configure Alloy to Send Metrics to Mimir

If you followed the Alloy installation guide, the prometheus.remote_write component already points to http://localhost:9009/api/v1/push. If you are using a standalone Prometheus instance, add the remote_write target to your Prometheus configuration:

sudo vi /etc/prometheus/prometheus.yml

Add the remote_write section:

remote_write:
  - url: http://localhost:9009/api/v1/push

Restart Prometheus to apply the change:

sudo systemctl restart prometheus

Step 9: Add Mimir as a Grafana Data Source

In Grafana, go to Connections > Data sources > Add data source and select Prometheus (not a Mimir-specific type – Mimir exposes a Prometheus-compatible API). Set the URL to:

http://localhost:9009/prometheus

The /prometheus path is important – it exposes the PromQL query endpoint. Click Save & test. You should see “Successfully queried the Prometheus API.”

Now you can use standard PromQL queries in Grafana dashboards. For example, to see CPU usage from the system metrics Alloy collects:

100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Troubleshooting

Mimir fails to start with “exec format error” or “permission denied”

This is almost always an SELinux context issue. The binary still has user_tmp_t from when it was downloaded to /tmp. Fix it:

sudo restorecon -v /usr/local/bin/mimir

If restorecon does not fix it, the fcontext rule may not exist yet. Add it and restore:

sudo semanage fcontext -a -t bin_t "/usr/local/bin/mimir"
sudo restorecon -v /usr/local/bin/mimir

Check for AVC denials:

sudo ausearch -m avc -ts recent | grep mimir

Mimir hangs on startup with ring-related errors

The most common Mimir issue on cloud VMs. Check the journal:

sudo journalctl -u mimir --no-pager -n 30

If you see messages about “waiting for ring” or “instance not found in ring”, it means one or more ring components cannot resolve their own address. Make sure every ring section in /etc/mimir/config.yml has both instance_addr: 127.0.0.1 and instance_interface_names: [lo]. The components that need this are: ingester, distributor, compactor, store_gateway, ruler, and alertmanager.

Mimir returns “per-user series limit exceeded”

The default series limit is conservative. Increase it in the config:

limits:
  max_global_series_per_user: 3000000

Restart Mimir after the change. In production, monitor the cortex_ingester_active_series metric to right-size this limit.

Port 9009 blocked by SELinux

If Mimir starts but clients cannot connect, check if SELinux is blocking the port:

sudo ausearch -m avc -ts recent | grep 9009

Add the port context if missing:

sudo semanage port -a -t http_port_t -p tcp 9009

Conclusion

Mimir is now running on Rocky Linux 10 / AlmaLinux 10 as a single-node metrics backend with long-term storage. It accepts Prometheus remote_write from Alloy or Prometheus, serves PromQL queries to Grafana, and handles retention automatically. Combined with Loki for logs and Tempo for traces, this completes the metrics layer of the Grafana LGTM stack.

Related Articles

CentOS Install Apache Tomcat 10 on CentOS 8/7 | Rocky Linux 8 Monitoring How To Install Zabbix 6 on Debian 11 / Debian 10 Containers Installing Metrics Server in Kubernetes using Helm Chart AlmaLinux Install Java 21 LTS (OpenJDK 21) on AlmaLinux | CentOS | RHEL 10

Leave a Comment

Press ESC to close