Speedtest Tracker Guide: Monitor and Log Internet Speeds via Docker

Set up Speedtest Tracker using Docker Compose. Automatically schedule internet speed tests, visualize logs, and track connectivity over time.

1. Docker Compose Configuration

To deploy Speedtest Tracker securely and efficiently, use a multi-container Docker Compose configuration. While Speedtest Tracker supports an embedded SQLite database, a production-grade self-hosted instance should utilize PostgreSQL to prevent database locks and corruption during heavy write cycles.

Create a directory for your deployment and save the following configuration as docker-compose.yml:

version: '3.8'

services:
  db:
    image: postgres:15-alpine
    container_name: speedtest-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: speedtest_tracker
      POSTGRES_USER: speedtest_user
      POSTGRES_PASSWORD: aPbVQnuUFACJ53dbtEU4YqNM
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U speedtest_user -d speedtest_tracker"]
      interval: 10s
      timeout: 5s
      retries: 5

  speedtest-tracker:
    image: alexjustesen/speedtest-tracker:latest
    container_name: speedtest-tracker
    restart: unless-stopped
    ports:
      - "8080:80"
    depends_on:
      db:
        condition: service_healthy
    environment:
      # Database Settings
      - DB_CONNECTION=pgsql
      - DB_HOST=db
      - DB_PORT=5432
      - DB_DATABASE=speedtest_tracker
      - DB_USERNAME=speedtest_user
      - DB_PASSWORD=aPbVQnuUFACJ53dbtEU4YqNM

      # Application Settings
      - APP_KEY=base64:$(openssl rand -base64 32)
      - APP_URL=https://speedtest.yourdomain.com
      - TIMEZONE=UTC

      # Speedtest Settings
      - SPEEDTEST_SCHEDULE=0 * * * *
      - SPEEDTEST_SERVERS=
      - PRUNE_RESULTS_OLDER_THAN=90
    volumes:
      - speedtest-data:/config
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  pgdata:
  speedtest-data:

Note: In the environment section, ensure APP_KEY is a persistent base64 key generated using openssl rand -base64 32 or via the application CLI.


2. Database Setting and Configuration

Speedtest Tracker uses Laravel as its underlying framework. When configured with PostgreSQL, the schema is auto-migrated during the first container startup.

Key Database Environment Variables: - DB_CONNECTION: Configured as pgsql (supports sqlite, mysql, mariadb, pgsql). - DB_HOST: Points to the container service name db. - DB_PORT: Database port, default for PostgreSQL is 5432. - DB_DATABASE: Target database name. - DB_USERNAME and DB_PASSWORD: Authentication credentials matched with the db container environment.

To manually backup the database, run the following command on the host:

docker exec -t speedtest-db pg_dump -U speedtest_user speedtest_tracker > backup.sql

To restore the database:

cat backup.sql | docker exec -i speedtest-db psql -U speedtest_user -d speedtest_tracker

3. Cron Expression Configuration for Tests

Automatic testing schedules are managed via the SPEEDTEST_SCHEDULE environment variable inside the container. This uses standard cron syntax (five-field format).

Configuration Formats

  • Every hour on the hour: 0 * * * * (Recommended default)
  • Every 30 minutes: */30 * * * *
  • Every 12 hours (at 00:00 and 12:00): 0 */12 * * *
  • Once daily at 2:00 AM: 0 2 * * *

Performance and Network Impact

Running speed tests consumes significant upstream and downstream bandwidth. A typical test consumes 100MB to 1GB of data depending on connection speed. - Avoid setting cron schedules to run more frequently than 15-minute intervals (*/15 * * * *). Frequent testing can trigger rate-limits or IP bans from Ookla Speedtest servers, and skew your network performance for other clients. - If you need to test against specific servers, retrieve a list of nearby server IDs using the Ookla CLI: bash docker exec -it speedtest-tracker speedtest -L Then paste the desired server IDs (comma-separated) into the SPEEDTEST_SERVERS environment variable.


4. Webhook Notification Triggers

Speedtest Tracker has built-in notification capabilities. These are configured directly through the UI under Settings > Notifications, or via environment variables for custom endpoints.

Supported Channels

  1. Discord Webhooks: Sends rich embeds with download/upload speeds and latency directly to a channel.
  2. Telegram Bots: Sends automated chat notifications using a bot token and chat ID.
  3. Slack Webhooks: Delivers messages to a designated Slack channel.
  4. Generic Webhooks: Sends JSON POST payloads to custom API endpoints.

Setting Up Webhook Alerts

To trigger webhooks when speeds drop below a predefined threshold, configure the following values inside the Speedtest Tracker dashboard: - Download Threshold (Mbps): Send an alert if download speed drops below a set limit (e.g., 100). - Upload Threshold (Mbps): Alert when upload drops (e.g., 20). - Ping Threshold (ms): Alert if latency spikes (e.g., >50ms).

The generic webhook payload structure follows this JSON schema:

{
  "event": "speedtest.completed",
  "data": {
    "id": 123,
    "ping": 12.45,
    "download": 450.12,
    "upload": 50.84,
    "packet_loss": 0.0,
    "timestamp": "2026-07-06T17:30:00Z",
    "server": {
      "id": 1234,
      "name": "Local ISP",
      "location": "City, Country"
    }
  }
}

5. Reverse Proxy Configuration

To access the Speedtest Tracker dashboard securely over HTTPS, configure a reverse proxy. Below are configurations for two popular options: Nginx and Caddy.

Nginx Virtual Host Configuration

Create a virtual host configuration file (e.g., /etc/nginx/sites-available/speedtest) and add the following server block:

server {
    listen 80;
    server_name speedtest.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name speedtest.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/speedtest.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/speedtest.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Enable WebSockets for live logging/updates
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Caddy Configuration

If you use Caddy, the reverse proxy configuration and automatic SSL certificate generation is simplified to a single block in your Caddyfile:

speedtest.yourdomain.com {
    reverse_proxy 127.0.0.1:8080 {
        header_up Host {host}
        header_up X-Real-IP {remote}
    }

    encode gzip
    log {
        output file /var/log/caddy/speedtest_access.log
    }
}

6. Initialization and Access

Deploy the stack by executing:

docker compose up -d

Verify that the containers are running and monitor migration logs:

docker compose logs -f speedtest-tracker

Once started, navigate to https://speedtest.yourdomain.com (or http://your-server-ip:8080).

Initial Credentials: - Email: admin@example.com - Password: password

Warning: Log in immediately, go to your profile settings, and change both the email address and password to secure the installation.