Good with a keyboard and fluent in gibberish

Deploying VictoriaStack in Proxmox

Because everything else sucks

VictoriaMetrics and its friends, VictoriaLogs and VictoriaTraces (alpha), are the new kids on the observability block. They promise easier operations with less resources and more features. At least, I don’t need to deploy 8 daemons to get all my data stored and indexed.

I’m going to take an unusual tact in this deployment. Normally, I’m all gung-ho on just throwing things into Docker, but I’m doing this one native. I love Docker, but I’ve seen it mess up plenty; I don’t need to add “my observability is fucked” to an already bad day.

To that end, I’ll be packaging up Victoria’s binary releases into debs with fpm and running Grafana in Docker. (Maybe at some point I’ll move Grafana to native packages, but getting this all set up was already a butt.)

A Yak Shave: fpm-action

fpm is unfortunately packaged quite poorly, so my first step was to create codeberg.org/AstraLuma/fpm-action to force things into a normal interface.

This is some CI infrastructure that:

  1. Clones the upstream repo
  2. Does the upstream makefile-based container build
  3. Specialize that container to add our own entrypoint, so we can have things like “pick a working directory”
  4. Ship the container image to Codeberg
  5. Have a action.yaml so it’s easily referable

Packaging

Ok, so with fpm I can makge a package. It also seemed like a good idea to automate the process of doing so: codeberg.org/AstraLuma/victoria-apt.

Since I basically made an apt repository for Victoria, this is set up to be run periodically and automatically pick up on upstream releases. I also split up the packages so the client utilities are separated from the main daemons.

So across five different jobs, it:

  1. Downloads the latest release from upstream GitHub (making note of what version was downloaded)
  2. Combines that with the repo files (eg, systemd units)
  3. Runs fpm
  4. Uploads the resulting package files to artifacts and the deb repo

Installation

Now I can actually touch a server!

0. Have a System

I’m starting with a vanilla Debian using LXC and managed by Proxmox. I created a data volume at /var/lib/victoria, since my box has tiered storage (NVMe root with spinning rust array).

All the other specifics are to taste.

1. Add Repo

As mentioned in the victoria-apt README, add /etc/apt/sources.list.d/forgejo.sources and its signing key.

2. Install

$ sudo apt install victoria-metrics victoria-logs victoria-traces vmutils vlutils 

As is normal for Debian packages, this will also configure systemd and start daemons.

3. Configure

I’m using CLI-based configuration in /etc/defaults. All three files look like:

# Set the command-line arguments to pass to the server.
# Due to shell escaping, to pass backslashes for regexes, you need to double
# them (\\d for \d). If running under systemd, you need to double them again
# (\\\\d to mean \d), and escape newlines too.
ARGS="-storageDataPath=/var/lib/victoria/metrics"

(/var/lib/victoria is the data volume mentioned in step 0.)

Don’t forget to restart the daemons via systemd when you change the config.

4. Start Sending Data

Victoria can ingest data in basically any format in use today, so odds are you can connect it to something in your network.

By default, VictoriaMetrics is running on port 8428, VictoriaLogs on 9428, and VictoriaTraces on 10428.

Grafana

Ok, so I have several time series (ish) databases filing up. I need to do something useful with that data.

The upstream recomendation is to use Grafana for querying, analysis, and dashboarding, and I see no reason to do otherwise.

I’m using the Grafana container (for now), since it’s a lot easier to get going than the package, and making use of compose & my caddy ingress:

services:
  grafana:
    image: docker.io/grafana/grafana
    container_name: grafana
    restart: always
    volumes:
      - grafana-data:/var/lib/grafana
      - ./datasources.yaml:/etc/grafana/provisioning/datasources/victoria.yaml
    networks:
      - ingress
    environment:
      GF_PLUGINS_PREINSTALL: victoriametrics-metrics-datasource,victoriametrics-logs-datasource
      GF_PLUGINS_DISABLE_PLUGINS: grafana-metricsdrilldown-app,grafana-lokiexplore-app,grafana-exploretraces-app,grafana-pyroscope-app
    extra_hosts:
      - "host.docker.internal:host-gateway"

networks:
  ingress:
    external: true

volumes:
  grafana-data:
  • container_name and networks are part of the ingress scheme
  • datasources.yaml and GF_PLUGINS_PREINSTALL means Grafana comes up connected to Victoria with zero post-install configuration
  • GF_PLUGINS_DISABLE_PLUGINS is because the drilldown plugins don’t hide themselves if you’re not using those datasources, and it was cluttering the UI
  • Grafana is using host.docker.internal to connect to Victoria so it’s not depending on external DNS or anything

The datasources.yaml was surprisingly hard to figure out, since I’m not readily familiar with Grafana administration. But I think this has all the bits I care about:

apiVersion: 1

datasources:
    # <string, required> Name of the VictoriaMetrics datasource
    # displayed in Grafana panels and queries.
  - name: VictoriaMetrics
    # <string, required> Sets the data source type.
    type: victoriametrics-metrics-datasource
    # <string, required> Sets the access mode, either
    # proxy or direct (Server or Browser in the UI).
    # Some data sources are incompatible with any setting
    # but proxy (Server).
    access: proxy
    # <string> Sets default URL of the single node version of VictoriaMetrics
    url: http://host.docker.internal:8428
    # <string> Sets the pre-selected datasource for new panels.
    # You can set only one default data source per organization.
    isDefault: true
    jsonData:
      vmuiUrl: http://vicky.qwertyuiop.home:8428/vmui/

    # <string, required> Name of the VictoriaLogs datasource
    # displayed in Grafana panels and queries.
  - name: VictoriaLogs
    # <string, required> Sets the data source type.
    type: victoriametrics-logs-datasource
    # <string, required> Sets the access mode, either
    # proxy or direct (Server or Browser in the UI).
    access: proxy
    # <string> Sets URL for sending queries to VictoriaLogs server.
    # see https://docs.victoriametrics.com/victorialogs/querying/
    url: http://host.docker.internal:9428
    jsonData:
      vmuiUrl: http://vicky.qwertyuiop.home:9428/select/vmui/

# This is how you do a basic connection to VictoriaTraces.
# I'm not using this because the correlations to metrics and logs is not yet known to me
#  - name: VictoriaTraces
#    type: jaeger
#    access: proxy
#    url: http://host.docker.internal:10428/select/jaeger
  • As mentioned above, Grafana is connecting to Victoria via host.docker.internal so it does a direct loopback
  • The Victoria plugins like to include vmui links in the UI, so the corrected hostname for people users is included
  • The reason not to do YAML-based provisioning is that it disables UI-based editing (you can opt-in to allowing it, in which case you have a footgun of change conflicts)

Bonus: Proxmox Dashboard through VictoriaMetrics

I deployed this on Proxmox, so the first thing I did was connect Proxmox to VictoriaMetrics via the InfluxDB interfaces.

And then I had to rewrite the sample Proxmox dashboard, because it’s written for Influx SQL and VictoriaMetrics speaks a superset of Prometheus.

So anyways, have the importable dashboard.