The pursuit of network transparency in modern home labs and enterprise edge environments necessitates a robust observability pipeline. Relying on anecdotal evidence of internet performance—such as "the internet feels slow"—is insufficient for diagnosing intermittent ISP throttling, packet loss, or hardware-induced latency spikes. A professional-grade solution requires a continuous, automated execution of network throughput tests, the persistent storage of these metrics in a high-performance time-series database, and a high-fidelity visualization layer to transform raw numerical data into actionable intelligence. This is achieved through the integration of Speedtest Tracker, InfluxDB, and Grafana. By leveraging containerized orchestration via Docker, administrators can deploy a self-hosted monitoring stack that tracks download speeds, upload speeds, latency, and jitter, providing a historical record of ISP performance and uptime. This ecosystem allows for the identification of discrepancies between advertised service level agreements (SLAs) and actual delivered performance, serving as an empirical audit log for internet service providers.
The Architecture of Automated Network Monitoring
A functional Speedtest Grafana deployment is not a single application but a distributed system of specialized microservices working in concert. The architecture typically consists of three distinct functional layers: the collector, the storage engine, and the visualization interface.
The collector layer is powered by Speedtest Tracker, a self-hosted application designed to automate the execution of Ookla speedtest CLI tests. This layer is responsible for the active probing of the network. It reaches out to various test servers across the internet to measure the fundamental metrics of connection quality. Beyond simple throughput, the collector captures critical jitter and latency measurements, which are essential for evaluating the suitability of the connection for real-time applications like VoIP or gaming.
The storage engine layer, frequently utilizing InfluxDB (specifically version 2.x for modern implementations), serves as the persistent memory of the system. Unlike traditional relational databases, InfluxDB is optimized for time-series data, allowing it to handle the high-frequency writes and complex temporal queries required for network telemetry. In the context of InfluxDBv2, the data is organized into buckets, which act as logical containers for the metrics. This layer must be configured with specific API tokens to ensure that only authorized collectors can write data and only authorized visualization tools can read it.
The visualization layer, represented by Grafana, provides the human-scale interface. This component queries the InfluxDB buckets and renders the results into sophisticated dashboards. These dashboards utilize complex queries, such as Flux or SQL, to aggregate data over various time intervals, allowing users to view everything from the most recent test result to monthly average throughput trends.
Deployment Orchestration via Docker and Compose
For the modern DevOps practitioner, manual installation of these services is deprecated in favor of containerized orchestration. Using Docker and Docker Compose, the entire stack can be instantiated with a single command, ensuring environment parity and simplified lifecycle management.
The deployment process begins with the acquisition of the necessary configuration templates. A common approach involves cloning a pre-configured repository that contains the service definitions and environment templates.
Clone the deployment repository using the following command:
git clone https://github.com/frdmn/docker-speedtest-grafanaNavigate to the directory and prepare the environment configuration by duplicating the sample environment file:
cp .env.sample .env
Once the .env file is created, it serves as the control plane for the containerized environment. This file allows for the customization of critical parameters without modifying the underlying Dockerfiles.
| Environment Variable | Default Value | Functional Impact |
| --- | --- and --- | --- |
| GRAFANAPORT | 3000 | Determines the host-to-container port mapping for the web interface access. |
| SPEEDTESTSPEEDTESTINTERVAL | 3600 | Defines the frequency of network probes, measured in seconds. |
| SPEEDTESTHOST | local | Sets the display name for the client being monitored in the dashboard. |
| SPEEDTESTSERVER | none | Allows for the targeting of a specific Ookla server ID to ensure geographic consistency. |
| INFLUXDBDB | speedtest | Specifies the target database name for storing telemetry results. |
| INFLUXDBHOST | influxdb | Defines the network alias for the InfluxDB container within the Docker network. |
| INFLUXDBUSERNAME | root | The authentication identity used for InfluxDB database operations. |
| INFLUXDB_PASSWORD | root | The credential required for secure database access. |
After the configuration is finalized, the containers can be brought online using the following command:
docker-to-compose up -d
The -d flag ensures that the containers run in detached mode, allowing the orchestration to continue in the background. Upon execution, the Docker engine will begin the creation process, as seen in the following lifecycle logs:
Creating speedtest_influxdb_1 ... done
Creating speedtest_grafana_1 ... done
Creating speedtest_speedtest_1 ... done
To manage the lifecycle of the stack, standard Docker commands apply. For example, to halt all monitoring services:
docker-compose stop
In scenarios where the configuration has been updated or a new image version is available, the following sequence is utilized to perform a clean rolling update:
docker-compose pull
docker-compose rm
docker-compose up -d
Data Ingestion and InfluxDBv2 Configuration
Transitioning from legacy InfluxDBv1 to the modern InfluxDBv2 architecture requires a more granular approach to security and data organization. The move to version 2.x introduces the concept of Organizations and Buckets, which enhances the security model through the use of scoped API tokens.
The configuration of the data pipeline follows a strict sequence of operations to ensure that the Speedtest Tracker can successfully hand off data to the storage engine.
- Initialize the storage container: Create a specific bucket named
speedtest-trackerwithin the InfluxDBv2 instance. This bucket serves as the destination for all incoming throughput metrics. - Implement the Security Model: This involves a two-tiered token strategy. First, an "ALL ACCESS" token must be generated to facilitate the initial setup and authentication between Grafana and InfluxDB. Second, a more restricted "read/write" token must be generated specifically for the
speedtest-trackerbucket. This ensures that even if the tracker application is compromised, the scope of unauthorized data modification is limited to a single bucket. - Configure the Collector: Within the Speedtest Tracker application settings, the user must input the InfluxDBv2 URL, the Organization name, the Bucket name, and the previously generated Read/Write token. It is critical to utilize the "Test connection" feature within the application to validate the network path and credential validity before proceeding.
- Verification: Before moving to visualization, the administrator must navigate to the "Data Explorer" within the InfluxDBv2 UI to confirm that new measurements are actively arriving in the bucket.
The transition to InfluxDBv2 also brings improved support for multi-bucket architectures. Advanced users can expand the dashboard's scope by adding new buckets through the Grafana Dashboard Settings. By navigating to Dashboard Settings, selecting Variables, and clicking on the bucket variable, users can access custom options to add additional data streams, allowing a single dashboard to monitor multiple distinct network segments or geographic locations.
Visualizing Network Telemetry in Grafana
The ultimate objective of this infrastructure is the generation of high-fidelity visual representations of network performance. This is achieved by importing specialized JSON dashboard definitions into Grafana. For the InfluxDBv2 implementation, the dashboard ID 17808 is specifically designed to parse the Flux query language used by the modern InfluxDB engine.
To implement the visualization layer, follow these steps:
- Access the Grafana web interface, typically at
http://localhost:3000, using the default credentials (admin/admin). - Navigate to the "Dashboards" section and select "New" followed by "Import".
- Use the provided dashboard JSON or the ID linked in the documentation to pull the configuration.
- Configure the Data Source: When prompted, select the InFLuxDB data source. It is mandatory to set the Query Language to
Flux, specify yourOrganization, identify the correctBucket(e.g.,speedtest-tracker), and provide theTokencreated during the InfluxDB setup phase.
A well-configured dashboard does more than just show a single number; it allows for deep-dive analysis through the use of tags. The collector can be configured to tag every test result with metadata such as isp, external_ip, server_id, server_name, server_location, and speedtest_url. This allows for complex filtering in the dashboard.
For instance, if a user wants to isolate the performance of a specific client, they can modify the SQL or Flux queries to include a WHERE clause. For a dashboard utilizing SQL-based retrieval, a query to view download time series for a specific host would look like this:
SELECT mean("value") FROM "download" WHERE $timeFilter and host = 'local' GROUP BY time($interval) fill(null)
This level of granularity enables administrators to differentiate between a global ISP outage and a localized issue affecting only a specific router or client in the network.
Advanced Maintenance and Development
For developers looking to extend the functionality of this stack, the environment is designed to support standard Git-based workflows. If one intends to contribute new panels or features to the dashboard, the following workflow is recommended to maintain code integrity:
Initialize a new feature branch:
git checkout -b feature/my-new-featureStage and commit the changes:
git commit -am 'Add some feature'Push the branch to the remote repository for pull request review:
git push origin feature/my-new-feature
Furthermore, maintaining the health of the monitoring system requires periodic log inspection. If the speedtest tasks fail to execute or the database connection drops, the following command provides real-time visibility into the container's standard output:
docker-compose logs -f
To specifically debug the Grafana component, one can isolate its log stream:
docker-compose logs -f grafana
Analytical Conclusion
The integration of Speedtest Tracker, InfluxDBv2, and Grafana represents a significant leap forward in DIY network observability. By moving away from transient, manual testing and toward a persistent, automated telemetry pipeline, administrators gain a scientific method for evaluating ISP reliability. The architecture described—utilizing Docker for orchestration, InfluxDBv2 for high-resolution time-series storage, and Grafana for multi-dimensional visualization—provides the necessary tools to transform raw network throughput into a historical record of connectivity. This system does not merely report speed; it provides the evidence required to hold service providers accountable to their advertised performance metrics, ensuring that the underlying network infrastructure remains a stable foundation for all connected services.