Docker & Container Deployment¶
Run speedtest-cli in a container using Docker or Podman for isolated, reproducible speed tests.
Quick Start¶
Using Docker¶
docker run --rm -it ghcr.io/takitsu21/speedtest:latest
Using Podman¶
podman run --rm -it ghcr.io/takitsu21/speedtest:latest
Both commands will: 1. Pull the latest speedtest-cli image (if not already cached) 2. Run a complete speed test 3. Display results in your terminal 4. Remove the container after completion
Container Image Details¶
Image Information¶
- Registry: GitHub Container Registry (ghcr.io)
- Repository:
ghcr.io/takitsu21/speedtest - Tags:
latest, version-specific tags (e.g.,1.2.3) - Base Image: Python 3.13-slim
- Size: ~200 MB (optimized)
Supported Platforms¶
- linux/amd64 (x86_64)
- linux/arm64 (ARM64/Apple Silicon)
- linux/arm/v7 (ARM 32-bit)
Multi-architecture support ensures the image works on: - Intel/AMD servers and desktops - Apple Silicon Macs (M1/M2/M3) - Raspberry Pi and ARM devices - Cloud platforms (AWS, GCP, Azure)
Basic Usage¶
Run Default Speed Test¶
docker run --rm -it ghcr.io/takitsu21/speedtest:latest
Flags Explained:
- --rm: Remove container after it exits
- -it: Interactive terminal (for colored output)
- ghcr.io/takitsu21/speedtest:latest: Image name
Run with CLI Options¶
Pass any speedtest-cli option to the container:
# Download only
docker run --rm -it ghcr.io/takitsu21/speedtest:latest --download
# Custom size
docker run --rm -it ghcr.io/takitsu21/speedtest:latest -ds 50 -us 25
# Multiple attempts
docker run --rm -it ghcr.io/takitsu21/speedtest:latest --attempts 3
# JSON output
docker run --rm -it ghcr.io/takitsu21/speedtest:latest --json
Advanced Usage¶
Save JSON Results to Host¶
Mount a volume to save results to your host machine:
# Create output directory
mkdir -p ~/speedtest-results
# Run and save JSON output
docker run --rm -it \
-v ~/speedtest-results:/output \
ghcr.io/takitsu21/speedtest:latest \
--json-output /output/results.json
Result: JSON file saved to ~/speedtest-results/results.json on your host.
Silent Mode for Automation¶
Run without interactive terminal:
docker run --rm ghcr.io/takitsu21/speedtest:latest --silent --json
Specific Version¶
Use a specific version instead of latest:
docker run --rm -it ghcr.io/takitsu21/speedtest:1.2.3
Benefits: - Reproducible builds - Version pinning for CI/CD - Rollback capability
Custom Network Configuration¶
Run with host networking for accurate results:
# Docker
docker run --rm -it --network host ghcr.io/takitsu21/speedtest:latest
# Podman
podman run --rm -it --network host ghcr.io/takitsu21/speedtest:latest
When to Use: - Container networking adds latency - Host network gives most accurate results - Required for some network configurations
!!! warning "Security Note"
--network host gives container access to host network stack. Only use if you trust the image.
Building Custom Image¶
Clone Repository¶
git clone https://github.com/takitsu21/speedtest.git
cd speedtest
Build Image¶
# Using Docker
docker build -t speedtest-custom .
# Using Podman
podman build -t speedtest-custom .
Build with BuildKit (Faster)¶
# Docker with BuildKit
DOCKER_BUILDKIT=1 docker build -t speedtest-custom .
# Podman (BuildKit enabled by default)
podman build -t speedtest-custom .
Multi-Platform Build¶
Build for multiple architectures:
docker buildx create --use
docker buildx build \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
-t speedtest-custom \
--push .
Run Custom Image¶
docker run --rm -it speedtest-custom
Docker Compose¶
Create docker-compose.yml for easier management:
version: '3.8'
services:
speedtest:
image: ghcr.io/takitsu21/speedtest:latest
stdin_open: true
tty: true
volumes:
- ./results:/output
command: --json-output /output/speedtest.json
Run:
docker-compose run --rm speedtest
Custom Options:
docker-compose run --rm speedtest --download --attempts 3
Scheduled Testing with Cron¶
Using Docker¶
Create a script ~/speedtest.sh:
#!/bin/bash
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
docker run --rm \
-v ~/speedtest-logs:/output \
ghcr.io/takitsu21/speedtest:latest \
--silent --json-output /output/speedtest_$TIMESTAMP.json
Make it executable:
chmod +x ~/speedtest.sh
Add to crontab:
# Run every day at 2 AM
0 2 * * * /home/username/speedtest.sh
Using systemd Timer (Linux)¶
Create ~/.config/systemd/user/speedtest.service:
[Unit]
Description=Speed Test
[Service]
Type=oneshot
ExecStart=/usr/bin/docker run --rm \
-v %h/speedtest-logs:/output \
ghcr.io/takitsu21/speedtest:latest \
--silent --json-output /output/speedtest_$(date +\%Y\%m\%d_\%H\%M\%S).json
Create ~/.config/systemd/user/speedtest.timer:
[Unit]
Description=Run Speed Test Daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Enable and start:
systemctl --user enable --now speedtest.timer
systemctl --user status speedtest.timer
Kubernetes Deployment¶
CronJob for Scheduled Testing¶
Create speedtest-cronjob.yaml:
apiVersion: batch/v1
kind: CronJob
metadata:
name: speedtest
spec:
schedule: "0 2 * * *" # Daily at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: speedtest
image: ghcr.io/takitsu21/speedtest:latest
args: ["--silent", "--json-output", "/output/results.json"]
volumeMounts:
- name: results
mountPath: /output
volumes:
- name: results
persistentVolumeClaim:
claimName: speedtest-results
restartPolicy: OnFailure
Apply:
kubectl apply -f speedtest-cronjob.yaml
One-Time Job¶
Create speedtest-job.yaml:
apiVersion: batch/v1
kind: Job
metadata:
name: speedtest-once
spec:
template:
spec:
containers:
- name: speedtest
image: ghcr.io/takitsu21/speedtest:latest
args: ["--json"]
restartPolicy: Never
backoffLimit: 3
Run:
kubectl apply -f speedtest-job.yaml
kubectl logs job/speedtest-once
CI/CD Integration¶
GitHub Actions¶
Add to .github/workflows/speedtest.yml:
name: Network Speed Test
on:
schedule:
- cron: '0 */6 * * *' # Every 6 hours
workflow_dispatch:
jobs:
speedtest:
runs-on: ubuntu-latest
steps:
- name: Run Speed Test
run: |
docker run --rm ghcr.io/takitsu21/speedtest:latest --json > results.json
- name: Upload Results
uses: actions/upload-artifact@v3
with:
name: speedtest-results
path: results.json
GitLab CI¶
Add to .gitlab-ci.yml:
speedtest:
image: docker:latest
services:
- docker:dind
script:
- docker run --rm ghcr.io/takitsu21/speedtest:latest --json > results.json
artifacts:
paths:
- results.json
expire_in: 1 week
only:
- schedules
Jenkins¶
pipeline {
agent any
triggers {
cron('0 */6 * * *')
}
stages {
stage('Speed Test') {
steps {
sh '''
docker run --rm ghcr.io/takitsu21/speedtest:latest \
--json-output results.json
'''
archiveArtifacts artifacts: 'results.json'
}
}
}
}
Monitoring Integration¶
Prometheus Exporter¶
Create a simple exporter script:
#!/bin/bash
# Run speedtest and convert to Prometheus metrics
RESULTS=$(docker run --rm ghcr.io/takitsu21/speedtest:latest --json)
echo "# HELP speedtest_download_mbps Download speed in Mbps"
echo "# TYPE speedtest_download_mbps gauge"
echo "speedtest_download_mbps $(echo $RESULTS | jq -r '.download')"
echo "# HELP speedtest_upload_mbps Upload speed in Mbps"
echo "# TYPE speedtest_upload_mbps gauge"
echo "speedtest_upload_mbps $(echo $RESULTS | jq -r '.upload')"
echo "# HELP speedtest_ping_ms Ping latency in milliseconds"
echo "# TYPE speedtest_ping_ms gauge"
echo "speedtest_ping_ms $(echo $RESULTS | jq -r '.ping')"
InfluxDB Integration¶
import subprocess
import json
from influxdb import InfluxDBClient
# Run speedtest
result = subprocess.run(
['docker', 'run', '--rm', 'ghcr.io/takitsu21/speedtest:latest', '--json'],
capture_output=True,
text=True
)
data = json.loads(result.stdout)
# Write to InfluxDB
client = InfluxDBClient(host='localhost', port=8086, database='speedtest')
point = {
"measurement": "speed",
"fields": {
"download": data['download'],
"upload": data['upload'],
"ping": data['ping'],
"jitter": data['jitter']
}
}
client.write_points([point])
Troubleshooting¶
Image Pull Issues¶
Problem: Cannot pull image
Solutions:
# Try with explicit registry
docker pull ghcr.io/takitsu21/speedtest:latest
# Check network connectivity
ping ghcr.io
# Login if private (not needed for this public image)
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
Permission Denied¶
Problem: Docker permission errors on Linux
Solution:
# Add user to docker group
sudo usermod -aG docker $USER
# Logout and login again, or:
newgrp docker
# Or use Podman (rootless by default)
podman run --rm -it ghcr.io/takitsu21/speedtest:latest
Slow Test Execution¶
Problem: Tests take too long in container
Possible Causes: - Container networking overhead - Resource limits - Network configuration
Solutions:
# Use host networking
docker run --rm -it --network host ghcr.io/takitsu21/speedtest:latest
# Increase container resources
docker run --rm -it --memory 512m --cpus 2 ghcr.io/takitsu21/speedtest:latest
# Use smaller test sizes
docker run --rm -it ghcr.io/takitsu21/speedtest:latest -ds 25 -us 10
No Output¶
Problem: Container runs but shows no output
Solutions:
# Ensure -it flags are used
docker run --rm -it ghcr.io/takitsu21/speedtest:latest
# Check container logs
docker ps -a
docker logs <container-id>
# Run with explicit shell
docker run --rm -it ghcr.io/takitsu21/speedtest:latest sh -c "speedtest-cli"
Best Practices¶
1. Use Specific Tags¶
# ✅ Good - version pinning
docker run --rm -it ghcr.io/takitsu21/speedtest:1.2.3
# ⚠️ Acceptable - latest
docker run --rm -it ghcr.io/takitsu21/speedtest:latest
2. Resource Limits¶
docker run --rm -it \
--memory 256m \
--cpus 0.5 \
ghcr.io/takitsu21/speedtest:latest
3. Cleanup Old Images¶
# Remove unused images
docker image prune -a
# Remove specific version
docker rmi ghcr.io/takitsu21/speedtest:old-version
4. Security¶
# Run as non-root (image already does this)
# Use read-only filesystem when possible
docker run --rm -it --read-only ghcr.io/takitsu21/speedtest:latest
# Drop capabilities
docker run --rm -it --cap-drop=ALL ghcr.io/takitsu21/speedtest:latest
Comparison: Container vs. Native¶
| Aspect | Container | Native Installation |
|---|---|---|
| Setup | Pull image only | Install Python + packages |
| Isolation | Fully isolated | System packages |
| Updates | Pull new image | Package upgrade |
| Portability | Highly portable | Python dependency |
| Performance | Slight overhead | Native speed |
| Networking | May affect latency | Direct access |
| Disk Space | ~200 MB | ~50 MB |
Use Containers When: - CI/CD pipelines - Consistent environments needed - Multiple versions required - Easy cleanup desired - Kubernetes/cloud deployments
Use Native When: - Development - Frequent testing - Minimal overhead required - Direct system access needed
Next Steps¶
- Usage Guide - Learn all CLI options
- Features - Explore capabilities
- API Reference - Programmatic usage
- Contributing - Build from source
- FAQ - Common questions