Deployment guide

Hoverfly

Overview

Hoverfly is a lightweight, open-source API simulation and service virtualization tool developed by SpectoLabs. It sits as a proxy in front of the HTTP and HTTPS services your application depends on. It can capture real traffic, replay it as fast, deterministic virtual services, spy on requests, or modify responses on the fly.

With Hoverfly, teams develop and test against realistic simulations of third-party or internal APIs that are slow, rate-limited, costly or not yet built. You can reproduce specific responses, latencies and failure modes on demand.

This image runs on Ubuntu 24.04 and installs the pinned official Hoverfly 1.12.10 release, verified by checksum. It runs under systemd as the unprivileged hoverfly user. Both the hoverfly server and the hoverctl command-line tool are installed to /usr/local/bin.

Ready on first boot. The image ships a working demo simulation, so Hoverfly virtualises traffic the moment the VM boots. A single request/response pair virtualises GET http://demo.sac.local/api/health. Sending that request through the proxy returns a canned JSON response, a real service virtualization round trip that you can see immediately. Replace the demo with your own captured or authored simulations when you are ready (see Step 7).

Authentication is enabled. Hoverfly's admin API is unauthenticated out of the box. This image enables authentication and generates a unique admin password and a JWT signing secret on each VM's first boot, written to a root-only file. Nothing is baked into the image. The admin API requires a JWT, obtained from your admin credentials. Because authentication is enabled, the proxy also requires credentials, so it is never an open relay.

Everything is bound to loopback. Both the admin API (127.0.0.1:8888) and the proxy (127.0.0.1:8500) are bound to loopback only. An nginx reverse proxy on port 80 fronts the admin API, so it is reachable off the box only through Hoverfly's own token authentication. The proxy is private by default, and you expose it deliberately to trusted clients when you need to (see Step 8). The only inbound ports on the image are SSH 22 and the nginx admin port 80.

What you get:

  • Hoverfly 1.12.10 (pinned, checksum verified), plus hoverctl, run under systemd as the unprivileged hoverfly user (hoverfly.service)
  • A working demo simulation, so the proxy virtualises traffic on first boot
  • Authentication enabled with a unique admin password and JWT secret generated per VM, and nothing baked into the image
  • The admin API and proxy bound to loopback, with nginx fronting the admin API on port 80 behind Hoverfly's own token authentication
  • A proxy that is never an open relay: it requires credentials and is not exposed by default
  • Unattended security upgrades left enabled, so the OS keeps receiving patches

Prerequisites

Before you deploy this image you need:

  • An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
  • A subscription to the Hoverfly listing on Azure Marketplace
  • Network security group (NSG) rules that allow TCP 22 for administration and TCP 80 for the admin API

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for development and test use. For simulations that serve heavy traffic, use Standard_D2s_v5 or larger.

1

Deploy from the Azure Portal

Search for Hoverfly in the Marketplace, select the SecureAnyCloud publisher, and select Create.

Configure the network security group to allow TCP 22 for administration and TCP 80 for the admin API.

The Hoverfly proxy is not exposed by default. If you later choose to expose it to trusted clients, open only that port, and only from the networks that should reach it (see Step 8).

2

Deploy from the Azure CLI

Accept the Marketplace terms, create the VM and open ports 22 and 80:

RG="devtools-prod"; LOCATION="eastus"; VM_NAME="hoverfly1" IMAGE_URN="sac1647283583153:hoverfly-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:hoverfly-ubuntu-24-04:default:latest
az vm create \
  --resource-group "$RG" --name "$VM_NAME" \
  --image "$IMAGE_URN" \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values "$SSH_KEY" \
  --public-ip-sku Standard
# Open SSH and the admin API port on the VM's NSG:
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 80 --priority 1002
3

First boot

On first boot, the image generates a unique admin username and password and a JWT signing secret, enables authentication and starts Hoverfly. It then proves the authentication round trip and the demo simulation, starts nginx, and writes /root/hoverfly-credentials.txt. This completes within a minute.

SSH in as azureuser and read your credentials:

sudo cat /root/hoverfly-credentials.txt

The file records the admin username, the per-VM admin password and the off-box admin URL. Store the password somewhere safe. It is unique to this VM and is the only credential that can obtain an admin token or use the proxy.

