UsulNet Docker Install: All-in-One Container Management Platform

Step-by-step guide to install UsulNet with Docker Compose. Covers production setup with PostgreSQL, Redis, NATS, security scanning, multi-node deployment, reverse proxy, and RBAC configuration.

UsulNet Docker Install: All-in-One Container Management Platform

I stumbled on UsulNet while browsing GitHub for Docker management tools. It caught my eye because it tries to be everything in one binary: container management, security scanning, reverse proxy config, backups, monitoring, multi-node orchestration. That’s a long feature list for a project that just shipped its first public beta (v26.2.0) in February 2026.

I’ve been writing about tools in this space recently, including Arcane and Dockhand. UsulNet takes a different approach from both. Where Arcane focuses on being a clean, open-source Docker UI with GitOps, and Dockhand leans into security scanning and auto-updates, UsulNet wants to replace your entire stack of management tools. Whether it actually pulls that off is a fair question, but the ambition is real.

What UsulNet does

UsulNet is a self-hosted Docker management platform written in Go. It compiles down to a single ~50 MB binary with no runtime dependencies. No Node.js, no Python, no heavy frontend framework. The UI is server-rendered HTML using Templ templates, Tailwind CSS, Alpine.js, and HTMX.

UsulNet dashboard showing container status, resource utilization, and security score

Here’s what you get out of the box:

  • Full container lifecycle management with bulk operations, stats, exec, filesystem browser
  • Docker Compose stack deployment with a built-in template catalog
  • Trivy vulnerability scanning with security scoring (0-100 per container)
  • SBOM generation in CycloneDX and SPDX formats
  • RBAC with 44+ granular permissions and custom roles
  • 2FA/TOTP, LDAP, OIDC authentication
  • Monitoring with alert rules and 11 notification channels
  • Scheduled backups to S3, local, Azure Blob, GCS, Backblaze B2, SFTP
  • Caddy and Nginx Proxy Manager integration for reverse proxy
  • Multi-node master/agent architecture with NATS messaging and mTLS
  • Monaco code editor and Neovim running in the browser
  • SSH connections, RDP, database browser, LDAP browser, Git integration
  • REST API with OpenAPI 3.0 docs and WebSocket streams

That list is long, and I’ll be honest, I haven’t tested every single feature. The core container management, stack deployment, and security scanning work well. Some of the more niche features like the in-browser Neovim and RDP connections feel like bonus items that may or may not matter to you.

How UsulNet compares to other Docker managers

If you’re coming from Arcane or Dockhand, or looking at the Arcane vs Dockhand comparison, here’s how UsulNet fits in:

UsulNetArcaneDockhand
LicenseAGPL-3.0BSD-3-ClauseBSL 1.1
BackendGo (single binary)GoBun + SvelteKit
FrontendTempl + HTMX + Alpine.jsSvelteKitSvelteKit 2 / Svelte 5
Vuln scanningTrivy (built-in)NoGrype/Trivy
RBACYes (44+ permissions)NoEnterprise tier only
Multi-nodeNATS + mTLS agentsarcane-headlessHawser
Reverse proxyCaddy + NPM integrationNoNo
BackupsS3, local, Azure, GCS, B2, SFTPNoNo
Monitoring/alertsBuilt-in with 11 notification channelsNoNo
Database browserPostgreSQL, MySQL, MongoDB, Redis, SQLiteNoNo
Code editorMonaco + NeovimNoNo
GitOpsAuto-deploy on Git pushBuilt-in GitOpsGit + webhooks
Docker SwarmYesNoNo
StatusBeta (v26.2.0, first release)Stable (since 2022)v1 (since Dec 2025)
PricingFree CE (2 nodes, 3 users), Business from EUR79/node/yrFreeFree homelab, SMB $499/host/yr

UsulNet has the widest feature set of the three, but it’s also the newest. Arcane has been around since 2022 with 1,800+ commits and 35 contributors. UsulNet has 11 commits and one developer. That gap matters when you hit an edge case at 2am.

Beta software

UsulNet is in public beta. It’s functional, but expect rough edges. The developer is actively shipping updates, but this is a solo project right now. If you need something battle-tested, look at Arcane first.

Prerequisites

Before you start, you need:

  • A Linux server (VPS or local machine). I recommend Hetzner for VPS hosting
  • Docker and Docker Compose v2 installed
  • At least 2 GB RAM (4 GB recommended)
  • Ports 8080 (HTTP) and 7443 (HTTPS) available
