Deploy a Multi-Service Stack with Secrets¶
Prerequisites:
- Docker and Docker Compose are installed on the target device.
- You have completed Deploy a Docker Compose Project or are familiar with its workflow.
This guide walks through deploying a three-service monitoring stack (VictoriaMetrics, Telegraf, Grafana) using Docker Compose, with the Grafana admin password injected from a Qbee secret. Hardcoding the password in the compose file exposes it to anyone who can read the configuration. Instead, you define the value once on the Parameters tab, template it into the compose file, and let the agent inject it at converge time. The secret value never appears in the committed configuration or in device logs.
The stack is fully self-contained: the Telegraf configuration is defined inline in the compose file via a Compose configs block, so there are no host files or bind mounts to manage.
The stack consists of:
- VictoriaMetrics -- time-series database, stores the metrics collected by Telegraf.
- Telegraf -- metrics collector, writes system metrics to VictoriaMetrics over its InfluxDB-compatible API.
- Grafana -- visualization, reads from VictoriaMetrics and renders dashboards.
Step 1 — Define the secret¶
Define the Grafana admin password as a secret. Secrets are redacted from logs and cannot be retrieved once saved.
- Navigate to Configure and select the level (or a parent) where the stack will run.
- Open the Parameters bundle.
- Under Secrets, add:
GRAFANA_ADMIN_PASSWORDwith your desired Grafana admin password (for example,my-grafana-password)- Click Save settings.
Expected outcome: The secret appears in the parameters list. Its value is redacted and cannot be retrieved later.
Secret values are write-only
Once a secret is saved, its value is redacted and cannot be retrieved. You can update the secret by setting a new value, which will be used on the next convergence. See Parameters and secrets for details.
Step 2 — Configure the Docker Compose project¶
The compose file defines all three services. The Grafana service needs its admin password set through environment, so the compose file is a template with the password injected from the secret. The Telegraf configuration is defined inline via a Compose configs block, so no host file or bind mount is needed.
- Open the Docker compose bundle and click + to add a project.
- Enter the project name
monitoring-stack. - Upload the following
compose.ymlfile:
services:
victoriametrics:
image: victoriametrics/victoria-metrics:latest
ports:
- "8428:8428"
volumes:
- vmdata:/vmdata
command:
- "--storageDataPath=/vmdata"
- "--retentionPeriod=1"
networks:
- monitoring
telegraf:
image: telegraf:1.30
depends_on:
- victoriametrics
networks:
- monitoring
configs:
- source: telegraf-config
target: /etc/telegraf/telegraf.conf
grafana:
image: grafana/grafana-oss:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD={{GRAFANA_ADMIN_PASSWORD}}
volumes:
- grafana-data:/var/lib/grafana
depends_on:
- victoriametrics
networks:
- monitoring
volumes:
vmdata:
grafana-data:
configs:
telegraf-config:
content: |
[agent]
interval = "10s"
flush_interval = "10s"
[[outputs.influxdb]]
urls = ["http://victoriametrics:8428"]
database = "telegraf"
skip_database_creation = true
[[inputs.cpu]]
percpu = true
totalcpu = true
[[inputs.mem]]
[[inputs.disk]]
[[inputs.diskio]]
[[inputs.system]]
networks:
monitoring:
- Enable templating on the compose file and add the template parameters:
- Key:
GRAFANA_ADMIN_PASSWORD - Value:
$(GRAFANA_ADMIN_PASSWORD) - Click Save settings.
Expected outcome: The project appears in the Docker Compose form with the compose file attached and the template parameter mapped to the secret.
Step 3 — Commit and verify¶
Click Commit changes in the top right. Optionally enter a commit message, then click Commit.
Within one polling cycle the agent applies the Docker Compose project -- with the Grafana admin password substituted into the environment -- pulls the images, and starts the three containers.
To verify, open the device in the console and check the device inventory tab. The monitoring-stack-victoriametrics-1, monitoring-stack-telegraf-1, and monitoring-stack-grafana-1 containers should all appear with a status of running.
Alternatively, open a remote console on the device and run:
docker compose ls
docker compose -p monitoring-stack ps
Expected outcome: The monitoring-stack project appears with all three services running.
To confirm Grafana accepted the injected password, open a browser at http://<device-ip>:3000 and sign in as admin with the password you defined as a secret.
A container is not running
If any of the three containers is missing or has exited, open a remote console and check its logs:
docker compose -p monitoring-stack logs <service>
Replace <service> with victoriametrics, telegraf, or grafana. The most common cause is the image failing to pull -- verify the device can reach the registry and that the agent has converged since the commit.
Done¶
You have deployed a self-contained multi-service monitoring stack. The Grafana admin password exists in exactly one place (the Parameters tab) and is never committed to the configuration or exposed in device logs. Everything else -- including the Telegraf configuration -- lives in the compose file, so there are no host files or bind mounts to maintain.
What Next?¶
| I want to... | Go to |
|---|---|
| Deploy a simpler single-project stack | Deploy a Docker Compose Project |
| Use the same pattern for a single container | Deploy a Docker Container |
| Understand parameters and secrets in depth | Parameters and secrets |
| Access the running containers | Remote Access |
| View container status | Inventory |