- Add Community Analytics card to Next.js dashboard with toggle switch - Expand telemetry settings page with collector management (add/remove/enable/disable) - Add version_checks table to telemetry collector Database tab for viewing update checks - Add telemetry types and API functions to Next.js frontend 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Container Census
Discover. Visualize. Track. Compare.
Container Census is a lightweight, Go-powered tool that automatically scans your Docker environment across one or many hosts and gives you a clear, historical view of everything running in your stack.
Community stats on container usage can be found here: Selfhosters Stats
Dashboard
View / Manage Containers
Manage Multipe Hosts with Agents
View History of Container
Visualize relationships / networks / links / dependencies
Security Overview
Vulnerabilities Overview
Keep Images Up To Date
Manage Telemetry Collection
Can enable public collection (Selfhosters Stats) or send telemetry information to your own private collector.
Want deeper insights?
Graph view
See how your containers are connected to each other via networks, dependencies, and links.
Multiple Hosts? No problem!
Run lightweight agents on remote hosts to feed data back to your private Telemetry Collector, or choose to anonymously share usage stats with the Selfhosters community to see what’s trending across thousands of self-hosted environments worldwide.
Privacy First
Anonymous telemetry is opt-in only and can be enabled anytime from the Settings page.
Key Features
- Multi-Host Scanning – Monitor every Docker host from one unified dashboard
- Lightweight Remote Agents – Secure, zero-config connectivity between hosts
- Simple Web Setup – Add new hosts with just an IP and token
- Automatic Discovery – Background scans every few minutes (default: 5)
- Image Update Management – Check for and apply updates to containers with :latest tags
- CPU & Memory Monitoring – Real-time resource usage tracking with historical trends
- Historical Insights – Track what's running, when, and where
- Modern Web UI – Responsive interface with live updates
- Full REST API – Query all container and host data programmatically
- Prometheus Metrics – Export metrics for Grafana and monitoring tools
- Container Control – Start, stop, restart, remove containers, and view logs
- Image Management – List, remove, or prune images across hosts
- Single-Container Deployment – Everything you need in one small footprint (agents and aggregated stats available in separate containers)
- Flexible Connectivity – Agent (recommended), Unix socket, TCP, or SSH
- Community / Private Telemetry (Optional) – Discover popular and trending images worldwide
Quick Start With Docker Compose
Server (required)
census-server:
image: ghcr.io/selfhosters-cc/container-census:latest
container_name: census-server
restart: unless-stopped
group_add:
- "${DOCKER_GID:-999}"
ports:
- "8080:8080"
volumes:
# Docker socket for scanning local containers
- /var/run/docker.sock:/var/run/docker.sock
# Persistent data directory (database, settings, scans)
- ./census/server:/app/data
environment:
# Server Configuration (optional, defaults shown)
# SERVER_HOST: "0.0.0.0"
# SERVER_PORT: "8080"
# DATABASE_PATH: "./data/census.db"
# Authentication (optional, disabled by default)
# AUTH_ENABLED: "false"
# AUTH_USERNAME: "your_username"
# AUTH_PASSWORD: "your_secure_password"
# SESSION_SECRET: "change-me-in-production" # Required if AUTH_ENABLED=true
# Timezone for telemetry reporting
TZ: ${TZ:-UTC}
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/api/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
Note
: All application settings (scanner interval, vulnerability scanning, telemetry endpoints, etc.) are now managed through the Web UI or API. The config file is only used for one-time migration from older versions.
Agent to collect data from other hosts
census-agent:
image: ghcr.io/selfhosters-cc/census-agent:latest
container_name: census-agent
restart: unless-stopped
# Runtime Docker socket GID configuration
group_add:
- "${DOCKER_GID:-999}"
ports:
- "9876:9876"
volumes:
# Docker socket for local container management
- /var/run/docker.sock:/var/run/docker.sock
# Optional: Persistent data directory for API token
# Only needed if NOT using API_TOKEN environment variable
# - ./census/agent:/app/data
environment:
# API Token (choose one method):
# Method 1: Set via environment variable (recommended - no volume needed)
API_TOKEN: ${AGENT_API_TOKEN:-your-secure-token-here}
# Method 2: Leave empty to auto-generate and persist to volume
# Requires mounting ./census/agent:/app/data volume above
PORT: 9876
TZ: ${TZ:-UTC}
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9876/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
Agent Configuration
API Token - Choose Your Method:
The agent supports multiple ways to configure the API token, in priority order:
-
Environment Variable (Recommended) - Set
API_TOKENenvironment variable- No volume mount needed
- Perfect for Kubernetes, Docker Swarm, or managed container platforms
- Token persists as long as the environment variable is set
- Example:
API_TOKEN=your-secure-token-here
-
File Persistence - Mount volume at
/app/data- Token auto-generated on first startup
- Persisted to
/app/data/agent-token - Survives container restarts and upgrades
- Useful when you want the agent to manage its own token
-
Command-line Flag - Pass
--tokenflag when running the container- Example:
./census-agent --token=your-token
- Example:
-
Auto-generate (Ephemeral) - No volume, no env var
- New token generated on each restart
- Requires updating the census server UI after each restart
- Not recommended for production
Get the API token:
# If using auto-generated token (method 2 or 4)
docker logs census-agent | grep "API Token"
# If using environment variable (method 1)
echo $AGENT_API_TOKEN
Add agent in the Census Server UI:
- Click "+ Add Agent Host" button
- Enter host name, agent URL (
http://host-ip:9876), and token - Click "Test Connection" then "Add Agent"
Telemetry & Analytics
Container Census includes an optional telemetry system to track anonymous container usage statistics. This helps understand trends and allows you to monitor your own infrastructure.

Key Features
- Anonymous data collection - No personal information collected
- Multi-endpoint support - Send to public and/or private analytics servers
- Self-hosted analytics - Run your own telemetry collector
- Visual dashboards - Charts showing popular images, growth trends
- Opt-in by default - Disabled unless explicitly enabled
- Server aggregation - Server collects stats from all agents before submission
Run Your Own Analytics Server
telemetry-collector:
image: ghcr.io/selfhosters-cc/telemetry-collector:latest
container_name: telemetry-collector
restart: unless-stopped
ports:
- "8081:8081"
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@telemetry-postgres:5432/telemetry?sslmode=disable
PORT: 8081
#API_KEY: ${TELEMETRY_API_KEY:-}
TZ: ${TZ:-UTC}
COLLECTOR_AUTH_ENABLED: true
COLLECTOR_AUTH_USERNAME: collector_user
COLLECTOR_AUTH_PASSWORD: collector_secure_password
depends_on:
telemetry-postgres:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8081/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
telemetry-postgres:
image: postgres:15-alpine
container_name: telemetry-postgres
restart: unless-stopped
environment:
POSTGRES_DB: telemetry
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- ./telemetry-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# Access dashboard
open http://localhost:8081
CPU & Memory Monitoring
Container Census includes comprehensive resource monitoring with historical trending capabilities:
Features
- Real-time Stats Collection - CPU and memory usage collected during each scan
- Per-Host Configuration - Enable/disable stats collection for each host individually
- Two-tier Data Retention:
- Granular data: All scans kept for 1 hour
- Aggregated data: Hourly averages kept for 2 weeks
- Interactive Charts - View trends over 1h, 24h, 7d, or all time
- Sparkline Previews - Quick glance at trends in the monitoring grid
- Prometheus Metrics - Export to Grafana and other monitoring tools
- All Connection Types - Works with local socket, agents, TCP, and SSH
Configuration
Enable stats collection per host:
- Navigate to the Hosts tab
- Click on the stats badge for any host to toggle collection
- Stats collection begins on the next scan
Adjust scan interval:
- Navigate to the Settings tab
- Select desired interval (1-15 minutes)
- Click Save Interval
Note: Stats collection adds minimal overhead but can be disabled for low-resource hosts.
Viewing Stats
Monitoring Tab:
- Grid view of all running containers with stats enabled
- Mini sparkline charts showing recent CPU and memory trends
- Quick summary of current usage
- Filter to show only containers from enabled hosts
Detailed Stats Modal:
- Click View Detailed Stats on any container
- Select time range: 1 hour, 24 hours, 7 days, or all time
- Dual-axis charts with CPU % and Memory MB
- Average, minimum, and maximum values displayed
API Endpoints for the Server
Hosts
GET /api/hosts- List all configured hostsGET /api/hosts/{id}- Get specific host details
Containers
GET /api/containers- Get latest containers from all hostsGET /api/containers/host/{id}- Get containers for specific hostGET /api/containers/history?start=TIME&end=TIME- Get historical container data
Resource Monitoring
GET /api/containers/{host_id}/{container_id}/stats?range={1h|24h|7d|all}- Get container stats historyGET /api/metrics- Prometheus-formatted metrics endpoint
Configuration
GET /api/config- Get current configuration including scanner intervalPOST /api/config/scanner- Update scanner interval (JSON:{"interval_seconds": 300})
Scanning
POST /api/scan- Trigger a manual scanGET /api/scan/results?limit=N- Get recent scan results
Health
GET /api/health- Health check endpoint
Development
Building Images
Use the interactive build-all-images.sh script in the scripts folder.
Project Structure
cmd/server/main.go- Server application entry pointcmd/agent/main.go- Agent application entry pointinternal/scanner/- Docker host connection and container discoveryinternal/agent/- Agent server implementationinternal/storage/- SQLite database operations with full CRUDinternal/api/- HTTP handlers and routinginternal/models/- Data structures shared across packagesweb/- Static frontend files served by the Go applicationscripts/- Utility scripts for building and deployment
Adding New Features
- Update models in
internal/models/models.go - Add database operations in
internal/storage/db.go - Implement API handlers in
internal/api/handlers.go - Update frontend in
web/directory
Troubleshooting
Authentication Issues
Finding your credentials: If you've enabled authentication and don't know your username/password, check the Docker container environment variables:
docker exec census-server env | grep AUTH_
This will show:
AUTH_USERNAME- Your usernameAUTH_PASSWORD- Your passwordAUTH_ENABLED- Whether auth is enabled
Browser keeps asking for login:
- Clear your browser cookies for the Census URL
- Try an incognito/private window
- Check that
SESSION_SECRETis set in your environment variables
API clients getting 401 errors: Census supports both session-based (browser) and Basic Auth (API clients):
- For browsers: Use the login page at
/login.html - For API clients: Include
Authorization: Basic <base64(username:password)>header
Cannot connect to Docker daemon
- Ensure Docker socket is mounted:
-v /var/run/docker.sock:/var/run/docker.sock - Check socket permissions
- Verify Docker is running on the host
- Ensure DOCKER_GID is set accurately. Defaults to 999. Confirm value on your system with
stat -c '%g' /var/run/docker.sockand set the value in your compose file
Permission denied
- The container runs as non-root user (UID 1000)
- Ensure mounted volumes have correct permissions
- For Docker socket, user needs to be in
dockergroup on host
Remote host connection fails
- Verify network connectivity
- Check firewall rules
- For TCP: Ensure Docker API is exposed on remote host
Database errors
- Ensure data directory is writable
- Check disk space
- Verify SQLite3 is properly compiled (CGO_ENABLED=1)
License
MIT License - see LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request








