Self-Hosted Docker Management Platform
A modern, feature-rich platform for managing Docker infrastructure across single and multi-node deployments.
Fast Deploy • Features • Screenshots • Deployment • Configuration • API • Architecture • Contributing
v26.2.7 — Latest Release
usulnet is in active development. We appreciate your feedback — please report any issues on GitHub Issues. Your reports help improve usulnet for everyone.
usulnet is built and maintained only by me at the moment. If you find it useful, consider supporting its continued development:
| Channel | Description |
|---|---|
| Buy Me a Coffee | One-time or recurring donations to support development |
| Business License | Purchase a Business or Enterprise license starting at €79/node/year |
| GitHub Sponsors | Sponsor via GitHub for recurring monthly support |
Every contribution, whether a coffee, a license purchase, or a star on GitHub, help to keep this project alive and growing. Thank you.
Deploy usulnet in one command. No manual configuration needed — all secrets are generated automatically.
curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/install.sh | sudo bashThis will:
- Download the production Docker Compose configuration
- Auto-generate secure database passwords, JWT secrets, and encryption keys
- Start usulnet with PostgreSQL, Redis, NATS, Nginx, and Guacamole
- Be ready in under 60 seconds (pre-built images, no compilation)
Access: https://your-server-ip:7443 — Default credentials: admin / usulnet
Or deploy manually with Docker Compose (requires sudo/root):
# Download the files
sudo mkdir -p /opt/usulnet && cd /opt/usulnet
sudo curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/docker-compose.prod.yml -o docker-compose.yml
sudo curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/.env.example -o .env
# IMPORTANT: download config.yaml — without this, Docker creates a directory and the app boot-loops
sudo curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/config.yaml -o config.yaml
# NATS server configuration (required — the compose file mounts this into the NATS container)
sudo curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/nats-server.conf -o nats-server.conf
# Generate secrets
DB_PASS=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
JWT_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
# Set database password in .env (used by PostgreSQL service)
sudo sed -i "s|CHANGE_ME_GENERATE_RANDOM_PASSWORD|${DB_PASS}|" .env
# Set secrets in config.yaml (used by usulnet application)
sudo sed -i "s|usulnet_dev|${DB_PASS}|" config.yaml
sudo sed -i "s|edbdbc0721315fc2529c04509d65c62e7c51ce9b10941078f2fae131acfb0e96|${JWT_SECRET}|" config.yaml
sudo sed -i "s|ed2cb601a830465890822d80d13668530b5af3c1c372799310339e8daf02e2e6|${ENCRYPTION_KEY}|" config.yaml
# Generate TLS certificates for PostgreSQL, Redis, and NATS (self-signed ECDSA P-256)
sudo mkdir -p certs
sudo openssl req -new -x509 -days 3650 -nodes \
-newkey ec -pkeyopt ec_paramgen_curve:P-256 \
-subj "/CN=postgres/O=usulnet" \
-addext "subjectAltName=DNS:postgres,DNS:localhost,IP:127.0.0.1" \
-keyout certs/postgres-server.key -out certs/postgres-server.crt 2>/dev/null
sudo openssl req -new -x509 -days 3650 -nodes \
-newkey ec -pkeyopt ec_paramgen_curve:P-256 \
-subj "/CN=redis/O=usulnet" \
-addext "subjectAltName=DNS:redis,DNS:localhost,IP:127.0.0.1" \
-keyout certs/redis-server.key -out certs/redis-server.crt 2>/dev/null
sudo openssl req -new -x509 -days 3650 -nodes \
-newkey ec -pkeyopt ec_paramgen_curve:P-256 \
-subj "/CN=nats/O=usulnet" \
-addext "subjectAltName=DNS:nats,DNS:localhost,IP:127.0.0.1" \
-keyout certs/nats-server.key -out certs/nats-server.crt 2>/dev/null
sudo chmod 600 certs/*.key
# Start
sudo docker compose up -dusulnet is a self-hosted Docker management platform built with Go that gives engineering teams full control over their container infrastructure. It replaces the need for multiple tools by providing a unified interface for container orchestration, security scanning, backup management, reverse proxy configuration, monitoring, and multi-node deployment — all from a single, modern web UI.
Designed for sysadmins, DevOps engineers, and platform teams who need a production-grade, self-hosted alternative to cloud-native container management solutions without vendor lock-in or usage telemetry.
- Single binary — No runtime dependencies like Node.js or Python. Templates are compiled into the binary at build time.
- Multi-node out of the box — Master/agent architecture with NATS messaging, mTLS, and auto-deployment of agents.
- Security-first — Built-in Trivy scanning, RBAC with 46 permissions, 2FA, LDAP/OIDC auth, encrypted secrets, audit logging.
- Full-stack management — Containers, images, volumes, networks, stacks, proxies, backups, SSH, databases, LDAP, Git — everything in one place.
- Lightweight — ~70 MB binary. No Electron, no bloated frontend frameworks. Pure Templ + Tailwind + Alpine.js + HTMX.
| Feature | Description |
|---|---|
| Containers | Full lifecycle management — create, start, stop, restart, pause, kill, remove. Bulk operations, real-time stats, settings editor, filesystem browser. |
| Images | Pull, inspect, remove, prune. Registry support (Docker Hub, private registries). Layer history and size analysis. |
| Volumes | Create, inspect, remove, prune. Built-in file browser for volume contents. |
| Networks | Create, inspect, remove, prune. Connect/disconnect containers. Bridge, overlay, macvlan support. |
| Stacks | Docker Compose deployment, management, and monitoring. Built-in stack catalog with one-click deployment. |
| Docker Swarm | Initialize clusters, manage nodes, create HA services, scale replicas, convert standalone containers. |
| Feature | Description |
|---|---|
| Vulnerability Scanning | Integrated Trivy scanner for container images and filesystems. CVE detection with severity classification. |
| Security Scoring | 0-100 composite security score per container and across the infrastructure. Trends tracking over time. |
| SBOM Generation | Software Bill of Materials in CycloneDX and SPDX formats. |
| RBAC | Role-based access control with 46 granular permissions. Custom roles. Team-based resource scoping. |
| 2FA / TOTP | Two-factor authentication with TOTP (Google Authenticator, Authy) and backup codes. |
| LDAP / OIDC | Enterprise authentication via Active Directory, LDAP, OAuth2, and OIDC (GitHub, Google, Microsoft, custom). |
| Audit Logging | User actions persisted to PostgreSQL with IP, timestamp, and details. Exportable as CSV. In-memory cache for fast dashboard rendering. |
| Encrypted Secrets | AES-256-GCM encryption for all sensitive configuration values (passwords, tokens, keys). |
| API Key Auth | Programmatic access via X-API-KEY header alongside JWT authentication. |
| Feature | Description |
|---|---|
| Real-time Metrics | CPU, memory, network I/O, disk I/O per container and per host. WebSocket-powered live dashboards. |
| Alert Rules | Threshold-based alerts on any metric. States: OK → Pending → Firing → Resolved. Silence rules. |
| 11 Notification Channels | Email, Slack, Discord, Telegram, Gotify, ntfy, PagerDuty, Opsgenie, Microsoft Teams, Generic Webhook, Custom. |
| Event Stream | Real-time Docker event stream (container, image, volume, network events) with filtering. |
| Centralized Logs | Aggregated container logs with search, filtering, and custom log file upload for analysis. |
| Prometheus Metrics | Native /metrics endpoint for Prometheus scraping (admin auth required). Go runtime and process metrics included. |
| Feature | Description |
|---|---|
| Backup Targets | Back up individual containers, volumes, or entire stacks. |
| Scheduled Backups | Cron-based backup scheduling with retention policies. |
| Storage Backends | Local filesystem, AWS S3, MinIO, Azure Blob, Google Cloud Storage, Backblaze B2, SFTP. |
| Compression | gzip or zstd compression with configurable levels. |
| One-click Restore | Restore any backup to its original or a different target. |
| Feature | Description |
|---|---|
| Operation Modes | master (full server), agent (worker node). |
| NATS Messaging | Inter-node communication via NATS with JetStream persistence. |
| Internal PKI & mTLS | Auto-generated certificates for secure agent-master communication. |
| Auto Agent Deploy | Deploy agents to remote hosts directly from the web UI via SSH. |
| Gateway Routing | API gateway automatically routes requests to the correct node. |
| Host Switching | Seamlessly switch between managed hosts from any page. |
| Feature | Description |
|---|---|
| Nginx Reverse Proxy | Built-in nginx reverse proxy with auto-HTTPS via Let's Encrypt. |
| Certificate Management | Let's Encrypt, custom certificates, auto-renewal, expiration alerts. |
| Stream Proxying | TCP/UDP stream proxy configuration for non-HTTP services. |
| Feature | Description |
|---|---|
| Embedded DNS Server | Built-in authoritative DNS server powered by miekg/dns (the library behind CoreDNS). UDP + TCP on configurable port. |
| Zone Management | Create and manage DNS zones (primary, secondary, forward) with full SOA configuration. Serial auto-increment on changes. |
| Record Types | A, AAAA, CNAME, MX, TXT, NS, SRV, PTR, CAA, SOA records with per-record TTL and enable/disable toggle. |
| TSIG Keys | Transaction Signature keys for secure zone transfers. Secrets encrypted at rest with AES-256-GCM. |
| Upstream Forwarding | Recursive queries forwarded to configurable upstream servers (default: Cloudflare 1.1.1.3 + 1.0.0.3 malware-blocking DNS). |
| Live Statistics | Real-time query counters (total, success, failed), zones loaded, and server uptime. Health check endpoint. |
| Audit Logging | All zone/record/key changes logged with user, action, resource, and timestamp. Browsable from the web UI. |
| Service Discovery | Auto-register containers as DNS A/SRV records — redis.containers.local → container IP |
| Feature | Description |
|---|---|
| Terminal Hub | Multi-tab terminal with container exec and host SSH in the browser (xterm.js). |
| Monaco Editor | Full VS Code editor experience in the browser for editing files inside containers and on hosts. |
| Neovim in Browser | Neovim with lazy.nvim plugin manager running directly in the browser via WebSocket. |
| Container Filesystem | Browse, read, edit, upload, download, and delete files inside running containers. |
| Host Filesystem | Browse and manage files on managed hosts (requires nsenter). |
| SFTP Browser | Browse remote filesystems over SSH/SFTP with upload, download, and directory management. |
| Snippets | Save and manage code snippets and configuration files with the built-in editor. |
| Command Cheat Sheet | Quick-reference for Docker, Linux, networking, and custom commands. |
| Feature | Description |
|---|---|
| SSH Connections | Manage SSH connections with password or key-based auth. Web terminal, SFTP browser, tunnel/port forwarding. |
| RDP/VNC Connections | Remote Desktop access via Apache Guacamole (guacd). RDP and VNC connections in the browser — no client software needed. Clipboard sync, file transfer, multi-session support. |
| Database Browser | Connect to PostgreSQL, MySQL/MariaDB, MongoDB, Redis, and SQLite. Execute queries, browse tables. |
| LDAP Browser | Connect to LDAP directories. Search, browse entries, view attributes. Settings and delete management. |
| Git Integration | Unified Git provider support (Gitea, GitHub, GitLab). Repository management, file editing, PRs, issues, CI/CD workflows. |
| Container Registries | Manage authentication for multiple private registries with encrypted credentials. |
| Web Shortcuts | Bookmark frequently accessed URLs with custom icons and categories. |
| Feature | Description |
|---|---|
| Outgoing Webhooks | HTTP webhooks triggered by container events (start, stop, die, health changes). Delivery logs with retry. |
| Auto-Deploy Rules | Automatically redeploy stacks on Git push events. Match by source repo and branch. |
| Runbooks | Define multi-step operational procedures. Execute manually or triggered by events. Execution history. |
| Crontab Manager | Web-based cron job manager. Create, edit, enable/disable, and run cron jobs from the UI. Supports shell commands, Docker exec, and HTTP webhooks. Full execution history with output, exit codes, and duration tracking. Auto-cleanup of old execution records (30-day retention). |
| Scheduled Jobs | Cron-based scheduling for backups, security scans, metrics collection, update checks, and cleanup tasks. |
| Image Updates | Detect available image updates, apply individually or in batch, with rollback capability. |
| Feature | Description |
|---|---|
| REST API | Full CRUD API at /api/v1 with JWT and API key authentication. |
| OpenAPI 3.0 | Auto-generated specification at /api/v1/openapi.json. Swagger UI at /docs/api. |
| WebSocket API | Real-time streams for logs, exec, stats, events, metrics, and terminal sessions. |
| Network Capture | Packet capture on container network interfaces for traffic analysis. |
| Feature | Description | Edition |
|---|---|---|
| Custom Dashboards | Drag-and-drop dashboard builder with 15 widget types (gauges, charts, tables, feeds). Multiple layouts. | Enterprise |
| GitOps / Git Sync | Synchronize stacks with Git repositories. Auto-deploy on push, conflict detection, branch selection. | Business |
| Firewall Manager | Visual iptables/nftables management from the UI. Rules per container, per network, per port. Create/edit/delete rules, apply to host, sync from host, audit log. Supports both iptables and nftables backends. | Business |
| SSL Observatory | SSL/TLS scanner for all services. Monitors certificate health with automatic grading (A+ to F), expiration alerts, cipher suite analysis, protocol version detection, OCSP stapling & Certificate Transparency checks. Dashboard with grade distribution. | Business |
| Backup Verification | Automated backup integrity verification. Supports extract, container, and database verification methods. Validates checksums, file readability, container mounting, and data integrity. Schedulable with cron expressions. | Business |
| WireGuard VPN | Native WireGuard VPN management from the UI. Create interfaces with auto-generated keys, manage peers, QR config generation, transfer statistics, multi-interface support with per-peer allowed IPs and keepalive settings. | Business |
| Container Marketplace | Curated app marketplace with one-click deployment. Browse, search, and install Docker Compose apps by category. User ratings and reviews, featured apps, configurable deployment fields, installation tracking, and community app submissions. | Business |
| Container Image Builder | Build Docker images from Dockerfiles in the UI. Multi-stage build support, build arguments, platform targeting, and reusable Dockerfile templates. | Business |
| Automated Rollback | Automatic stack rollback on deploy failure or health check failure. Configurable rollback policies, retry limits, cooldown periods, and full execution history. | Business |
| Ephemeral Environments | TTL-based short-lived Docker environments for testing and CI/CD previews. API-driven. | Enterprise |
| Manifest Builder | Visual Docker Compose editor with service templates, validation, and YAML preview. | Enterprise |
| OPA Policies | Open Policy Agent integration for deployment policy enforcement. Rego policies, violation tracking. | Enterprise |
| Runtime Security | Real-time container runtime monitoring — process tracking, file integrity, network anomaly detection. | Enterprise |
| Image Signing | Cosign/Sigstore image signing and verification. Key management, policy enforcement. | Enterprise |
| Compliance | Map infrastructure to CIS Docker Benchmark, SOC 2, PCI DSS, and HIPAA frameworks. Exportable reports. | Enterprise |
| Resource Optimization | Right-sizing recommendations based on actual usage. Over/under-provisioned detection, cost analysis. | Enterprise |
| Log Aggregation | Centralized log collection, indexing, and full-text search across all containers. Configurable retention. | Enterprise |
| Drift Detection | Detect configuration drift between expected and actual container state. Change events audit trail. | Enterprise |
| Change Audit Feed | Chronological feed of all infrastructure changes with filtering by type, user, and time range. | Enterprise |
Infrastructure overview with container status, resource utilization, security score, and recent events.
Secure login with optional TOTP two-factor authentication, backup codes, and account lockout protection.
Full container lifecycle management with real-time stats, logs, exec terminal, filesystem browser, and settings editor.
Pull, inspect, remove, and prune Docker images. Registry support with layer history and size analysis.
Create, inspect, remove, and prune Docker volumes. Built-in file browser for volume contents.
Create, inspect, and manage Docker networks. Bridge, overlay, and macvlan support with interactive D3.js force-directed topology graph — drag, zoom, hover-highlight connections, and click nodes for details.
Deploy Docker Compose stacks from YAML, from Git repositories, or from the built-in stack catalog.
Trivy-powered vulnerability scanning with security scoring, trend analysis, SBOM generation, and exportable reports.
Aggregated container logs with search and filtering. Centralized log collection and custom log file upload for analysis.
Multi-tab browser terminal with container exec and host SSH. SFTP browser, tunnel/port forwarding. Powered by xterm.js.
Full VS Code editor (Monaco) and Neovim in the browser for editing files inside containers, on hosts, or in your snippet library.
Manage Docker hosts across your infrastructure from a single pane of glass. Auto-deploy agents via SSH with mTLS.
User management with role assignment, team-based resource scoping, and profile editing.
Role-based access control with 46 granular permissions. Create custom roles with fine-grained permission assignment.
Enterprise authentication via Active Directory and LDAP. Provider management, group mapping, and connection testing.
Platform settings, license management, update checker, and command cheat sheet.
The fastest way to get started. Uses pre-built images, no compilation required:
curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/install.sh | bashSee Fast Deployment above for details and manual options.
# Prerequisites: Go 1.25+, Make, Docker
git clone https://github.com/fr4nsys/usulnet.git
cd usulnet
# Build and run with Docker Compose (builds from source, ~10-15 min first time)
docker compose -f docker-compose.dev.yml build
docker compose -f docker-compose.dev.yml up -d
# Or build natively
make build && make runservices:
usulnet:
image: ghcr.io/fr4nsys/usulnet:latest
ports:
- "8080:8080" # HTTP
- "7443:7443" # HTTPS (auto-TLS)
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- usulnet-data:/var/lib/usulnet
- nginx-conf:/etc/nginx/conf.d/usulnet
- nginx-certs:/etc/usulnet/certs
- acme-webroot:/var/lib/usulnet/acme
environment:
# sslmode=require: encrypted connection (self-signed cert, no CA verification needed)
- USULNET_DATABASE_URL=postgres://usulnet:secret@postgres:5432/usulnet?sslmode=require
- USULNET_REDIS_URL=rediss://redis:6379/0
- USULNET_NATS_URL=natss://nats:4222
- USULNET_SECURITY_JWT_SECRET=your-secret-key-min-32-chars-long
- USULNET_SECURITY_CONFIG_ENCRYPTION_KEY=your-64-hex-char-aes-256-key-here
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
nats:
condition: service_started
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: usulnet
POSTGRES_USER: usulnet
POSTGRES_PASSWORD: secret
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U usulnet"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
redis:
image: redis:8-alpine
entrypoint:
- /bin/sh
- -c
- |
set -e
apk add --no-cache openssl >/dev/null 2>&1
mkdir -p /tmp/redis-certs
openssl req -new -x509 -days 3650 -nodes \
-newkey ec -pkeyopt ec_paramgen_curve:P-256 \
-subj "/CN=redis/O=usulnet" \
-keyout /tmp/redis-certs/server.key \
-out /tmp/redis-certs/server.crt 2>/dev/null
chmod 600 /tmp/redis-certs/server.key
chmod 644 /tmp/redis-certs/server.crt
exec redis-server \
--tls-port 6379 --port 0 \
--tls-cert-file /tmp/redis-certs/server.crt \
--tls-key-file /tmp/redis-certs/server.key \
--tls-auth-clients no \
--maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis-data:/data
restart: unless-stopped
nats:
image: nats:2.12-alpine
command: ["--jetstream", "--store_dir", "/data"]
volumes:
- nats-data:/data
restart: unless-stopped
nginx:
image: nginx:1.28-alpine
ports:
- "80:80" # Public HTTP (ACME + redirect)
- "443:443" # Public HTTPS (reverse proxy)
volumes:
- nginx-conf:/etc/nginx/conf.d/usulnet:ro
- nginx-certs:/etc/usulnet/certs:ro
- acme-webroot:/var/lib/usulnet/acme:ro
depends_on:
- usulnet
restart: unless-stopped
guacd:
image: guacamole/guacd:1.6.0
restart: unless-stopped # RDP/VNC gateway for remote desktop
volumes:
usulnet-data:
postgres-data:
redis-data:
nats-data:
nginx-conf:
nginx-certs:
acme-webroot:Master node:
# config.yaml on master
mode: master
server:
port: 8080
nats:
url: natss://nats-server:4222
jetstream:
enabled: trueAgent node:
# config.yaml on agent
mode: agent
agent:
master_url: natss://master-nats:4222
name: worker-01
token: your-auth-token
heartbeat_interval: 30s
metrics_interval: 1mOr deploy agents directly from the web UI:
- Go to Nodes → Add Node
- Enter the host's SSH credentials
- Click Deploy Agent — usulnet will install and configure the agent automatically
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2+ vCPU |
| RAM | 2 GB | 4 GB (single node) / 8 GB (master with agents) |
| Disk | 10 GB | 50 GB+ (with backups) |
| OS | Linux (amd64, arm64) | Debian/Ubuntu/RHEL |
| Docker | 20.10+ | Latest stable |
| PostgreSQL | 12+ | 16+ |
| Redis | 7+ | 8+ |
| NATS | 2.0+ | 2.12+ |
usulnet is configured via config.yaml or environment variables (prefix USULNET_, nested with _).
server:
host: 0.0.0.0
port: 8080
https_port: 7443
base_url: https://usulnet.example.com
read_timeout: 30s
write_timeout: 30s
idle_timeout: 120s
max_request_size: 52428800 # 50 MB
rate_limit_rps: 100
tls:
enabled: true
auto_tls: true # Auto-generate self-signed certs
# cert_file: /path/to/cert.pem # Or use custom certs
# key_file: /path/to/key.pemdatabase:
# sslmode=require — TLS-encrypted, no CA verification (default; works with self-signed cert).
# Use sslmode=verify-full and set USULNET_DATABASE_SSL_ROOTCERT for full cert verification.
url: postgres://usulnet:password@localhost:5432/usulnet?sslmode=require
max_open_conns: 25
max_idle_conns: 10
conn_max_lifetime: 30m
query_timeout: 30sPostgreSQL TLS: All Docker Compose files ship with PostgreSQL TLS enabled by default. A self-signed ECDSA P-256 certificate is auto-generated on every container startup — no external cert files, no init containers.
sslmode=requireencrypts the connection without needing a CA cert. To verify the server certificate, usesslmode=verify-fulland mount your CA cert, then setUSULNET_DATABASE_SSL_ROOTCERT=/path/to/ca.crt.
Redis TLS: All Docker Compose files ship with Redis TLS enabled by default. A self-signed ECDSA P-256 certificate is auto-generated on every container startup. The
rediss://URL scheme enables TLS automatically. To use your own certificate, mountredis-server.crtandredis-server.keyinto the container at/certs-src/. To verify the server certificate, settls_ca_filein the Redis configuration and disabletls_skip_verify.
security:
jwt_secret: "your-secret-at-least-32-characters"
jwt_expiry: 24h
refresh_expiry: 168h # 7 days
config_encryption_key: "64-hex-chars" # AES-256 key for secrets at rest
cookie_secure: true
cookie_samesite: strict
password_min_length: 8
password_require_uppercase: true
password_require_number: true
max_failed_logins: 5
lockout_duration: 15mstorage:
type: s3 # local | s3
path: /var/lib/usulnet # local storage path
s3:
endpoint: s3.amazonaws.com
bucket: usulnet-backups
region: us-east-1
access_key: AKIA...
secret_key: ...
use_path_style: false # true for MinIO
backup:
compression: zstd # gzip | zstd
compression_level: 3
default_retention_days: 30trivy:
enabled: true
cache_dir: /var/lib/usulnet/trivy
timeout: 5m
severity: CRITICAL,HIGH,MEDIUM
ignore_unfixed: false
update_db_on_start: truenginx:
acme_email: admin@example.com
config_dir: "/etc/nginx/conf.d/usulnet"
cert_dir: "/etc/usulnet/certs"
acme_web_root: "/var/lib/usulnet/acme"
listen_http: ":80"
listen_https: ":443"dns:
enabled: true # Enable the embedded DNS server
listen_addr: ":53" # UDP/TCP listen address
forwarders: # Upstream servers for recursive queries
- "1.1.1.3" # Cloudflare malware-blocking DNS
- "1.0.0.3"The embedded DNS server runs in-process and is fully managed from the web UI. Zones and records are stored in PostgreSQL (source of truth) and pushed to the in-memory server on every change. The server supports authoritative responses for managed zones and forwards all other queries to the configured upstream resolvers.
dns:
service_discovery:
enabled: true
domain: "containers.local"
ttl: 30
create_srv: true
include_stopped_cleanup: trueWhen enabled, running containers are automatically registered as DNS records in a containers.local zone. A records map <container>.containers.local to the container IP. SRV records are created for exposed ports.
Environment variables:
USULNET_DNS_ENABLED=true # Enable/disable DNS server
USULNET_DNS_LISTEN_ADDR=:53 # Listen address
USULNET_DNS_SD_ENABLED=true # Enable service discovery
USULNET_DNS_SD_DOMAIN=containers.local # Service discovery domain
USULNET_DNS_SD_TTL=30 # TTL for auto-registered records
USULNET_DNS_SD_CREATE_SRV=true # Create SRV records for exposed portsNotification channels are configured through the web UI at Admin → Notification Channels. Supported types:
Email (SMTP), Slack, Discord, Telegram, Gotify, ntfy,
PagerDuty, Opsgenie, Microsoft Teams, Generic Webhook
Any configuration key can be set via environment variable:
USULNET_SERVER_PORT=9090
USULNET_DATABASE_URL=postgres://...
USULNET_SECURITY_JWT_SECRET=...
USULNET_REDIS_URL=rediss://...
USULNET_NATS_URL=natss://...
USULNET_TRIVY_ENABLED=true
USULNET_MODE=masterusulnet exposes a full REST API at /api/v1 with OpenAPI 3.0 documentation.
# Login to get a JWT token
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "usulnet"}'
# Use the token
curl http://localhost:8080/api/v1/containers \
-H "Authorization: Bearer <token>"
# Or use an API key
curl http://localhost:8080/api/v1/containers \
-H "X-API-KEY: your-api-key"| Method | Endpoint | Description |
|---|---|---|
| Auth | ||
POST |
/auth/login |
Authenticate and receive JWT |
POST |
/auth/refresh |
Refresh expired token |
POST |
/auth/logout |
Invalidate session |
| System | ||
GET |
/system/info |
System and Docker engine info |
GET |
/system/version |
Application version |
GET |
/system/health |
Health status |
GET |
/system/metrics |
System metrics |
| Containers | ||
GET |
/containers |
List all containers |
GET |
/containers/{id} |
Container details |
POST |
/containers/{id}/start |
Start container |
POST |
/containers/{id}/stop |
Stop container |
POST |
/containers/{id}/restart |
Restart container |
DELETE |
/containers/{id} |
Remove container |
GET |
/containers/{id}/logs |
Container logs |
GET |
/containers/{id}/stats |
Resource stats |
| Images | ||
GET |
/images |
List images |
GET |
/images/{id} |
Image details |
POST |
/images/pull |
Pull image |
DELETE |
/images/{id} |
Remove image |
| Volumes | ||
GET |
/volumes |
List volumes |
POST |
/volumes |
Create volume |
GET |
/volumes/{name} |
Volume details |
DELETE |
/volumes/{name} |
Remove volume |
| Networks | ||
GET |
/networks |
List networks |
POST |
/networks |
Create network |
GET |
/networks/{id} |
Network details |
DELETE |
/networks/{id} |
Remove network |
| Stacks | ||
GET |
/stacks |
List stacks |
POST |
/stacks/deploy |
Deploy stack |
GET |
/stacks/{name} |
Stack details |
DELETE |
/stacks/{name} |
Remove stack |
| Hosts | ||
GET |
/hosts |
List managed nodes |
POST |
/hosts |
Add node |
GET |
/hosts/{id} |
Node details |
PUT |
/hosts/{id} |
Update node |
DELETE |
/hosts/{id} |
Remove node |
| Backups | ||
GET |
/backups |
List backups |
POST |
/backups |
Create backup |
POST |
/backups/{id}/restore |
Restore backup |
DELETE |
/backups/{id} |
Delete backup |
| Security | ||
POST |
/security/scan |
Scan all containers |
POST |
/security/scan/{id} |
Scan specific container |
| Updates | ||
GET |
/updates |
List available updates |
POST |
/updates/check |
Check for updates |
| Proxy | ||
GET |
/proxy/hosts |
List proxy hosts |
POST |
/proxy/hosts |
Create proxy host |
PUT |
/proxy/hosts/{id} |
Update proxy host |
DELETE |
/proxy/hosts/{id} |
Remove proxy host |
| Users (admin) | ||
GET |
/users |
List users |
POST |
/users |
Create user |
PUT |
/users/{id} |
Update user |
DELETE |
/users/{id} |
Delete user |
| Endpoint | Description |
|---|---|
/ws/logs/{id} |
Real-time container log streaming |
/ws/exec/{id} |
Interactive container terminal |
/ws/stats/{id} |
Live container resource stats |
/ws/events |
Docker event stream |
/ws/metrics |
System metrics stream |
/ws/monitoring/stats |
Monitoring dashboard data |
/ws/monitoring/container/{id} |
Per-container monitoring |
/ws/jobs/{id} |
Job progress tracking |
/ws/capture/{id} |
Packet capture stream |
/ws/editor/nvim |
Neovim terminal session |
Interactive API documentation is available at:
- Swagger UI:
http://localhost:8080/docs/api - OpenAPI JSON:
http://localhost:8080/api/v1/openapi.json
+-------------------+
| Web Browser |
| (Tailwind/Alpine/ |
| HTMX/xterm.js) |
+---------+---------+
|
HTTP/WS/HTTPS
|
+---------------------------------------------------------------------+
| usulnet (master) |
| |
| +------------+ +------------+ +-----------+ +----------------+ |
| | Chi Router | | Templ UI | | REST API | | WebSocket Hub | |
| | (Frontend) | | (SSR HTML) | | (JSON) | | (Real-time) | |
| +------+-----+ +------+-----+ +-----+-----+ +-------+--------+ |
| | | | | |
| +------+---------------+--------------+-----------------+--------+ |
| | Service Layer | |
| | container | image | volume | network | stack | security | |
| | backup | proxy | auth | user | team | ssh | git | monitoring | |
| +------+---------------+--------------+-----------------+--------+ |
| | | | | |
| +------+-----+ +------+-----+ +----+------+ +-------+-------+ |
| | PostgreSQL | | Redis | | NATS | |Docker Socket | |
| | (Data) | | (Sessions/ | | (JetStream| |(Docker API) | |
| | | | Cache) | | Messaging| | | |
| +-------------+ +------------+ +-----------+ +---------------+ |
+---------------------------------------------------------------------+
| |
NATS (mTLS) NATS (mTLS)
| |
+--------+--------+ +----------+--------+
| usulnet (agent) | | usulnet (agent) |
| worker-01 | | worker-02 |
| +-------------+ | | +-------------+ |
| |Docker Socket| | | |Docker Socket| |
| +-------------+ | | +-------------+ |
+------------------+ +------------------+
| Layer | Technology |
|---|---|
| Language | Go 1.25+ |
| Web Framework | Chi v5 |
| Templates | Templ — compile-time type-safe HTML |
| CSS | Tailwind CSS (standalone CLI, no Node.js) |
| Frontend JS | Alpine.js + HTMX |
| Terminal | xterm.js v5 |
| Editor | Monaco v0.52 + Neovim |
| Database | PostgreSQL 16 (pgx + sqlx) |
| Cache | Redis 8 (TLS) |
| Messaging | NATS 2.12 with JetStream |
| Auth | JWT + OAuth2/OIDC + LDAP + TOTP |
| Security | Trivy vulnerability scanner |
| Logging | zap (structured JSON) |
| Scheduling | cron v3 |
| Docker | Docker SDK for Go |
cmd/
usulnet/ # Main application entry point (serve, migrate, config, admin)
usulnet-agent/ # Agent binary entry point
internal/
api/ # REST API handlers, middleware, router
handlers/ # Per-resource API handlers
middleware/ # Auth, RBAC, CORS, rate limiting, logging
app/ # Application bootstrap, config loading, service wiring
agent/ # Agent mode: heartbeat, inventory, command execution
docker/ # Docker client wrapper with multi-host support
gateway/ # API gateway for master mode (routes to agents)
integrations/ # External system integrations
gitea/ # Gitea Git provider
github/ # GitHub Git provider
gitlab/ # GitLab Git provider
models/ # Domain models and types
nats/ # NATS client with JetStream support
pkg/ # Shared packages
crypto/ # AES-256-GCM encryption, password hashing
logger/ # Structured logging (zap wrapper)
validator/ # Request validation
repository/ # Data access layer
postgres/ # PostgreSQL repositories (54 migrations)
redis/ # Redis session store, JWT blacklist
scheduler/ # Cron job scheduler
workers/ # Job implementations (backup, scan, cleanup, metrics)
services/ # Business logic (54 services)
auth/ # JWT, OIDC, LDAP authentication
backup/ # Backup creation, restore, scheduling
container/ # Container lifecycle management
dns/ # DNS server (zones, records, TSIG keys, embedded miekg/dns backend)
git/ # Unified Git provider (Gitea/GitHub/GitLab)
image/ # Image pull, inspect, prune
monitoring/ # Metrics collection, alert engine
network/ # Docker network management
notification/ # Multi-channel notification dispatch
proxy/ # Nginx reverse proxy
security/ # Trivy scanning, scoring, SBOM
ssh/ # SSH connections, SFTP, tunnels
stack/ # Docker Compose stack management
storage/ # S3/local backup storage
volume/ # Docker volume management
web/ # Web UI layer
templates/ # Templ templates (~144 files)
components/ # Reusable UI components
layouts/ # Page layouts (base, auth)
pages/ # Full page templates
partials/ # HTMX partial responses
handler_*.go # 45 web handlers
web/
static/ # Static assets
src/input.css # Tailwind source CSS
css/output.css # Compiled CSS
js/ # Alpine.js, HTMX, xterm.js, Monaco
deploy/ # Production Docker Compose files
docs/ # Developer documentation
nvim/ # Neovim editor configuration (lazy.nvim)
54 migrations managing tables for:
- Users, roles, permissions, teams
- SSH connections, SSH keys
- Container registries
- Configuration variables and templates
- Backup schedules and metadata
- Security scan results and issues
- Notification configurations
- Alert rules, events, and silences
- Outgoing webhooks and delivery logs
- Auto-deploy rules
- Runbooks and execution history
- Git connections and repositories
- Terminal session history
- Metrics time-series data
- Audit log entries
- User preferences
- DNS zones, records, TSIG keys, and audit log
usulnet [command] [flags]
Commands:
serve Start the usulnet server
migrate Database migration management
config Configuration utilities
admin Administrative commands
version Print version information
# Server
usulnet serve --config config.yaml --mode master
# Migrations
usulnet migrate up # Apply pending migrations
usulnet migrate down [N] # Rollback N migrations (default: 1)
usulnet migrate status # Show migration status
# Config
usulnet config check # Validate configuration
usulnet config show # Display config (secrets masked)
# Admin
usulnet admin reset-password [PASS] # Reset admin password (default: usulnet)
# Version
usulnet version # Show version, commit, build date- Go 1.25+
- Make
- Docker & Docker Compose (for dev services)
# Clone
git clone https://github.com/fr4nsys/usulnet.git
cd usulnet
# Start dev services (PostgreSQL, Redis, NATS, MinIO)
make dev-up
# Install Templ CLI
go install github.com/a-h/templ/cmd/templ@latest
# Full build
make build
# Run
make run# Terminal 1: Watch and regenerate templates
make templ-watch
# Terminal 2: Watch and recompile CSS
make css-watch
# Terminal 3: Run the application
make run# Run all tests with race detection
make test
# Generate HTML coverage report
make test-coverage
# Lint
make lint
# Format
make fmtmake build # Build main binary (templ + css + go build)
make build-agent # Build agent binary
make build-all # Build both binaries
make frontend # Regenerate templates + CSS only
make clean # Clean build artifacts
make docker-build # Build Docker imageIf you discover a security vulnerability, please report it responsibly:
- Do not open a public issue
- Email: security@usulnet.com
- Include a detailed description and steps to reproduce
- We will respond within 48 hours
- JWT authentication with configurable expiry
- API key authentication for programmatic access
- TOTP 2FA with backup codes
- LDAP/Active Directory integration
- OAuth2/OIDC (GitHub, Google, Microsoft, custom)
- RBAC with 46 granular permissions
- Team-based resource scoping
- AES-256-GCM encryption for secrets at rest
- bcrypt password hashing
- Account lockout after failed logins
- Password complexity policies
- CSRF protection
- Secure cookie settings (HttpOnly, SameSite)
- TLS/HTTPS with auto-generated certificates
- Redis TLS encryption by default (ECDSA P-256 self-signed)
- PostgreSQL TLS encryption by default (ECDSA P-256 self-signed)
- mTLS for inter-node communication
- Rate limiting (configurable per endpoint)
- Comprehensive audit logging
- Trivy vulnerability scanning
- SBOM generation (CycloneDX, SPDX)
- Security scoring (0-100)
- Docker CIS Benchmark compliance checks
usulnet is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later).
This means you are free to use, modify, and distribute usulnet, provided that:
- Any modified version that is made available over a network must also be released under AGPL-3.0
- The source code must be made available to users who interact with the software over a network
- All copyright notices and license headers are preserved
Paid editions are activated with a signed JWT license key obtained from the License Portal.
One instance per license key — each key can be active on exactly one host at a time. Attempting to activate on a second host while another is active returns a conflict error.
How activation works:
- Go to Settings → License → Activate and paste your JWT license key
- The application contacts
api.usulnet.comto register the instance and receives a signed Activation Receipt — a short-lived JWT (7-day TTL) cryptographically bound to the instance fingerprint - A background process renews the receipt every 6 hours
- If the server cannot be reached, the existing receipt remains valid for up to 14 days — after 7 days a sync warning is displayed in the dashboard; after 14 days the instance automatically downgrades to Community Edition
Releasing an instance remotely (via the portal):
- Sign in at id.usulnet.com with your purchase email
- Click Release Instance next to your active license
- The release takes effect on the next check-in cycle (up to 6 hours)
- Once released, the license can be activated on a different host
For commercial licensing, contact license@usulnet.com.
Contributions are welcome. Please follow these steps to submit a pull request:
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'feat: add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
This project follows Conventional Commits:
feat: add new feature
fix: resolve bug
docs: update documentation
refactor: restructure code
test: add or update tests
chore: maintenance tasks
usulnet is built on the shoulders of exceptional open-source projects:
- Go — The language that makes this possible
- Docker — Container runtime
- Chi — HTTP router
- Templ — Type-safe HTML templates
- Tailwind CSS — Utility-first CSS
- Alpine.js — Lightweight JS framework
- HTMX — HTML over the wire
- xterm.js — Terminal emulator
- Monaco Editor — Code editor
- Trivy — Vulnerability scanner
- NATS — Messaging system
- PostgreSQL — Database
Built with care for the infrastructure community.
v26.2.7 — Found a bug? Report it here. Your feedback makes usulnet better.
GitHub •
Issues •
Discussions

































































