Ports and Network Configuration
1. Prerequisites
Hardware
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB | 2 GB |
| Disk | 20 GB | 40 GB (more for long activity logs and Caddy access logs) |
Software
- OS: Any modern Linux distribution (Debian 11+, Ubuntu 22.04+, Fedora, Rocky, Alma, Alpine). Tested on Debian 13.
- Docker Engine: 24.0 or newer
- Docker Compose: v2 (part of Docker Engine since 23.0)
- WireGuard kernel module: present on most modern kernels. The container does not need an external install, but WireGuard capabilities (
NET_ADMIN) must be grantable to the container.
DNS
Before starting the container you need one DNS A-record (plus optionally AAAA for IPv6) pointing to the public IP of the host:
gate.example.com. IN A 198.51.100.42
GateControl uses this name for two purposes:
- Admin UI via
GC_BASE_URL— Caddy provisions a Let's Encrypt certificate for it automatically on first start. - WireGuard endpoint if you also set
GC_WG_HOST=gate.example.com. (GC_WG_HOSTmay be a bare public IP instead, but using the same hostname simplifies peer configs.)
Per-route domains (for reverse-proxy routes you create later) need separate A-records pointing to the same host.
Ports
| Port | Protocol | Purpose | Must be reachable from |
|---|---|---|---|
| 80 | TCP | HTTP → HTTPS redirect, ACME HTTP-01 challenge | Internet |
| 443 | TCP | HTTPS admin UI and all reverse-proxy routes | Internet |
| 443 | UDP | HTTP/3 (optional but recommended) | Internet |
| 51820 | UDP | WireGuard VPN endpoint | Internet |
| 53 | TCP/UDP on 127.0.0.1 and on the VPN subnet gateway IP (10.8.0.1 by default) |
Internal DNS for VPN peers | Container only (loopback and WG interface) |
If anything already binds 127.0.0.1:53 on the host (a common cause: NetworkManager-dnsmasq, libvirt-dnsmasq, bind9), the GateControl container will refuse to start. systemd-resolved binds 127.0.0.53 and does not conflict. The entrypoint checks this explicitly and exits with a clear message if it finds another listener.
Open the first four ports in your cloud firewall / iptables / ufw before you start the container.
11. Updates
Automatic update
cd /opt/gatecontrol
./update.sh
update.sh pulls the latest image from GHCR, recreates the container only if a new image was actually pulled, and logs to /var/log/gatecontrol-update.log. Safe to schedule via cron or a systemd timer:
# /etc/cron.d/gatecontrol-update
0 3 * * * root /opt/gatecontrol/update.sh
Manual update
cd /opt/gatecontrol
docker compose pull
docker compose up -d
Downtime is roughly 10–30 seconds while the container restarts and Caddy re-reads its persisted state. No data migration is ever required — migrations run automatically on container start, with per-step commits so a failed migration does not roll back successful ones.
Verify after update
curl -s http://127.0.0.1:3000/health | jq .version
The version string should match the tag you pulled.