Self-Hosted Deployment
The Self-Hosted tier gives your organisation full control over the entire AegisWire stack. You deploy and operate the control plane, database, and gateways in your own infrastructure. AegisWire provides the container images, configuration documentation, and software licence.
Architecture
In a self-hosted deployment, you operate all components:
Your Cloud Account / On-Premises
├── Go Control Plane (Docker container)
├── PostgreSQL Database (managed or containerised)
├── Gateway Node(s) (Docker container with NET_ADMIN)
└── TLS termination (your certificate, your domain)
The AegisWire business platform only generates your licence. It does not have access to your control plane APIs, your user data, or your traffic. For self-hosted deployments, metering and analytics stay entirely within your control plane.
Deployment Steps
1. Obtain Your Licence
After purchasing a Self-Hosted plan, you receive a licence file from the AegisWire business platform. This licence is an Ed25519-signed token tied to your organisation.
2. Deploy PostgreSQL
AegisWire requires PostgreSQL 15 or later. Options:
- AWS RDS: Recommended for cloud deployments. Create a
db.t4g.mediumor larger instance. - Containerised: Include a PostgreSQL container in your Docker Compose configuration.
- Existing cluster: Point the control plane at your existing PostgreSQL instance.
The control plane will run database migrations automatically on startup.
3. Deploy the Control Plane
The Go control plane is distributed as a Docker container image via the private AegisWire registry. Self-hosted customers receive image pull credentials via the customer portal at app.aegiswire.com. Required environment variables:
# Database connection
AW_DB_DSN="postgres://user:password@host:5432/aegiswire?sslmode=require"
# Network
AW_LISTEN_ADDR=":8443"
AW_ADMIN_LISTEN_ADDR=":8080"
# Domain configuration
AW_DOMAIN="vpn.yourdomain.com"
# Licence
AW_LICENCE_FILE="/etc/aegiswire/licence.json"
Run the container:
docker run -d \
--name aegiswire-cp \
--restart unless-stopped \
-p 8443:8443 \
-p 8080:8080 \
-v /path/to/licence.json:/etc/aegiswire/licence.json:ro \
-e AW_DB_DSN="postgres://..." \
-e AW_LISTEN_ADDR=":8443" \
-e AW_ADMIN_LISTEN_ADDR=":8080" \
-e AW_DOMAIN="vpn.yourdomain.com" \
registry.aegiswire.com/controlplane:latest
4. Deploy Gateway Nodes
Each gateway node requires the NET_ADMIN capability for TUN device management:
docker run -d \
--name aegiswire-gw \
--restart unless-stopped \
--cap-add NET_ADMIN \
-p 51820:51820/udp \
-e AW_CP_ENDPOINT="https://vpn.yourdomain.com:8443" \
-e AW_GATEWAY_LISTEN=":51820/udp" \
registry.aegiswire.com/gateway:latest
For high availability, deploy at least two gateway nodes behind a UDP load balancer.
5. Configure TLS
Place a valid TLS certificate in front of the control plane. Options:
- Reverse proxy: nginx, Caddy, or Traefik with automatic Let's Encrypt certificates
- Cloud load balancer: AWS ALB/NLB with ACM certificates
- Direct: Mount certificate files and configure the control plane to serve TLS directly
6. Configure DNS
Create DNS records:
vpn.yourdomain.compointing to your control planegw.yourdomain.compointing to your gateway endpoint(s)
Production Hardening
High Availability
For production deployments, ensure redundancy:
- Control Plane: Deploy at least 2 replicas behind a load balancer. The control plane is stateless — all state is in PostgreSQL.
- Database: Use a managed PostgreSQL service with automated backups and failover (e.g., AWS RDS Multi-AZ).
- Gateways: Deploy multiple gateway nodes per region. AWT supports connection migration, so clients can failover between gateways.
Backup and Recovery
- Database: Configure automated daily backups with point-in-time recovery. Retain backups for at least 30 days.
- Configuration: Store your Docker Compose, environment files, and licence in version control.
- Certificates: Keep TLS certificates and private keys in a secrets manager.
Network Security
- Restrict control plane admin port (8080) to your management network
- Place gateways in a DMZ or public subnet with only UDP tunnel port exposed
- Use security groups or firewall rules to limit database access to the control plane only
- Enable PostgreSQL SSL connections
Monitoring
The control plane exposes a health endpoint at /healthz and structured JSON logs on stdout. Integrate with your existing monitoring stack:
- Logs: Ship container logs to your SIEM or log aggregation platform
- Health checks: Monitor
/healthzwith your infrastructure alerting - Metrics: The control plane logs session counts, enrollment events, and gateway health
Capacity Planning
Use the following guidelines for initial sizing:
| Component | Users < 100 | Users < 1,000 | Users < 10,000 |
|---|---|---|---|
| Control Plane | 1 vCPU, 2 GiB | 2 vCPU, 4 GiB | 4 vCPU, 8 GiB |
| PostgreSQL | db.t4g.small | db.t4g.medium | db.r6g.large |
| Gateway (per node) | 2 vCPU, 4 GiB | 4 vCPU, 8 GiB | 8 vCPU, 16 GiB |
Gateway throughput depends on node size. See the capacity model documentation for the detailed formula relating node class, reserved throughput, and user capacity.
Updating
To update your self-hosted deployment:
- Authenticate with the AegisWire registry:
docker login registry.aegiswire.com - Pull the latest container images
- Review the release notes for migration steps
- Update gateway nodes first (rolling restart)
- Update the control plane (it will run database migrations automatically)
- Verify health via
/healthzand the admin interface
AegisWire maintains backward compatibility within a major version. Client devices do not need to be updated simultaneously — they will continue to function with the updated gateway and control plane.