← NewTon DC Tournament Manager

Docker Quick Start

Get NewTon DC Tournament Manager running in Docker in under 2 minutes.

Quick Start

Prerequisites: Docker and Docker Compose installed. Don't have Docker? Download Docker Desktop (macOS/Windows) or install via your package manager (Linux).

mkdir newton-tournament
cd newton-tournament

curl -O https://raw.githubusercontent.com/skrodahl/NewTon/main/docker/docker-compose.yml
docker compose up -d

Open http://localhost:8080 — NewTon is running.

Port 2020 = “Double 20” — nginx runs on port 2020 internally. The default host port (8080) maps to this.

Camera / QR scanning requires HTTPS. The quick start runs HTTP only. Pick one of the three setups below to enable camera access.


Setup Options

Image tag: All compose files below use skrodahl/newton:latest (Docker Hub) with GHCR as a commented alternative.

SSL (All Platforms)

SSL enabled by default — gives you HTTPS and camera access on any platform.

services:
  newton-tournament:
    image: skrodahl/newton:latest
    # Alternative: ghcr.io/skrodahl/newton:latest
    container_name: newton
    ports:
      - "2020:2020"   # HTTP — redirects to HTTPS
      - "443:443"     # HTTPS
    volumes:
      - ./tournaments:/var/www/html/tournaments
      - ./images:/var/www/html/images:ro
      - newton-ssl:/etc/nginx/ssl    # Persists the auto-generated certificate
    restart: unless-stopped
    environment:
      - TZ=Europe/Oslo
      - SSL_ENABLED=true             # Auto-generates a self-signed cert (30-year, SAN)
      - NEWTON_API_ENABLED=true      # Set false to disable tournament upload/download
      - NEWTON_DEMO_MODE=false       # Set true to show a privacy banner
      # - NEWTON_LANDING_PAGE=true   # Show landing page at root URL
      # - NEWTON_BASE_URL=https://darts.example.com

volumes:
  newton-ssl:

Save as docker-compose.yml in a folder of your choice, then run docker compose up -d. That’s it.

Access at https://localhost. Your browser will warn about the self-signed certificate on first visit — accept the exception once and it will not appear again.

LAN Access via <hostname>.local