Hetzner VPS DigitalOcean $100 Free Vultr $100 Free

Or use a Mini PC as home server.

Install Docker

If you don’t have Docker yet:

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  jammy stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-compose

Full walkthrough: Install Docker & Docker-compose for Ubuntu.

Install UsulNet with Docker Compose

UsulNet needs PostgreSQL, Redis, and NATS alongside the main application. That’s more moving parts than Arcane (which runs as a single container) or Dockhand (single container with optional PostgreSQL). The trade-off is that you get proper session management, caching, and inter-node messaging baked in.

Quick install (one command)

The fastest way to get running:

curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/install.sh | bash

This downloads the production compose file, generates all the secrets automatically, and starts everything. You’ll be up in about 60 seconds. Access it at https://your-server-ip:7443 with default credentials admin / usulnet.

I’d still recommend the manual method below so you know what’s in the compose file and can customize it.

Create a directory for UsulNet:

mkdir -p /opt/usulnet && cd /opt/usulnet

Download the production compose file and environment template:

curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/docker-compose.prod.yml -o docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/.env.example -o .env

Generate the secrets. You need a database password, a JWT secret, and an encryption key:

sed -i "s|CHANGE_ME_GENERATE_RANDOM_PASSWORD|$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)|" .env
sed -i "s|CHANGE_ME_GENERATE_WITH_OPENSSL_RAND_HEX_32|$(openssl rand -hex 32)|" .env
sed -i "s|CHANGE_ME_GENERATE_WITH_OPENSSL_RAND_HEX_32|$(openssl rand -hex 32)|" .env

Or open the .env file and fill in the values manually. Your choice.

Start everything:

docker compose up -d

Open https://your-server-ip:7443 in your browser. UsulNet generates a self-signed TLS certificate on first start, so you’ll get a browser warning. Log in with admin / usulnet and change the password right away.

Change default credentials

The default login is admin / usulnet. Change the password immediately after first login. Go to your profile settings to update it. Also enable 2FA while you’re there.

What the compose file includes

Here’s what gets deployed:

services:
  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:
      - USULNET_DATABASE_URL=postgres://usulnet:secret@postgres:5432/usulnet?sslmode=disable
      - USULNET_REDIS_URL=redis://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:7-alpine
    command: redis-server --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:

Four containers total. PostgreSQL stores all the application data, Redis handles sessions and caching, NATS provides the messaging layer for multi-node communication (even in standalone mode, UsulNet expects it to be there).

Docker socket is read-only

Notice the Docker socket is mounted as :ro (read-only). UsulNet still works fine for container management with a read-only socket mount because the Docker API handles write operations through the socket regardless of the mount flag. The :ro flag just prevents UsulNet from modifying the socket file itself.

Container and stack management

The container management works about how you’d expect. You get a list of all running containers with real-time CPU and memory stats, and you can start, stop, restart, pause, kill, or remove them individually or in bulk.

UsulNet container management interface showing container list with real-time stats

What I found more interesting is the stack deployment. You can deploy compose stacks three ways:

Paste or write a compose file directly in the web editor. UsulNet validates the YAML before deploying. The editor is Monaco (same one VS Code uses), so you get syntax highlighting and autocomplete.

Connect a Git repository (Gitea, GitHub, or GitLab) and deploy stacks from compose files in the repo. You can set up auto-deploy rules that redeploy when you push changes to a specific branch.

UsulNet has a built-in stack catalog with pre-configured templates for common applications. Pick one, adjust the settings, and deploy. Good for quickly spinning up something you want to test.

UsulNet stack deployment interface with compose editor and template catalog

The container filesystem browser and web terminal both work. You can browse files inside running containers, edit them with the Monaco editor, and open exec sessions. The terminal uses xterm.js, same library most web-based terminals use. It’s responsive enough for interactive work.

Security scanning with Trivy

UsulNet integrates Trivy for vulnerability scanning. This runs locally on your server and doesn’t send data to external services.

UsulNet security scanning interface showing vulnerability results and security score

To enable it, make sure Trivy is configured in your config.yaml or via environment variables:

trivy:
  enabled: true
  cache_dir: /var/lib/usulnet/trivy
  timeout: 5m
  severity: CRITICAL,HIGH,MEDIUM
  ignore_unfixed: false
  update_db_on_start: true

Or set USULNET_TRIVY_ENABLED=true in your environment.

What sets this apart from Dockhand’s scanning is the security scoring. Each container gets a 0-100 score based on the scan results, and you get an aggregate score across your entire infrastructure. There’s trend tracking too, so you can see if your security posture is improving or degrading over time.

