Skip to content

Sharing Mocks Publicly

This guide covers how to expose your local mockd server to the internet, enabling teammates, clients, or external services to access your mocks.

mockd supports several ways to share your mocks publicly:

MethodCostProtocolsBest For
mockd tunnel (built-in)FreeAll 7 protocolsRecommended for all users
Third-party tunnelsFreeHTTP, WebSocket, SSEAlternative if built-in tunnel is unavailable
Self-hosted relayYour infraAll protocolsEnterprise, air-gapped environments

mockd’s built-in tunnel supports all seven protocols through a single secure connection on port 443:

ProtocolTunnel SupportHow It Works
HTTP/HTTPSYesStandard HTTPS
gRPCYesNative HTTP/2 with trailers (not gRPC-web)
WebSocketYesUpgrade proxied, bidirectional streaming
MQTTYesTLS ALPN routing (mqtt) on port 443
SSEYesStreaming responses
GraphQLYesOver HTTP
SOAPYesOver HTTP

mockd includes a built-in cloud tunnel that exposes your local mocks to the internet with a single command. No signup required for anonymous tunnels (2-hour session, 100MB bandwidth).

Terminal window
# Start mock server + tunnel in one shot (recommended)
mockd tunnel --config mocks.yaml
# Output:
# Connecting to relay at relay.mockd.io:443...
# Anonymous token acquired (2h session, 100MB bandwidth)
#
# Tunnel connected!
# Public URL: https://a1b2c3d4.tunnel.mockd.io
# Local server: http://localhost:4280
# Admin API: http://localhost:4290

Your mocks are now accessible at https://a1b2c3d4.tunnel.mockd.io.

Alternatively, if you already have a running mockd server, enable the tunnel on it:

Terminal window
# Start your mock server
mockd serve --config mocks.yaml
# In another terminal, enable the tunnel
mockd tunnel enable

All protocols are tunneled automatically through the single secure connection:

Terminal window
# Start tunnel with a config that includes gRPC, MQTT, etc.
mockd tunnel --config multi-protocol.yaml
# Test gRPC through the tunnel
grpcurl -d '{"name": "World"}' a1b2c3d4.tunnel.mockd.io:443 helloworld.Greeter/SayHello
# Test MQTT through the tunnel (requires TLS ALPN client)
mosquitto_pub -h a1b2c3d4.tunnel.mockd.io -p 443 --alpn mqtt \
--capath /etc/ssl/certs -t test/hello -m "Hello!"

Protect your tunnel from unauthorized access:

Use exactly one auth mode per tunnel. --auth-token, --auth-basic, and --allow-ips are mutually exclusive.

Terminal window
# Require bearer token
mockd tunnel --config mocks.yaml --auth-token secret123
# Require HTTP Basic Auth
mockd tunnel --config mocks.yaml --auth-basic admin:password
# Restrict by IP range
mockd tunnel --config mocks.yaml --allow-ips "10.0.0.0/8,192.168.1.0/24"
  • Webhook development: Expose mocks to receive webhooks from Stripe, GitHub, etc.
  • Team sharing: Share mocks with remote teammates without deploying
  • Client demos: Show API mocks to stakeholders with a public URL
  • CI/CD integration: Use tunneled endpoints in integration test pipelines
  • Mobile testing: Test mobile apps against mocks on a real device

For quick testing or if you’re using the OSS version, you can use free third-party tunnel services.

localtunnel is free, requires no signup, and supports HTTP/WebSocket/SSE.

Terminal window
# Install
npm install -g localtunnel
# Start mockd
mockd serve
# In another terminal, create tunnel
lt --port 4280
# Output: your url is: https://random-name.loca.lt

Testing your tunnel:

Terminal window
# Add a mock
mockd http add --path /api/users --body '{"users": [{"id": 1, "name": "Alice"}]}'
# Test via tunnel (note the bypass header)
curl -H "bypass-tunnel-reminder: true" https://random-name.loca.lt/api/users