Phones, tablets, and scoring stations on the same network can reach the container by name (e.g. https://newtondarts.local) once mDNS is set up on the host. macOS has Bonjour built in; Linux needs avahi-daemon; Windows needs Bonjour installed. See Docs/MDNS.md for full setup steps.


Behind a Reverse Proxy

The container joins your proxy’s Docker network. SSL termination and HTTPS are handled by the proxy — no SSL_ENABLED needed.

services:
  newton-tournament:
    image: skrodahl/newton:latest
    # Alternative: ghcr.io/skrodahl/newton:latest
    container_name: newton
    # ports:
    #   - "8080:2020"  # Remove when using a reverse proxy
    networks:
      - proxy_network
    volumes:
      - ./tournaments:/var/www/html/tournaments
      - ./images:/var/www/html/images:ro
    restart: unless-stopped
    environment:
      - TZ=Europe/Oslo
      - NEWTON_API_ENABLED=true
      - NEWTON_DEMO_MODE=false
      # - NEWTON_LANDING_PAGE=true
      # - NEWTON_BASE_URL=https://darts.example.com

networks:
  proxy_network:
    external: true

Save as docker-compose.yml in a folder of your choice, then run docker compose up -d. That’s it.

In Nginx Proxy Manager, point the proxy host to newton:2020.

Camera Access Behind NPM

NPM sets its own Permissions-Policy header that overrides the container’s, blocking camera access in the Chalker. Add this to the Advanced tab of your NPM proxy host:

more_set_headers "Permissions-Policy: geolocation=(), microphone=(), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=(), ambient-light-sensor=()";

more_set_headers replaces the header rather than adding a duplicate. OpenResty (which NPM runs on) includes the headers-more module, so this directive is available without any additional setup.

Demo / Public Site

environment:
  - NEWTON_API_ENABLED=false   # Disable upload API for security
  - NEWTON_DEMO_MODE=true      # Show privacy banner
  - NEWTON_LANDING_PAGE=true   # Show landing page at root

Analytics Instance

A read-only analytical surface — browse leaderboards, match history, and brackets. Tournament data comes from shared tournament files on disk. No tournament management tabs, no deletion. Accepts tournament uploads from venue instances via the relay API.

environment:
  - NEWTON_API_ENABLED=true            # Required for auto-import and bracket view
  - NEWTON_MODE=analytics              # Analytics-only mode

Mount the ./tournaments and ./images volumes. Configure the venue instance to auto-backup to this server’s relay API, or share the same tournaments directory. See Automatic Backup for the full setup guide.


Environment Variables

VariableDefaultDescription
SSL_ENABLEDfalseAuto-generates a self-signed certificate; enables HTTPS on HTTPS_PORT and redirects HTTP on HTTP_PORT
HTTP_PORT2020HTTP listening port (redirects to HTTPS when SSL enabled)
HTTPS_PORT443HTTPS listening port
SSL_HOSTNAMEnewtondartsHostname used in the auto-generated SSL certificate’s Subject Alternative Name. Set this to match the .local hostname you advertise via mDNS — see Docs/MDNS.md. Falls back to deprecated MDNS_HOSTNAME if unset.
NEWTON_API_ENABLEDtrueEnables REST API endpoints for tournament upload, download, and delete
NEWTON_MODEfullApp mode. analytics hides tournament management tabs, shows only Analytics and limited Global Settings
NEWTON_DEMO_MODEfalseShows a privacy banner at the top of the app
NEWTON_LANDING_PAGEfalseShows a landing page at the root URL instead of loading the app directly
NEWTON_BASE_URLunsetCanonical URL for Open Graph and Twitter Card meta tags on the landing page
NEWTON_GITHUB_URLgithub.com/skrodahl/NewTonGitHub link shown in the demo banner
NEWTON_HOST_PORT8080Host port for the basic HTTP compose (quick start only)

Security

REST API

The REST API has no built-in authentication. Do not expose the container directly to the public internet without additional protection. Safe options:

Security Headers

The Docker image includes comprehensive security headers enabled by default — no configuration needed:

NewTon DC Tournament Manager achieves an A grade on securityheaders.com out of the box.

HSTS

Strict-Transport-Security is included automatically when SSL_ENABLED=true. It is not set in HTTP-only mode to avoid breaking non-SSL deployments.

When terminating HTTPS at a reverse proxy, add HSTS there instead:

# Nginx Proxy Manager — Advanced tab
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Customization

Logo and Payment QR Code

Place your own files in the images/ folder. The images/ volume is mounted read-only from the host, so changes are picked up immediately — no container restart needed.

mkdir -p images

# Custom logo — supports .png, .jpg, .jpeg, or .svg
cp /path/to/your/logo.jpg ./images/logo.jpg

# Custom payment QR code
cp /path/to/your/payment-qr.png ./images/payment.png

Default images bundled in the Docker image: images/logo.jpg (club logo placeholder) and images/payment.png (GitHub project QR code). Need a payment QR? Use the QR Code Generator — transparent background, no signup required.


Troubleshooting

Port Already in Use

NEWTON_HOST_PORT=9000 docker compose up -d

Container Won’t Start

docker compose logs

Can’t Access http://localhost:8080

  1. Verify the container is running: docker compose ps — should show 0.0.0.0:8080->2020/tcp
  2. Try http://127.0.0.1:8080 instead of localhost
  3. Check logs: docker compose logs

Browser Warning on https://localhost

Expected with a self-signed certificate. Accept the exception once — it will not appear again. The cert is stored in the newton-ssl named volume and persists across restarts.

<hostname>.local Not Reachable

mDNS resolution is a host-side concern, not handled by the container. See Docs/MDNS.md for full setup. Quick checks:


Need Help?