Files
container-census/docker-compose.collector.example.yml
T
Self Hosters 28a6fbd082 Huge updates:
1. Added optional security to the UI for the server and telemtry collector
2. Expanded the telemetry being collected and the telemetry UI accordingly
3. Documentation update
4. Enhanced charting
2025-10-16 18:50:21 -04:00

221 lines
7.3 KiB
YAML

# Example Docker Compose for Telemetry Collector
# Self-hosted analytics dashboard for Container Census telemetry
version: '3.8'
services:
# PostgreSQL database for telemetry data
telemetry-db:
image: postgres:15-alpine
container_name: telemetry-postgres
restart: unless-stopped
environment:
POSTGRES_DB: telemetry
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- telemetry-data:/var/lib/postgresql/data
networks:
- telemetry-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# Telemetry collector with analytics dashboard
telemetry-collector:
image: ghcr.io/selfhosters-cc/telemetry-collector:latest
container_name: telemetry-collector
restart: unless-stopped
ports:
- "${COLLECTOR_PORT:-8081}:8081"
environment:
# PostgreSQL connection
DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-changeme}@telemetry-db:5432/telemetry?sslmode=disable
# Server port
PORT: 8081
# Dashboard authentication (optional)
# If enabled, only the dashboard UI requires auth - APIs remain public
COLLECTOR_AUTH_ENABLED: ${COLLECTOR_AUTH_ENABLED:-false}
COLLECTOR_AUTH_USERNAME: ${COLLECTOR_AUTH_USERNAME:-admin}
COLLECTOR_AUTH_PASSWORD: ${COLLECTOR_AUTH_PASSWORD:-changeme}
# Timezone
TZ: ${TZ:-UTC}
depends_on:
telemetry-db:
condition: service_healthy
networks:
- telemetry-network
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8081/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
volumes:
telemetry-data:
name: telemetry-data
networks:
telemetry-network:
name: telemetry-network
driver: bridge
# ==============================================================================
# Quick Start
# ==============================================================================
#
# 1. Create .env file with your settings:
# cat > .env << 'EOF'
# POSTGRES_PASSWORD=your-secure-db-password
# COLLECTOR_PORT=8081
# COLLECTOR_AUTH_ENABLED=true
# COLLECTOR_AUTH_USERNAME=admin
# COLLECTOR_AUTH_PASSWORD=your-dashboard-password
# TZ=America/New_York
# EOF
#
# 2. Start the telemetry system:
# docker-compose -f docker-compose.collector.example.yml up -d
#
# 3. Access dashboard:
# Open http://localhost:8081
# (Login with COLLECTOR_AUTH_USERNAME/PASSWORD if auth enabled)
#
# 4. Configure Census Server to submit telemetry:
# In your Census Server's config/config.yaml:
#
# telemetry:
# enabled: true
# interval_hours: 168 # Weekly
# endpoints:
# - name: private
# url: http://YOUR_COLLECTOR_IP:8081/api/ingest
# enabled: true
#
# ==============================================================================
# Authentication Model
# ==============================================================================
#
# The telemetry collector has a unique auth model:
#
# PUBLIC (No Auth Required):
# - POST /api/ingest - Anonymous telemetry submission
# - GET /api/stats/* - Read-only analytics data
# - GET /health - Health check
#
# PROTECTED (Requires Basic Auth if COLLECTOR_AUTH_ENABLED=true):
# - GET / - Dashboard UI (HTML/CSS/JS)
# - GET /index.html - Dashboard files
# - GET /app.js - Dashboard files
# - GET /styles.css - Dashboard files
#
# This allows:
# ✓ Anyone to submit telemetry anonymously
# ✓ Anyone to query stats via API
# ✓ Only authenticated users to view the dashboard UI
#
# ==============================================================================
# Available Endpoints
# ==============================================================================
#
# Telemetry Submission:
# POST /api/ingest - Submit telemetry data
#
# Analytics APIs:
# GET /api/stats/summary - Overall statistics
# GET /api/stats/top-images?days=30&limit=20
# GET /api/stats/growth?days=90
# GET /api/stats/installations?days=30
# GET /api/stats/registries?days=30
# GET /api/stats/versions
# GET /api/stats/scan-intervals
# GET /api/stats/activity-heatmap?days=30
# GET /api/stats/geography?days=30
#
# Dashboard Features:
# • Summary cards (installations, submissions, containers, hosts, agents, images)
# • Top 20 container images chart
# • Installation growth over time
# • Registry distribution (Docker Hub, GHCR, etc.)
# • Agent version adoption
# • Scan interval configuration
# • Activity heatmap by day/hour
# • Geographic distribution by timezone (privacy-friendly)
#
# ==============================================================================
# Management Commands
# ==============================================================================
#
# View logs:
# docker-compose -f docker-compose.collector.example.yml logs -f
# docker-compose -f docker-compose.collector.example.yml logs -f telemetry-collector
#
# Stop services:
# docker-compose -f docker-compose.collector.example.yml down
#
# Restart services:
# docker-compose -f docker-compose.collector.example.yml restart
#
# Access PostgreSQL:
# docker exec -it telemetry-postgres psql -U postgres -d telemetry
#
# Backup database:
# docker exec telemetry-postgres pg_dump -U postgres telemetry > backup-$(date +%Y%m%d).sql
#
# Restore database:
# cat backup.sql | docker exec -i telemetry-postgres psql -U postgres -d telemetry
#
# Check database size:
# docker exec telemetry-postgres psql -U postgres -d telemetry -c "SELECT pg_size_pretty(pg_database_size('telemetry'));"
#
# ==============================================================================
# Data Retention & Deduplication
# ==============================================================================
#
# The collector uses a 7-day deduplication window:
# - Same installation submitting within 7 days → UPDATE existing record
# - Same installation submitting after 7+ days → INSERT new record
#
# This means:
# - Weekly submissions from 1 installation = ~52 records/year
# - Daily submissions from 1 installation = ~52 records/year (deduplicated)
# - Balances data retention with storage efficiency
#
# Charts show latest data per installation using DISTINCT ON queries.
#
# ==============================================================================
# Security Notes
# ==============================================================================
#
# Production Checklist:
# ☐ Change POSTGRES_PASSWORD from default
# ☐ Set COLLECTOR_AUTH_ENABLED=true
# ☐ Use strong COLLECTOR_AUTH_PASSWORD
# ☐ Place behind reverse proxy with HTTPS/TLS
# ☐ Configure firewall rules (only allow Census servers to reach port 8081)
# ☐ Set up regular database backups
# ☐ Monitor disk space (PostgreSQL data volume)
# ☐ Use Docker secrets instead of .env for credentials
#
# Network Security:
# - API endpoints are intentionally public for anonymous telemetry
# - Protect at network level (firewall, VPN, reverse proxy)
# - Consider IP whitelisting if you know source IPs
#