WebSocket through localtunnel:

// localtunnel supports WebSocket upgrade
const ws = new WebSocket('wss://random-name.loca.lt/ws/chat');
ws.onopen = () => ws.send('Hello from tunnel!');

ngrok offers a free tier with signup. Better reliability than localtunnel.

Terminal window
# Install (see ngrok.com/download)
# Configure auth token (one-time)
ngrok config add-authtoken YOUR_TOKEN
# Start tunnel
ngrok http 4280

ngrok features:

  • Stable URLs (paid)
  • Request inspection dashboard
  • Custom domains (paid)

If you have a Cloudflare account with a domain, Cloudflare Tunnel provides free, unlimited HTTP tunneling.

Terminal window
# Install cloudflared
# See: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/
# Quick tunnel (temporary URL)
cloudflared tunnel --url http://localhost:4280
# Named tunnel (persistent, requires setup)
cloudflared tunnel create mockd
cloudflared tunnel route dns mockd mocks.yourdomain.com
cloudflared tunnel run mockd
Featurelocaltunnelngrok (free)Cloudflare Tunnel
CostFreeFree (limited)Free
Signup requiredNoYesYes (+ domain)
Stable URLsNoNo (paid only)Yes
WebSocketYesYesYes
SSEYesYesYes
TCP tunnelsNoPaid onlyNo
Request inspectionNoYesYes
TierSession DurationBandwidthSubdomainSignup
Anonymous2 hours100 MBRandomNo
Free8 hours1 GBRandomYes
Pro ($12/mo)24 hours5 GB/moCustomYes
Team ($29/mo)Unlimited50 GB/moCustom + domainYes

Anonymous tunnels require no signup or token — just run mockd tunnel.

For enterprise users or those needing full control, you can run your own relay server.

version: '3.8'
services:
mockd-relay:
image: ghcr.io/getmockd/relay:latest
ports:
- "80:80"
- "443:443"
environment:
- MOCKD_DOMAIN=relay.yourcompany.com
- MOCKD_TLS_EMAIL=admin@yourcompany.com
volumes:
- caddy_data:/data
volumes:
caddy_data:
Terminal window
mockd tunnel --relay wss://relay.yourcompany.com/tunnel --token YOUR_TOKEN
Terminal window
helm repo add mockd https://charts.mockd.dev
helm install mockd-relay mockd/relay \
--set domain=relay.yourcompany.com \
--set tls.email=admin@yourcompany.com

By default, tunnels are public. Add authentication for sensitive mocks:

Terminal window
# Require bearer token
mockd tunnel --auth-token secret123
# Require HTTP Basic Auth
mockd tunnel --auth-basic admin:password
# Restrict by IP
mockd tunnel --allow-ips "10.0.0.0/8,192.168.1.0/24"

When you create a tunnel:

  • Exposed: The local port you specify with --port (HTTP, gRPC, WebSocket, SSE)
  • Exposed: MQTT broker ports (via TLS ALPN routing)
  • NOT exposed: Admin API (port 4290) — unless explicitly tunneled
  • NOT exposed: Other local services
  1. Use authentication for any non-trivial testing
  2. Disable mocks you don’t want publicly accessible
  3. Monitor usage via mockd logs or cloud dashboard
  4. Stop tunnels when not actively needed
  5. Use short-lived tunnels for demos rather than persistent ones

Check that mockd is running and accessible locally:

Terminal window
curl http://localhost:4280/health

Some tunnel providers have idle timeouts. Configure heartbeat in your WebSocket mock config:

# In your YAML config file
websocket:
path: /ws
heartbeat:
enabled: true
interval: "30s"
timeout: "10s"

Ensure your tunnel provider supports long-lived connections. localtunnel and ngrok both support SSE.

The tunnel is working but no mock matches the request. Check your mock configuration:

Terminal window
mockd list