4

Confirm the service is running

Confirm that hoverfly.service and nginx.service are active, that hoverfly -version reports the pinned release, and that the admin API answers /api/health on loopback:

systemctl is-active hoverfly.service nginx.service hoverfly -version curl -s http://127.0.0.1:8888/api/health

Expected output:

active active v1.12.10 {"message":"Hoverfly is healthy"}
5

Authenticate to the admin API

Authentication is enabled, so the admin API rejects unauthenticated requests with 401. To use it, obtain a JSON Web Token from your per-VM admin credentials by posting to /api/token-auth, then send that token as a Bearer header.

The block below reads the credentials from the first-boot file and performs the full round trip against the loopback admin API:

sudo bash -c ' U=$(grep "^HOVERFLY_ADMIN_USERNAME=" /root/hoverfly-credentials.txt | cut -d= -f2-) PW=$(grep "^HOVERFLY_ADMIN_PASSWORD=" /root/hoverfly-credentials.txt | cut -d= -f2-) echo -n "unauthenticated GET /api/v2/hoverfly -> HTTP " curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8888/api/v2/hoverfly TOKEN=$(curl -s -H "Content-Type: application/json" -X POST \
  -d "{\"Username\":\"$U\",\"Password\":\"$PW\"}" \
  http://127.0.0.1:8888/api/token-auth | jq -r .token) echo "obtained a JWT (first 40 chars): ${TOKEN:0:40}..." echo "authenticated GET /api/v2/hoverfly/mode:" curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8888/api/v2/hoverfly/mode echo '

Expected output (the mode is simulate, the default for serving virtual services):

unauthenticated GET /api/v2/hoverfly -> HTTP 401 obtained a JWT (first 40 chars): eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ... authenticated GET /api/v2/hoverfly/mode: {"mode":"simulate","arguments":{"matchingStrategy":"strongest"}}

The admin API is also reachable off the box at http://<public-ip>/, because nginx forwards port 80 to the loopback admin API. The same token authentication protects it. To manage Hoverfly remotely, replace http://127.0.0.1:8888 with http://<public-ip> in the commands above.

6

Send a request through the proxy

The shipped demo simulation virtualises GET http://demo.sac.local/api/health. Because authentication is enabled, the proxy also requires credentials, so it rejects an unauthenticated request with 407. Supply your admin credentials as HTTP Basic proxy credentials, and the proxy returns the simulated response:

sudo bash -c ' U=$(grep "^HOVERFLY_ADMIN_USERNAME=" /root/hoverfly-credentials.txt | cut -d= -f2-) PW=$(grep "^HOVERFLY_ADMIN_PASSWORD=" /root/hoverfly-credentials.txt | cut -d= -f2-) echo -n "unauthenticated proxy request -> HTTP " curl -s -o /dev/null -w "%{http_code}\n" -x http://127.0.0.1:8500 http://demo.sac.local/api/health echo "authenticated proxy request (the demo simulation):" curl -s --proxy-user "$U:$PW" -x http://127.0.0.1:8500 http://demo.sac.local/api/health echo '

Expected output:

unauthenticated proxy request -> HTTP 407 authenticated proxy request (the demo simulation): {"status":"ok","service":"sac-hoverfly-demo","virtualized":true}

This is a complete service virtualization round trip. The request never reaches a real demo.sac.local server, because Hoverfly answers it from the shipped simulation. Point any HTTP client's proxy at Hoverfly, and requests that it has a simulation for are answered instantly and deterministically.

7

Capture and author your own simulations

Replace the demo with your own simulations using hoverctl, the Hoverfly command-line tool. The typical workflow is to run Hoverfly in capture mode, send your application's real traffic through it to record the responses, then switch back to simulate mode to replay them. Simulations are portable JSON files that you can capture once and commit to source control.

The shipped simulation lives at /etc/hoverfly/demo-simulation.json. Inspect the current simulation through the admin API:

