Monitor your home internet speeds with the Ookla Speedtest CLI.
0

Configure Feed

Select the types of activity you want to include in your feed.

Add configurable user permissions for non-root execution

Allow container to run with specific UID/GID to match host user
permissions, preventing file ownership issues with mounted volumes.

Key changes:
- Add UID/GID environment variables to docker-compose.yml
- Modify Dockerfile to support arbitrary user IDs (chmod 777 on dirs)
- Update nginx config to run without root (disable user directive)
- Copy speedtest license to user's home at runtime
- Use /tmp for HOME directory when running as non-root
- Document usage in README with id -u/id -g examples

Default remains 1000:1000 but can be overridden via:
UID=1000 GID=1000 docker-compose up -d

Joseph Hale (Feb 17, 2026, 2:37 PM -0700) 3efdfede 2c76b4b8

+49 -15
+5
.env.example
··· 1 1 # Speedtest configuration 2 2 CRON_SCHEDULE=*/30 * * * * 3 + 4 + # User permissions (defaults to current user) 5 + # Set these to match your host user to ensure proper file permissions 6 + UID=1000 7 + GID=1000
+14 -10
Dockerfile
··· 18 18 fi && \ 19 19 chmod +x /usr/local/bin/speedtest 20 20 21 - # Accept license automatically 22 - RUN mkdir -p /root/.config/ookla && \ 23 - echo '{"Settings": {"LicenseAccepted": "604ec14274326065ea260afd5035643b"}}' > /root/.config/ookla/speedtest-cli.json 21 + # Create directories with wide permissions for any UID 22 + RUN mkdir -p /data /app /tmp/.config/ookla && \ 23 + chmod 777 /data /tmp && \ 24 + chmod -R 777 /tmp/.config 24 25 25 - # Create directories 26 - RUN mkdir -p /data /app 26 + # Accept license automatically (will be copied to user's home at runtime) 27 + RUN echo '{"Settings": {"LicenseAccepted": "604ec14274326065ea260afd5035643b"}}' > /tmp/speedtest-cli.json 27 28 28 29 # Copy application files 29 30 COPY speedtest_runner.sh /app/ 30 31 COPY generate_html.sh /app/ 31 32 COPY entrypoint.sh /app/ 32 - RUN chmod +x /app/*.sh 33 + RUN chmod +x /app/*.sh && chmod 777 /app 34 + 35 + # Create nginx config that works with non-root user 36 + RUN sed -i 's/listen 80;/listen 8080;/g' /etc/nginx/conf.d/default.conf && \ 37 + sed -i 's/listen \[::\]:80;/listen [::]:8080;/g' /etc/nginx/conf.d/default.conf && \ 38 + sed -i 's/user nginx;/# user nginx;/g' /etc/nginx/nginx.conf && \ 39 + sed -i '/pid/d' /etc/nginx/nginx.conf 33 40 34 41 # Environment variables with defaults 35 42 ENV CRON_SCHEDULE="*/30 * * * *" 36 43 ENV DATA_FILE="/data/speedtest.csv" 37 44 ENV HTML_FILE="/usr/share/nginx/html/index.html" 38 - 39 - # Nginx configuration for port 8080 40 - RUN sed -i 's/listen 80;/listen 8080;/g' /etc/nginx/conf.d/default.conf && \ 41 - sed -i 's/listen \[::\]:80;/listen [::]:8080;/g' /etc/nginx/conf.d/default.conf 45 + ENV HOME=/tmp 42 46 43 47 # Expose web port 44 48 EXPOSE 8080
+16
README.md
··· 35 35 | Environment Variable | Default | Description | 36 36 |---------------------|---------|-------------| 37 37 | `CRON_SCHEDULE` | `*/30 * * * *` | Cron expression for test frequency | 38 + | `UID` | `1000` | User ID to run as (match host user) | 39 + | `GID` | `1000` | Group ID to run as (match host user) | 40 + 41 + ### Running as Current User 42 + 43 + To run the container with your current user's permissions: 44 + 45 + ```bash 46 + # Option 1: Set in .env file 47 + echo "UID=$(id -u)" >> .env 48 + echo "GID=$(id -g)" >> .env 49 + docker-compose up -d 50 + 51 + # Option 2: Pass directly on command line 52 + UID=$(id -u) GID=$(id -g) docker-compose up -d 53 + ``` 38 54 39 55 ### Cron Schedule Examples 40 56
+2
docker-compose.yml
··· 4 4 speedtest: 5 5 build: . 6 6 container_name: speedtest 7 + user: "${UID:-1000}:${GID:-1000}" 7 8 ports: 8 9 - "${HTTP_PORT:-8080}:8080" 9 10 volumes: 10 11 - ./data:/data 11 12 environment: 12 13 - CRON_SCHEDULE=${CRON_SCHEDULE:-*/30 * * * *} 14 + - HOME=/tmp 13 15 restart: unless-stopped
+12 -5
entrypoint.sh
··· 1 1 #!/bin/bash 2 2 set -e 3 3 4 + # Setup home directory for current user 5 + export HOME=${HOME:-/tmp} 6 + mkdir -p "$HOME/.config/ookla" 7 + cp /tmp/speedtest-cli.json "$HOME/.config/ookla/" 8 + 4 9 # Setup cron job 5 10 CRON_SCHEDULE="${CRON_SCHEDULE:-*/30 * * * *}" 6 11 echo "Setting up speedtest cron job with schedule: $CRON_SCHEDULE" 7 12 8 - # Create crontab file 9 - echo "$CRON_SCHEDULE /app/speedtest_runner.sh >> /var/log/speedtest.log 2>&1" > /etc/crontabs/root 13 + # Create crontab file for current user 14 + mkdir -p /tmp/crontabs 15 + echo "$CRON_SCHEDULE /app/speedtest_runner.sh >> /var/log/speedtest.log 2>&1" > /tmp/crontabs/speedtest 10 16 11 17 # Create log file 12 18 touch /var/log/speedtest.log ··· 15 21 /app/generate_html.sh 16 22 17 23 # Start nginx 18 - nginx 24 + nginx -g 'daemon off;' & 25 + NGINX_PID=$! 19 26 20 27 # Run initial speedtest 21 28 /app/speedtest_runner.sh 22 29 23 - # Start cron in foreground (using busybox crond) 30 + # Start cron in foreground (using busybox crond with user crontab) 24 31 echo "Starting cron daemon..." 25 - crond -f -l 8 -L /var/log/cron.log 32 + crond -f -l 8 -L /var/log/cron.log -c /tmp/crontabs