Netmaker Mesh VPN
Create and manage WireGuard mesh networks with a beautiful web interface.
Overview
Netmaker is an open-source network automation platform that creates and manages WireGuard-based mesh networks through a centralized control plane. Developed by Gravitl, it emerged as a solution to simplify enterprise-grade mesh networking, allowing organizations to connect distributed infrastructure, remote workers, and IoT devices through encrypted tunnels without the complexity of traditional VPN solutions. Unlike hub-and-spoke VPN architectures, Netmaker enables direct peer-to-peer connections between nodes, reducing latency and eliminating single points of failure.
This stack combines Netmaker's core server with a React-based web interface (netmaker-ui), CoreDNS for mesh network name resolution, Eclipse Mosquitto for MQTT-based node communication, and Caddy for automatic HTTPS termination. The architecture creates a complete mesh VPN management platform where Netmaker handles WireGuard configuration and network topology, Mosquitto facilitates real-time communication between the server and mesh nodes, CoreDNS provides internal DNS resolution for mesh participants, and Caddy serves both the web interface and API endpoints with automatic SSL certificates.
This configuration suits organizations requiring secure site-to-site connectivity, DevOps teams managing distributed infrastructure, and network administrators deploying zero-trust architectures. The combination provides enterprise-grade mesh networking capabilities with the operational simplicity of a web-managed platform, making advanced WireGuard deployments accessible without deep networking expertise.
Key Features
- WireGuard mesh network creation with automatic peer configuration and key management
- Real-time node communication and configuration updates via MQTT messaging through Mosquitto
- Integrated DNS resolution for mesh network participants using CoreDNS with dynamic host records
- Web-based network topology visualization and node management through React interface
- Egress and ingress gateway functionality for connecting external networks to the mesh
- Automatic HTTPS certificate provisioning for both dashboard and API endpoints via Caddy
- SQLite-based configuration storage with support for multiple database backends
- UDP hole punching and NAT traversal for direct peer-to-peer connections
Common Use Cases
- 1Site-to-site VPN replacement for connecting multiple office locations with direct inter-site communication
- 2Secure remote access for distributed development teams requiring access to internal services and databases
- 3IoT device connectivity for managing sensors and edge devices across multiple geographic locations
- 4Multi-cloud infrastructure networking to create secure connections between AWS, Azure, and Google Cloud resources
- 5Kubernetes cluster networking for connecting workloads across different cloud providers and on-premises infrastructure
- 6Zero-trust network architecture implementation with granular access controls and encrypted communications
- 7Branch office connectivity for retail or service organizations with multiple small locations
Prerequisites
- Minimum 2GB RAM and 1GB disk space for the complete stack with moderate network size
- Domain name with DNS control for automatic SSL certificate generation and API/dashboard access
- UDP ports 51821-51830 accessible from the internet for WireGuard connections
- Basic understanding of network subnets and routing for mesh network planning
- Linux server with kernel support for WireGuard (kernel 5.6+ or WireGuard kernel module)
- Firewall configuration allowing inbound connections on ports 80, 443, 53, and 1883
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 netmaker: 3 image: gravitl/netmaker:latest4 container_name: netmaker5 cap_add: 6 - NET_ADMIN7 - NET_RAW8 - SYS_MODULE9 sysctls: 10 - net.ipv4.ip_forward=111 - net.ipv4.conf.all.src_valid_mark=112 environment: 13 - SERVER_NAME=${SERVER_NAME}14 - SERVER_HOST=${SERVER_HOST}15 - SERVER_API_CONN_STRING=api.${SERVER_NAME}:44316 - COREDNS_ADDR=${SERVER_HOST}17 - DNS_MODE=on18 - API_PORT=808119 - MASTER_KEY=${MASTER_KEY}20 - DATABASE=sqlite21 - MQ_HOST=mq22 - MQ_PORT=188323 - MQ_SERVER_PORT=188324 volumes: 25 - netmaker-data:/root/data26 - netmaker-dnsconfig:/root/config/dnsconfig27 ports: 28 - "51821-51830:51821-51830/udp"29 networks: 30 - netmaker-network31 restart: unless-stopped3233 netmaker-ui: 34 image: gravitl/netmaker-ui:latest35 container_name: netmaker-ui36 environment: 37 - BACKEND_URL=https://api.${SERVER_NAME}38 depends_on: 39 - netmaker40 networks: 41 - netmaker-network42 restart: unless-stopped4344 coredns: 45 image: coredns/coredns:latest46 container_name: netmaker-coredns47 command: -conf /root/dnsconfig/Corefile48 volumes: 49 - netmaker-dnsconfig:/root/dnsconfig50 ports: 51 - "53:53/udp"52 - "53:53/tcp"53 networks: 54 - netmaker-network55 restart: unless-stopped5657 mq: 58 image: eclipse-mosquitto:259 container_name: netmaker-mq60 volumes: 61 - ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro62 - mq-data:/mosquitto/data63 - mq-logs:/mosquitto/log64 ports: 65 - "1883:1883"66 networks: 67 - netmaker-network68 restart: unless-stopped6970 caddy: 71 image: caddy:alpine72 container_name: netmaker-caddy73 ports: 74 - "80:80"75 - "443:443"76 volumes: 77 - ./Caddyfile:/etc/caddy/Caddyfile:ro78 - caddy-data:/data79 depends_on: 80 - netmaker81 - netmaker-ui82 networks: 83 - netmaker-network84 restart: unless-stopped8586volumes: 87 netmaker-data: 88 netmaker-dnsconfig: 89 mq-data: 90 mq-logs: 91 caddy-data: 9293networks: 94 netmaker-network: 95 driver: bridge.env Template
.env
1# Netmaker Mesh VPN2SERVER_NAME=netmaker.example.com3SERVER_HOST=your_server_ip45# Generate with: tr -dc A-Za-z0-9 </dev/urandom | head -c 326MASTER_KEY=your_master_key_hereUsage Notes
- 1Dashboard at https://dashboard.netmaker.example.com
- 2API at https://api.netmaker.example.com
- 3Create networks and enroll nodes
- 4Supports egress, ingress gateways
- 5DNS resolution for mesh nodes
Individual Services(5 services)
Copy individual services to mix and match with your existing compose files.
netmaker
netmaker:
image: gravitl/netmaker:latest
container_name: netmaker
cap_add:
- NET_ADMIN
- NET_RAW
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
environment:
- SERVER_NAME=${SERVER_NAME}
- SERVER_HOST=${SERVER_HOST}
- SERVER_API_CONN_STRING=api.${SERVER_NAME}:443
- COREDNS_ADDR=${SERVER_HOST}
- DNS_MODE=on
- API_PORT=8081
- MASTER_KEY=${MASTER_KEY}
- DATABASE=sqlite
- MQ_HOST=mq
- MQ_PORT=1883
- MQ_SERVER_PORT=1883
volumes:
- netmaker-data:/root/data
- netmaker-dnsconfig:/root/config/dnsconfig
ports:
- 51821-51830:51821-51830/udp
networks:
- netmaker-network
restart: unless-stopped
netmaker-ui
netmaker-ui:
image: gravitl/netmaker-ui:latest
container_name: netmaker-ui
environment:
- BACKEND_URL=https://api.${SERVER_NAME}
depends_on:
- netmaker
networks:
- netmaker-network
restart: unless-stopped
coredns
coredns:
image: coredns/coredns:latest
container_name: netmaker-coredns
command: "-conf /root/dnsconfig/Corefile"
volumes:
- netmaker-dnsconfig:/root/dnsconfig
ports:
- 53:53/udp
- 53:53/tcp
networks:
- netmaker-network
restart: unless-stopped
mq
mq:
image: eclipse-mosquitto:2
container_name: netmaker-mq
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
- mq-data:/mosquitto/data
- mq-logs:/mosquitto/log
ports:
- "1883:1883"
networks:
- netmaker-network
restart: unless-stopped
caddy
caddy:
image: caddy:alpine
container_name: netmaker-caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
depends_on:
- netmaker
- netmaker-ui
networks:
- netmaker-network
restart: unless-stopped
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 netmaker:5 image: gravitl/netmaker:latest6 container_name: netmaker7 cap_add:8 - NET_ADMIN9 - NET_RAW10 - SYS_MODULE11 sysctls:12 - net.ipv4.ip_forward=113 - net.ipv4.conf.all.src_valid_mark=114 environment:15 - SERVER_NAME=${SERVER_NAME}16 - SERVER_HOST=${SERVER_HOST}17 - SERVER_API_CONN_STRING=api.${SERVER_NAME}:44318 - COREDNS_ADDR=${SERVER_HOST}19 - DNS_MODE=on20 - API_PORT=808121 - MASTER_KEY=${MASTER_KEY}22 - DATABASE=sqlite23 - MQ_HOST=mq24 - MQ_PORT=188325 - MQ_SERVER_PORT=188326 volumes:27 - netmaker-data:/root/data28 - netmaker-dnsconfig:/root/config/dnsconfig29 ports:30 - "51821-51830:51821-51830/udp"31 networks:32 - netmaker-network33 restart: unless-stopped3435 netmaker-ui:36 image: gravitl/netmaker-ui:latest37 container_name: netmaker-ui38 environment:39 - BACKEND_URL=https://api.${SERVER_NAME}40 depends_on:41 - netmaker42 networks:43 - netmaker-network44 restart: unless-stopped4546 coredns:47 image: coredns/coredns:latest48 container_name: netmaker-coredns49 command: -conf /root/dnsconfig/Corefile50 volumes:51 - netmaker-dnsconfig:/root/dnsconfig52 ports:53 - "53:53/udp"54 - "53:53/tcp"55 networks:56 - netmaker-network57 restart: unless-stopped5859 mq:60 image: eclipse-mosquitto:261 container_name: netmaker-mq62 volumes:63 - ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro64 - mq-data:/mosquitto/data65 - mq-logs:/mosquitto/log66 ports:67 - "1883:1883"68 networks:69 - netmaker-network70 restart: unless-stopped7172 caddy:73 image: caddy:alpine74 container_name: netmaker-caddy75 ports:76 - "80:80"77 - "443:443"78 volumes:79 - ./Caddyfile:/etc/caddy/Caddyfile:ro80 - caddy-data:/data81 depends_on:82 - netmaker83 - netmaker-ui84 networks:85 - netmaker-network86 restart: unless-stopped8788volumes:89 netmaker-data:90 netmaker-dnsconfig:91 mq-data:92 mq-logs:93 caddy-data:9495networks:96 netmaker-network:97 driver: bridge98EOF99100# 2. Create the .env file101cat > .env << 'EOF'102# Netmaker Mesh VPN103SERVER_NAME=netmaker.example.com104SERVER_HOST=your_server_ip105106# Generate with: tr -dc A-Za-z0-9 </dev/urandom | head -c 32107MASTER_KEY=your_master_key_here108EOF109110# 3. Start the services111docker compose up -d112113# 4. View logs114docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/netmaker-mesh/run | bashTroubleshooting
- Nodes fail to connect after enrollment: Check that UDP ports 51821-51830 are properly forwarded and accessible from client networks
- CoreDNS fails to start with 'bind: address already in use': Stop systemd-resolved or change host DNS port binding to avoid port 53 conflicts
- Caddy SSL certificate generation fails: Verify domain DNS records point to server IP and ports 80/443 are accessible for Let's Encrypt challenges
- MQTT connection errors in Netmaker logs: Ensure Mosquitto container is healthy and port 1883 is accessible within the Docker network
- Netmaker API returns 'database locked' errors: Check that only one Netmaker instance is running and SQLite database file permissions are correct
- Mesh nodes lose connectivity intermittently: Verify NAT traversal settings and consider configuring relay servers for nodes behind strict firewalls
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
netmakernetmaker-uicorednscaddymosquitto
Tags
#vpn#wireguard#mesh#netmaker#networking
Category
Security & NetworkingAd Space
Shortcuts: C CopyF FavoriteD Download