UsulNet also generates SBOMs (Software Bill of Materials) in CycloneDX and SPDX formats. If you need to document what’s running in your containers for compliance purposes, that’s built in.

First scan takes a while

The first vulnerability scan downloads the Trivy database, which is a few hundred MB. Subsequent scans are faster because the database is cached locally. If the first scan times out, increase the timeout value in the Trivy config.

Setting up authentication

UsulNet supports multiple authentication methods. The free Community Edition includes TOTP 2FA. OIDC and LDAP require the Business license.

2FA/TOTP (free)

Every user can enable TOTP-based two-factor authentication from their profile settings. It works with any authenticator app (Google Authenticator, Authy, etc.). Backup codes are generated so you don’t get locked out.

OIDC/OAuth2 (Business license)

If you run an identity provider like Authentik, Keycloak, or want to use GitHub/Google/Microsoft login, configure OIDC in the settings. You’ll need:

  • Client ID
  • Client secret
  • Issuer URL / Discovery endpoint

Users are auto-provisioned on first OIDC login. You can map OIDC groups to UsulNet roles for automatic permission assignment.

LDAP/Active Directory (Business license)

For enterprise environments, UsulNet can authenticate against LDAP directories. Configure the LDAP provider with your bind DN, search base, and attribute mappings. There’s also a built-in LDAP browser for testing and debugging your directory setup.

Multi-node management

UsulNet uses a master/agent architecture for managing Docker across multiple hosts. The communication layer is NATS with JetStream for persistence, and all agent-master traffic is encrypted with mTLS.

UsulNet multi-node management showing connected agent nodes

There are three modes:

  • standalone: single-node, the default
  • master: control plane that manages agents
  • agent: worker node that connects to a master

Deploying agents

You can deploy agents to remote hosts directly from the web UI. Go to Nodes > Add Node, enter the SSH credentials for the remote machine, and click Deploy Agent. UsulNet SSHs into the remote host, installs the agent container, and configures it automatically.

Or deploy manually on the remote machine:

# config.yaml on the agent
mode: agent
agent:
  master_url: nats://master-nats:4222
  name: worker-01
  token: your-auth-token
  heartbeat_interval: 30s
  metrics_interval: 1m

The agent sends heartbeats and metrics at configurable intervals. If an agent goes offline, the dashboard shows the status change. You can switch between managed hosts from any page in the UI.

This is different from how Arcane and Dockhand handle multi-node. Arcane uses arcane-headless, a lightweight agent that connects outbound. Dockhand uses Hawser, which has NAT traversal. UsulNet’s NATS-based approach is more involved to set up but gives you persistent messaging and better reliability for larger deployments.

Reverse proxy integration

This is something neither Arcane nor Dockhand offer. UsulNet can configure Caddy or Nginx Proxy Manager directly from its UI.

If you run Caddy, enable the integration in your config:

caddy:
  enabled: true
  admin_url: http://caddy:2019
  acme_email: admin@example.com

You can then create proxy hosts, manage certificates, and configure routes from the UsulNet dashboard. Caddy handles automatic HTTPS with Let’s Encrypt.

Full Nginx Proxy Manager integration is available too. Manage proxy hosts, SSL certificates, redirections, TCP/UDP streams, and access lists, all from within UsulNet.

If you want to put UsulNet itself behind a reverse proxy, it serves on port 8080 (HTTP) and 7443 (HTTPS) by default. WebSocket support is required for live logs, terminal, and real-time metrics.

