Stoplight Prism on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of Stoplight Prism on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Prism is a popular open source HTTP mock server and contract validation proxy. You point it at an API description in OpenAPI, Swagger or Postman format and it stands up a live mock server in seconds: every endpoint returns realistic, schema conformant example responses, and every incoming request is validated against the contract so mismatches are caught immediately. It lets front end, mobile and integration teams build against an API before the real backend exists, and lets teams prove that a running service actually honours its published contract.
The image installs Prism 5.16.0 (@stoplight/prism-cli) from the public npm registry, pinned to an exact version, on the Node.js 24 LTS runtime that Prism requires. Prism runs as a dedicated unprivileged prism system user under systemd (prism.service) and serves the mock on port 4010. A sensible starter OpenAPI 3.0 specification, the cloudimg Sample Widgets API, ships at /opt/prism/spec/cloudimg-sample-api.yaml and is served on first boot, so you can call a live mock immediately and then replace it with your own description whenever you are ready.
Secure by default, and honest about what that means. Prism is by design an unauthenticated mock server: serving a mock API to any client that can reach the port is its normal, intended function, so there is no login, password or token to manage and nothing to rotate. The image applies an honest secure by default posture around it: the mock returns only synthetic example data from the specification you provide and exposes no host secret, no filesystem and no administrative surface; Prism runs as an unprivileged user under a hardened systemd unit with the operating system kept read only outside its own state directory; and the only network listener is the mock itself. No SSH key and no default operating system credential are baked into the image.
What is included:
-
Stoplight Prism 5.16.0 (
@stoplight/prism-cli) from the public npm registry, pinned, run under systemd (prism.service) as an unprivilegedprismuser, serving the mock on port 4010 -
Node.js 24 LTS (
Krypton) from NodeSource, the runtime Prism 5.16.0 requires (enginesnode >=24.18.0) -
A starter OpenAPI 3.0 specification (the cloudimg Sample Widgets API) at
/opt/prism/spec/cloudimg-sample-api.yaml, served as a working mock out of the box, ready to be replaced with your own description -
A hardened systemd unit and a run wrapper that selects mock or proxy mode from
/etc/prism/prism.env -
A fully patched Ubuntu 24.04 LTS base with unattended security upgrades enabled
Prerequisites
-
Active Azure subscription, SSH public key, VNet + subnet in target region
-
Subscription to the Stoplight Prism listing on Azure Marketplace
-
Network Security Group rules allowing TCP 22 (admin) and TCP 4010 (the mock API) from the developers, test runners and CI agents that will consume the mock
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is ample. Prism is a lightweight Node.js process; increase the size only if you drive very high request concurrency.
Step 1: Deploy from the Azure Portal
Search Stoplight Prism in Marketplace, select the cloudimg publisher, and click Create. Configure the Network Security Group to allow TCP 4010 from the clients and CI agents that will use the mock, and TCP 22 for administration. Keep 4010 restricted to the networks you serve.
Step 2: Deploy from the Azure CLI
RG="stoplight-prism-prod"; LOCATION="eastus"; VM_NAME="prism1"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/stoplight-prism-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$GALLERY_IMAGE_ID" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 4010 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1002
Step 3: First boot and the per instance info note
On first boot the image resolves this VM's address, (re)starts Prism with the shipped configuration, and writes a root only info note recording the reachable mock URL. This completes within seconds. SSH in as azureuser and read the note:
sudo cat /root/prism-info.txt
The note records PRISM_MOCK_URL for this instance plus ready to paste curl examples. Because Prism is an unauthenticated mock by design, the note contains no credential; it is purely a convenience.
Step 4: Confirm the service is running
prism.service is active and Prism is listening on port 4010.
systemctl is-active prism.service
prism --version
sudo ss -tlnp | grep ':4010 '

Step 5: Call the mock
The mock serves the endpoints defined in the shipped OpenAPI specification. GET /health is a liveness probe, and GET /widgets returns a schema conformant example array straight from the spec. These are real mocked responses, not just status codes.
curl -s http://127.0.0.1:4010/health | jq .
curl -s http://127.0.0.1:4010/widgets | jq .
curl -s http://127.0.0.1:4010/widgets/1 | jq .
Prism selects the example from the specification and returns it with the correct status code and content type, so your clients receive realistic data before the real backend exists.

