docker.recipes

Netmaker Mesh VPN

advanced

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:latest
4 container_name: netmaker
5 cap_add:
6 - NET_ADMIN
7 - NET_RAW
8 - SYS_MODULE
9 sysctls:
10 - net.ipv4.ip_forward=1
11 - net.ipv4.conf.all.src_valid_mark=1
12 environment:
13 - SERVER_NAME=${SERVER_NAME}
14 - SERVER_HOST=${SERVER_HOST}
15 - SERVER_API_CONN_STRING=api.${SERVER_NAME}:443
16 - COREDNS_ADDR=${SERVER_HOST}
17 - DNS_MODE=on
18 - API_PORT=8081
19 - MASTER_KEY=${MASTER_KEY}
20 - DATABASE=sqlite
21 - MQ_HOST=mq
22 - MQ_PORT=1883
23 - MQ_SERVER_PORT=1883
24 volumes:
25 - netmaker-data:/root/data
26 - netmaker-dnsconfig:/root/config/dnsconfig
27 ports:
28 - "51821-51830:51821-51830/udp"
29 networks:
30 - netmaker-network
31 restart: unless-stopped
32
33 netmaker-ui:
34 image: gravitl/netmaker-ui:latest
35 container_name: netmaker-ui
36 environment:
37 - BACKEND_URL=https://api.${SERVER_NAME}
38 depends_on:
39 - netmaker
40 networks:
41 - netmaker-network
42 restart: unless-stopped
43
44 coredns:
45 image: coredns/coredns:latest
46 container_name: netmaker-coredns
47 command: -conf /root/dnsconfig/Corefile
48 volumes:
49 - netmaker-dnsconfig:/root/dnsconfig
50 ports:
51 - "53:53/udp"
52 - "53:53/tcp"
53 networks:
54 - netmaker-network
55 restart: unless-stopped
56
57 mq:
58 image: eclipse-mosquitto:2
59 container_name: netmaker-mq
60 volumes:
61 - ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
62 - mq-data:/mosquitto/data
63 - mq-logs:/mosquitto/log
64 ports:
65 - "1883:1883"
66 networks:
67 - netmaker-network
68 restart: unless-stopped
69
70 caddy:
71 image: caddy:alpine
72 container_name: netmaker-caddy
73 ports:
74 - "80:80"
75 - "443:443"
76 volumes:
77 - ./Caddyfile:/etc/caddy/Caddyfile:ro
78 - caddy-data:/data
79 depends_on:
80 - netmaker
81 - netmaker-ui
82 networks:
83 - netmaker-network
84 restart: unless-stopped
85
86volumes:
87 netmaker-data:
88 netmaker-dnsconfig:
89 mq-data:
90 mq-logs:
91 caddy-data:
92
93networks:
94 netmaker-network:
95 driver: bridge

.env Template

.env
1# Netmaker Mesh VPN
2SERVER_NAME=netmaker.example.com
3SERVER_HOST=your_server_ip
4
5# Generate with: tr -dc A-Za-z0-9 </dev/urandom | head -c 32
6MASTER_KEY=your_master_key_here

Usage Notes

  1. 1Dashboard at https://dashboard.netmaker.example.com
  2. 2API at https://api.netmaker.example.com
  3. 3Create networks and enroll nodes
  4. 4Supports egress, ingress gateways
  5. 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 file
2cat > docker-compose.yml << 'EOF'
3services:
4 netmaker:
5 image: gravitl/netmaker:latest
6 container_name: netmaker
7 cap_add:
8 - NET_ADMIN
9 - NET_RAW
10 - SYS_MODULE
11 sysctls:
12 - net.ipv4.ip_forward=1
13 - net.ipv4.conf.all.src_valid_mark=1
14 environment:
15 - SERVER_NAME=${SERVER_NAME}
16 - SERVER_HOST=${SERVER_HOST}
17 - SERVER_API_CONN_STRING=api.${SERVER_NAME}:443
18 - COREDNS_ADDR=${SERVER_HOST}
19 - DNS_MODE=on
20 - API_PORT=8081
21 - MASTER_KEY=${MASTER_KEY}
22 - DATABASE=sqlite
23 - MQ_HOST=mq
24 - MQ_PORT=1883
25 - MQ_SERVER_PORT=1883
26 volumes:
27 - netmaker-data:/root/data
28 - netmaker-dnsconfig:/root/config/dnsconfig
29 ports:
30 - "51821-51830:51821-51830/udp"
31 networks:
32 - netmaker-network
33 restart: unless-stopped
34
35 netmaker-ui:
36 image: gravitl/netmaker-ui:latest
37 container_name: netmaker-ui
38 environment:
39 - BACKEND_URL=https://api.${SERVER_NAME}
40 depends_on:
41 - netmaker
42 networks:
43 - netmaker-network
44 restart: unless-stopped
45
46 coredns:
47 image: coredns/coredns:latest
48 container_name: netmaker-coredns
49 command: -conf /root/dnsconfig/Corefile
50 volumes:
51 - netmaker-dnsconfig:/root/dnsconfig
52 ports:
53 - "53:53/udp"
54 - "53:53/tcp"
55 networks:
56 - netmaker-network
57 restart: unless-stopped
58
59 mq:
60 image: eclipse-mosquitto:2
61 container_name: netmaker-mq
62 volumes:
63 - ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
64 - mq-data:/mosquitto/data
65 - mq-logs:/mosquitto/log
66 ports:
67 - "1883:1883"
68 networks:
69 - netmaker-network
70 restart: unless-stopped
71
72 caddy:
73 image: caddy:alpine
74 container_name: netmaker-caddy
75 ports:
76 - "80:80"
77 - "443:443"
78 volumes:
79 - ./Caddyfile:/etc/caddy/Caddyfile:ro
80 - caddy-data:/data
81 depends_on:
82 - netmaker
83 - netmaker-ui
84 networks:
85 - netmaker-network
86 restart: unless-stopped
87
88volumes:
89 netmaker-data:
90 netmaker-dnsconfig:
91 mq-data:
92 mq-logs:
93 caddy-data:
94
95networks:
96 netmaker-network:
97 driver: bridge
98EOF
99
100# 2. Create the .env file
101cat > .env << 'EOF'
102# Netmaker Mesh VPN
103SERVER_NAME=netmaker.example.com
104SERVER_HOST=your_server_ip
105
106# Generate with: tr -dc A-Za-z0-9 </dev/urandom | head -c 32
107MASTER_KEY=your_master_key_here
108EOF
109
110# 3. Start the services
111docker compose up -d
112
113# 4. View logs
114docker compose logs -f

One-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 | bash

Troubleshooting

  • 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

Ad Space