server {
    listen 443 ssl http2;
    server_name usulnet.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Add labels to the UsulNet service:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.usulnet.rule=Host(`usulnet.yourdomain.com`)"
  - "traefik.http.routers.usulnet.entrypoints=websecure"
  - "traefik.http.routers.usulnet.tls.certresolver=letsencrypt"
  - "traefik.http.services.usulnet.loadbalancer.server.port=8080"

Full Traefik setup: How to use Traefik as a reverse proxy in Docker.

Point a tunnel at http://localhost:8080. SSL and WebSocket support are handled automatically. No ports to open.

Backup configuration

UsulNet can back up individual containers, volumes, or entire stacks on a schedule. Storage backends include local filesystem, AWS S3, MinIO, Azure Blob, Google Cloud Storage, Backblaze B2, and SFTP.

Configure storage in your config.yaml:

storage:
  type: s3
  s3:
    endpoint: s3.amazonaws.com
    bucket: usulnet-backups
    region: us-east-1
    access_key: YOUR_KEY
    secret_key: YOUR_SECRET
  backup:
    compression: zstd
    compression_level: 3
    default_retention_days: 30

Or use local storage:

storage:
  type: local
  path: /var/lib/usulnet/backups

Backups are compressed with gzip or zstd (your choice) and can be restored with one click from the UI.

Environment variables reference

All config values can be set via environment variables with the USULNET_ prefix:

VariableDefaultWhat it does
USULNET_SERVER_PORT8080HTTP port
USULNET_SERVER_HTTPS_PORT7443HTTPS port
USULNET_DATABASE_URLnonePostgreSQL connection string (required)
USULNET_REDIS_URLnoneRedis connection string (required)
USULNET_NATS_URLnoneNATS connection string (required)
USULNET_SECURITY_JWT_SECRETnoneJWT signing secret, min 32 chars (required)
USULNET_SECURITY_CONFIG_ENCRYPTION_KEYnoneAES-256 key, 64 hex chars (required)
USULNET_TRIVY_ENABLEDfalseEnable Trivy vulnerability scanning
USULNET_MODEstandaloneOperation mode: standalone, master, agent
USULNET_SERVER_RATE_LIMIT_RPS100Rate limit per second

Licensing and pricing

UsulNet is AGPL-3.0 licensed. The source code is on GitHub and you can use it, modify it, and distribute it freely. The catch with AGPL is that if you modify UsulNet and make it available over a network, you have to release your changes under the same license.

TierCostWhat you get
Community (CE)FreeFull Docker management, scanning, monitoring, 2 nodes, 3 users, 1 team
BusinessEUR79/node/yearUnlimited nodes, OIDC, LDAP, custom roles, audit log export, API keys
EnterpriseCustomUnlimited everything, SSO SAML, HA mode, white label, dedicated support

The Community Edition is limited to 2 nodes, 3 users, and 1 team. OIDC and LDAP authentication require a Business license. That’s more restrictive than Arcane (fully free, no limits) or Dockhand (free tier with OIDC included), but you also get a lot more features in the CE than either of those offer.

Troubleshooting

UsulNet won't start - PostgreSQL connection errors

Make sure the database container is healthy before UsulNet tries to connect. The depends_on with condition: service_healthy in the compose file should handle this, but if you’re starting services manually, PostgreSQL needs to be fully ready first.

Check PostgreSQL health:

docker exec usulnet-postgres pg_isready -U usulnet

If it returns “accepting connections”, the database is fine and the issue is likely in your connection string.

Self-signed certificate warnings

UsulNet generates a self-signed TLS certificate on first start for HTTPS on port 7443. Your browser will show a warning. For production, put a proper reverse proxy with Let’s Encrypt certificates in front of it, or configure custom TLS certificates in the config:

server:
  tls:
    enabled: true
    cert_file: /path/to/cert.pem
    key_file: /path/to/key.pem
Trivy scans fail or timeout

The first scan downloads the vulnerability database, which can be large. Increase the timeout:

trivy:
  timeout: 10m

Also verify the container has outbound internet access for downloading the database. If you’re behind a proxy, configure the HTTP_PROXY and HTTPS_PROXY environment variables on the UsulNet container.

NATS connection issues

If you see NATS connection errors in the logs, make sure the NATS container is running and accessible. The default JetStream data directory needs write permissions:

docker logs usulnet-nats

If NATS is running but UsulNet can’t connect, check that both containers are on the same Docker network.

My take after testing

UsulNet is ambitious. One developer, first public beta, and the feature list reads like a product that’s been in development for years. The container management, stack deployment, and Trivy scanning work. The UI is clean and responsive, and the Go backend is fast.

What concerns me is the project’s maturity. Eleven commits, one contributor, first release. Compare that to Arcane (1,800+ commits, 35 contributors, stable since 2022) and you see the gap. The AGPL license is also worth thinking about if you plan to modify the source, as you’re obligated to share your changes.

The four-container stack (PostgreSQL, Redis, NATS, plus the app itself) is heavier than Arcane’s single container or Dockhand’s single container approach. On a small VPS with 2 GB RAM, that overhead is noticeable. On a machine with 4+ GB, it’s not a big deal.

If you want the widest feature set in a Docker management tool and you’re comfortable running beta software, UsulNet is worth trying. If you want stability and a proven track record, Arcane is the safer pick. If security scanning is your priority and you want something more lightweight, check out Dockhand.