Step 6: Contract validation catches bad requests
Prism validates every incoming request against the contract. A request that matches the specification is accepted; a request that violates it is rejected with HTTP 422 and a body that explains exactly what was wrong. The sample POST /widgets requires a name property, so a request without one is rejected.
# a valid request that matches the contract is accepted (201)
curl -s -o /dev/null -w 'valid POST -> HTTP %{http_code}\n' \
-X POST http://127.0.0.1:4010/widgets \
-H 'Content-Type: application/json' -d '{"name":"Gadget","color":"red"}'
# an invalid request (missing the required name) is rejected (422)
curl -s -o /dev/null -w 'invalid POST -> HTTP %{http_code}\n' \
-X POST http://127.0.0.1:4010/widgets \
-H 'Content-Type: application/json' -d '{"color":"red"}'
# the 422 body explains exactly which part of the contract was violated
curl -s -X POST http://127.0.0.1:4010/widgets \
-H 'Content-Type: application/json' -d '{"color":"red"}' | jq .
The validation message reads Request body must have required property 'name', which is how Prism tells a client precisely how it broke the contract.

Step 7: Verify the appliance end to end
A self test ships on the image and proves the whole mock round trip plus contract validation in one command. Run it at any time.
sudo /usr/local/bin/prism-selftest
grep '^PRISM_MOCK_URL=' /root/prism-info.txt
It prints an OK line after confirming /health, /widgets, a valid create and the invalid request rejection.

Step 8: Serve your own API description
Replace the sample specification with your own OpenAPI, Swagger or Postman description. Copy your file onto the VM, point PRISM_SPEC at it, and restart the service.
sudo nano /etc/prism/prism.env
# set PRISM_SPEC=/opt/prism/spec/my-api.yaml (or a URL), then save and:
sudo systemctl restart prism.service
PRISM_SPEC accepts a local file path or an http(s) URL. The rest of the environment file documents every option inline.
Step 9: Switch between mock, proxy and dynamic modes
Prism runs as a mock by default. It can instead run as a validation proxy that forwards requests to a real upstream and validates both the request and the response against the contract, or generate dynamic responses from the schema instead of static examples. Set the mode in the environment file.
# validation proxy: forward to a real backend and validate against the contract
# in /etc/prism/prism.env set:
# PRISM_MODE=proxy
# PRISM_UPSTREAM=<upstream-url>
# dynamic responses generated from the schema instead of static examples:
# PRISM_FLAGS=--dynamic
sudo systemctl restart prism.service
Step 10: Use the mock from your clients and CI
On any workstation or CI agent, point your HTTP client at this instance. Replace <vm-ip> with this instance's address (or a DNS name you point at it) and make sure the Network Security Group allows TCP 4010 from that client.
curl http://<vm-ip>:4010/widgets
curl -X POST http://<vm-ip>:4010/widgets -H 'Content-Type: application/json' -d '{"name":"Sprocket"}'
In a test suite or CI pipeline, set the mock base URL as an environment variable and point your integration tests at the instance. Every request then exercises a predictable, controllable endpoint you own instead of a shared service or an unfinished backend.
Step 11: Put a real domain and TLS in front for production
Prism serves plain HTTP because a mock returns only synthetic data. For a shared or internet facing deployment, place Prism behind your own reverse proxy that terminates TLS and, if you wish, adds authentication. Bind Prism to loopback by setting PRISM_HOST=127.0.0.1 in /etc/prism/prism.env so only your proxy can reach it, then front it with nginx and a CA signed certificate for <your-domain>.
Step 12: Security recommendations
-
Restrict the NSG. Allow TCP 4010 only from the developers, test runners and CI agents that consume the mock, and TCP 22 only from your administration network.
-
Front it with your own TLS proxy for anything shared. Bind Prism to loopback and terminate TLS at nginx with a real certificate when the mock is reachable beyond a trusted subnet.
-
Remember the mock is unauthenticated by design. It serves only synthetic data from your specification, but treat the port as open to whoever can reach it and scope the NSG accordingly.
-
Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Step 13: Support and Licensing
Stoplight Prism is open source software distributed under the Apache License 2.0. This cloudimg image bundles the unmodified upstream @stoplight/prism-cli release from the public npm registry. cloudimg provides the packaging, the systemd hardening, the dedicated unprivileged service account, the starter OpenAPI specification, the per instance info automation, the paired deploy guide, and 24/7 support with a guaranteed 24 hour response SLA.
cloudimg is not affiliated with or endorsed by Stoplight or the Prism project. Stoplight and Prism are marks of their respective owner and are used here only to identify the software.
Deploy on Azure
Find Stoplight Prism on Ubuntu 24.04 LTS on the Azure Marketplace, published by cloudimg. Deploy from the Portal or the Azure CLI as shown above.
Need Help?
Email support@cloudimg.co.uk for deployment help, configuration questions, or licensing enquiries.