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.4 — Latest Release
We appreciate your feedback — please report any issues on GitHub Issues. Your reports help to 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, and NATS
- 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
# 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
# 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.
- 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 44+ 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 — ~50 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 44+ 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 | standalone (single node), master (control plane), 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 |
|---|---|
| Caddy Integration | Configure Caddy reverse proxy via API. Auto-HTTPS with Let's Encrypt. |
| Nginx Proxy Manager | Full NPM integration — proxy hosts, certificates, redirections, streams, access lists. |
| Certificate Management | Let's Encrypt, custom certificates, auto-renewal, expiration alerts. |
| Stream Proxying | TCP/UDP stream proxy configuration for non-HTTP services. |
| 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 Connections | Remote Desktop connections to Windows servers. Configurable resolution, color depth, NLA/TLS security modes. |
| 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. |
| 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. |
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 visual topology.
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 44+ 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
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=nats://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.10-alpine
command: ["--jetstream", "--store_dir", "/data"]
volumes:
- nats-data:/data
restart: unless-stopped
volumes:
usulnet-data:
postgres-data:
redis-data:
nats-data:Master node:
# config.yaml on master
mode: master
server:
port: 8080
nats:
url: nats://nats-server:4222
jetstream:
enabled: trueAgent node:
# config.yaml on agent
mode: agent
agent:
master_url: nats://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 (standalone) / 8 GB (master) |
| Disk | 10 GB | 50 GB+ (with backups) |
| OS | Linux (amd64, arm64) | Debian/Ubuntu/RHEL |
| Docker | 20.10+ | Latest stable |
| PostgreSQL | 12+ | 16+ |
| Redis | 5+ | 7+ |
| NATS | 2.0+ | 2.10+ |
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: truecaddy:
enabled: true
admin_url: http://caddy:2019
acme_email: admin@example.comNotification 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=nats://...
USULNET_TRIVY_ENABLED=true
USULNET_MODE=standaloneusulnet 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.10 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
npm/ # Nginx Proxy Manager
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 (36 migrations)
redis/ # Redis session store, JWT blacklist
scheduler/ # Cron job scheduler
workers/ # Job implementations (backup, scan, cleanup, metrics)
services/ # Business logic (39 services)
auth/ # JWT, OIDC, LDAP authentication
backup/ # Backup creation, restore, scheduling
container/ # Container lifecycle management
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/ # Caddy/NPM 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 (~135 files)
components/ # Reusable UI components
layouts/ # Page layouts (base, auth)
pages/ # Full page templates
partials/ # HTMX partial responses
handler_*.go # 37 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)
36 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
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 standalone
# 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 44+ 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.4 — Found a bug? Report it here. Your feedback makes usulnet better.
GitHub •
Issues •
Discussions

































