sudo bash -c ' U=$(grep "^HOVERFLY_ADMIN_USERNAME=" /root/hoverfly-credentials.txt | cut -d= -f2-) PW=$(grep "^HOVERFLY_ADMIN_PASSWORD=" /root/hoverfly-credentials.txt | cut -d= -f2-) TOKEN=$(curl -s -H "Content-Type: application/json" -X POST \
  -d "{\"Username\":\"$U\",\"Password\":\"$PW\"}" \
  http://127.0.0.1:8888/api/token-auth | jq -r .token) curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8888/api/v2/simulation | jq ".data.pairs[0].request.path" '

Expected output:

[ { "matcher": "exact", "value": "/api/health" } ]

To capture new simulations with hoverctl, point it at a target and switch modes. For example, record traffic to a real API and export it to a file:

hoverctl mode capture
# ... send your application's traffic through the proxy on port 8500 ... hoverctl mode simulate hoverctl export my-service.json

Then load the saved simulation on any Hoverfly instance:

hoverctl import my-service.json

See the Hoverfly documentation for the full capture, matching and templating reference.

8

Expose the proxy to trusted clients

The proxy is bound to loopback and is not exposed by the network security group. For an application on another host to use Hoverfly for service virtualization, expose the proxy deliberately. The safest option is an SSH tunnel from the client, which needs no open port:

ssh -L 8500:127.0.0.1:8500 azureuser@<public-ip>
# then on the client, use the proxy at 127.0.0.1:8500 with your admin credentials

If you need the proxy reachable directly, rebind Hoverfly to a routable interface by adding -listen-on-host 0.0.0.0 to the service command in /etc/systemd/system/hoverfly.service. Then add a network security group rule for TCP 8500 scoped to the specific client CIDR, never to the whole internet.

Authentication remains enforced, so clients still need the admin credentials. Scoping the rule is still essential defence in depth.

9

Manage the service

Manage Hoverfly with systemd. Check the service status:

systemctl status hoverfly.service --no-pager

Restart the service, for example after you edit the simulation or the service command:

sudo systemctl restart hoverfly.service

The runtime environment, including the per-VM admin credentials and JWT secret, lives in /etc/default/hoverfly (root only). The BoltDB store that holds users and tokens lives at /var/lib/hoverfly/hoverfly.db.

10

Security recommendations

Both the admin API and the proxy are bound to loopback, and only SSH 22 and the nginx admin port 80 are exposed. Confirm the listening sockets at any time:

ss -tln | grep -E ':(22|80|8888|8500)\b'

Keep the admin API and proxy on loopback. Both are bound to 127.0.0.1 and reached off the box only through nginx (admin) or an SSH tunnel (proxy). Do not rebind to 0.0.0.0 without scoping a network security group rule to specific client networks.

Terminate TLS in front of nginx. Port 80 is plain HTTP. For production, add a TLS certificate to the nginx server block so that admin credentials and tokens are encrypted in transit.

Rotate the admin password if it is ever exposed. The password is generated per VM and stored in /root/hoverfly-credentials.txt and /etc/default/hoverfly. To rotate it, update HoverflyAdminPass in /etc/default/hoverfly, remove /var/lib/hoverfly/hoverfly.db, and restart the service.

Scope any proxy exposure tightly. If you expose the proxy on port 8500, restrict the network security group rule to the exact client CIDR. An open forward proxy is an abuse relay.

Keep the OS and Hoverfly patched. Unattended security upgrades remain enabled for the OS. Track new Hoverfly releases and update the binaries when you upgrade.

11

Support and Licensing

Hoverfly is developed by SpectoLabs and distributed under the Apache License 2.0. It is free and open source, with no per-CPU or per-deployment fee. This image bundles the unmodified official Hoverfly release.

SecureAnyCloud provides the packaging, the working demo simulation, enabled authentication with per-VM credentials, loopback-only bindings, the nginx-fronted admin API, a proxy that is never an open relay, and 24/7 support with a guaranteed 24 hour response SLA.

SecureAnyCloud is not affiliated with or endorsed by SpectoLabs. Hoverfly is a mark of its respective owner and is used here only to identify the software.

Deploy on Azure

Find Hoverfly on Ubuntu 24.04 LTS on the Azure Marketplace, published by SecureAnyCloud. Deploy from the Portal or the Azure CLI as shown above.

Need Help?

Email sales@secureanycloud.com for deployment help, configuration questions, or licensing enquiries.

Deploy on Azure

Launch Hoverfly API Simulation Proxy on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure