Developer Tools Azure

Swagger UI on Ubuntu 24.04 LTS on Azure User Guide

| Product: Swagger UI on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of Swagger UI on Ubuntu 24.04 LTS on Azure using cloudimg Azure Marketplace images. Swagger UI is the open source, interactive renderer that turns an OpenAPI or Swagger definition into a clean, browsable API reference where every endpoint, parameter, request body and response model is laid out and can be tried directly from the page.

The image serves the official swagger-ui-dist v5.32.11 distribution, which is the prebuilt, ready to serve build of Swagger UI and the exact content the official swaggerapi/swagger-ui container serves. cloudimg mirrors it natively behind nginx, which terminates HTTPS. A self contained Swagger Petstore demo definition ships in the image so the documentation renders out of the box; you replace it with your own definition to document your service. The distribution is pinned by exact version and verified against a checksum at build time.

Secure by default. Unlike a plain static bundle, this appliance never exposes the API docs unauthenticated. nginx fronts the interface with HTTP Basic Auth, and the password is generated uniquely per virtual machine on first boot and written to a root only file. Before that password exists the interface is fail closed (every request is answered 401), so the docs are never open to the world.

What is included:

  • Swagger UI v5.32.11 (official swagger-ui-dist distribution), sha256 pinned

  • nginx 1.24 serving the static bundle over TLS behind HTTP Basic Auth

  • A per VM HTTP Basic Auth credential (user admin) generated on first boot, apr1 hashed, stored in a root only credentials file

  • A self contained Swagger Petstore demo definition, with the external validator disabled so the browser makes no third party calls (offline and air gapped ready)

  • The upstream Apache 2.0 LICENSE and NOTICE vendored into the served root

  • swagger-ui-firstboot.service systemd oneshot that generates a per VM TLS certificate, mints the per VM Basic Auth password, starts nginx, then proves the 401 without credentials and 200 with credentials round trip

  • :80 redirects to HTTPS, plus an unauthenticated /healthz endpoint (nginx native, HTTP 200) for load balancer and probe checks

  • Ubuntu 24.04 LTS base with the latest security patches applied at build time

  • Azure Linux Agent for seamless cloud integration and SSH key injection

  • 24/7 cloudimg support with a guaranteed 24 hour response SLA

Prerequisites

  • Active Azure subscription, an SSH public key, and a VNet plus subnet in the target region

  • A network security group that allows inbound TCP 22 (SSH), 80 (HTTP redirect) and 443 (HTTPS)

  • Security note: the Basic Auth credential protects the interface, but you should still restrict the inbound rule for ports 80 and 443 to trusted source ranges in your network security group, or place the VM behind a reverse proxy or VPN, as defence in depth.

Deploy from the Azure Marketplace

  1. In the Azure portal, choose Create a resource and search for Swagger UI on Ubuntu 24.04 LTS by cloudimg.

  2. Select the plan and click Create.

  3. On the Basics tab pick your subscription, resource group and region, give the VM a name, and choose a size. Standard_B2s is a good starting point for evaluation and light use; scale up for heavier concurrent use.

  4. Set the authentication type to SSH public key, provide your key, then set the inbound ports to allow SSH (22), HTTP (80) and HTTPS (443).

  5. Review and create. When the deployment finishes, note the VM's public IP address.

On first boot, swagger-ui-firstboot.service generates a per VM self signed TLS certificate, mints a per VM Basic Auth password, starts nginx, then confirms the docs answer 401 without credentials and 200 with them, and writes the credential to a root only file. This usually completes within a minute of the VM reaching the running state.

Retrieve the per VM credential

SSH into the VM as azureuser and read the access note. It contains the URL, the admin username and the password that was generated uniquely for this VM on first boot.

sudo cat /root/swagger-ui-credentials.txt

The note records the URL, the credential and how to change it. The password is unique to your instance and never leaves the VM.

Terminal showing the per VM Swagger UI access note with the URL, the admin username, the Basic Auth password field, and instructions to change the password and drop in your own OpenAPI spec

Open the API documentation

Point a browser at https://<VM-public-IP>/. Because the image ships a self signed certificate, your browser will warn on first visit; accept the exception (or install your own certificate, see below). The browser then prompts for the Basic Auth credential: enter admin and the password from the access note. Swagger UI loads and renders the shipped Swagger Petstore definition.

Swagger UI rendering the shipped Swagger Petstore OpenAPI 3.0 definition, showing the GET and POST pets operations grouped under the pet tag and the Schemas section, served from the cloudimg appliance

Click any operation to expand it and see its parameters, request body and responses, including an example value generated from the schema:

The GET /pets operation expanded in Swagger UI, showing the limit query parameter, the Try it out button, and the 200 response with an example JSON array of pets

Use Try it out to turn the documentation into an interactive request form, with editable parameters and an Execute button:

The GET /pets operation in Try it out mode, showing the editable limit parameter, the Execute button, and the 200 response media type and example value

Reusable schemas defined under components render in the Schemas section, with each property, type and constraint shown:

The Swagger UI Schemas section with the Pet model expanded, showing its id, name, tag and status properties

Verify the deployment

SSH into the VM as azureuser and confirm nginx is active. nginx is the only network facing process; it serves the static bundle over TLS on :443 behind Basic Auth and redirects :80 to HTTPS.

sudo systemctl start nginx.service
systemctl is-active nginx.service swagger-ui-firstboot.service | paste -sd' ' -
ss -tln | grep -E ':443 |:80 ' | awk '{print $1, $4}'
test -f /var/lib/cloudimg/swagger-ui-firstboot.done && echo 'firstboot sentinel present'

nginx reports active and listens on public ports 80 and 443 once first boot has completed:

active active
LISTEN 0.0.0.0:443
LISTEN 0.0.0.0:80
LISTEN [::]:443
LISTEN [::]:80
firstboot sentinel present

Terminal showing the nginx and firstboot services active, nginx listening on public ports 80 and 443, and the firstboot sentinel present

Secure by default: HTTP Basic Auth

The whole point of this appliance is that the API docs are never open to the world. The health probe is unauthenticated so a load balancer can check it, but the documentation itself returns 401 without credentials and 200 only with the per VM admin password. You can prove the round trip directly on the VM, reading the password from the access note:

PW=$(sudo grep '^swagger.ui.password=' /root/swagger-ui-credentials.txt | cut -d= -f2-)
echo "GET / (no credentials)   -> HTTP $(curl -sk -o /dev/null -w '%{http_code}' -m5 https://127.0.0.1/)"
echo "GET /healthz             -> HTTP $(curl -sk -o /dev/null -w '%{http_code}' -m5 https://127.0.0.1/healthz)"
echo "GET / (with credentials) -> HTTP $(curl -sk -u "admin:$PW" -o /dev/null -w '%{http_code}' -m5 https://127.0.0.1/)"
echo "GET :80/                 -> HTTP $(curl -s -o /dev/null -w '%{http_code}' -m5 http://127.0.0.1/)"

The health check is 200 without credentials, the docs are 401 without them and 200 with them, and port 80 redirects with 301:

GET / (no credentials)   -> HTTP 401
GET /healthz             -> HTTP 200
GET / (with credentials) -> HTTP 200
GET :80/                 -> HTTP 301

Terminal showing the API docs returning HTTP 401 without credentials and HTTP 200 with credentials, the unauthenticated health probe returning 200, the served static files including the vendored openapi.json, and the Apache 2.0 licence

Runtime and versions

The runtime stack, the exact Swagger UI distribution version and checksum, and the unit enabled for the customer's first boot can all be inspected on the VM:

nginx -v
cat /var/www/swagger-ui/CLOUDIMG_VERSION
systemctl is-enabled nginx.service
curl -s -o /dev/null -w 'GET /healthz  ->  HTTP %{http_code}\n' -m 5 http://127.0.0.1/healthz

The pinned distribution version and its sha256 are recorded in the served root:

nginx version: nginx/1.24.0 (Ubuntu)
swagger_ui_dist_version=5.32.11
swagger_ui_dist_sha256=966b7c7ea3bc98af2f5f125dac3a971973df20ed1f9c40707d846200d8b462a6
upstream=https://github.com/swagger-api/swagger-ui
licence=Apache-2.0
enabled
GET /healthz  ->  HTTP 200

Terminal showing the nginx version, the pinned swagger-ui-dist v5.32.11 version and sha256, the enabled nginx unit, and a successful unauthenticated health check

Bring your own API definition

The image ships a self contained Swagger Petstore demo definition at /var/www/swagger-ui/openapi.json so the docs render out of the box. To document your own service, replace that file with your own OpenAPI or Swagger definition. Swagger UI is configured to load openapi.json from the served root, so no other change is needed:

# The shipped demo definition lives here:
sudo ls -l /var/www/swagger-ui/openapi.json
# To document your own service, copy your definition over it, keeping the same path:
#   sudo cp my-api.json /var/www/swagger-ui/openapi.json
# (optionally back up the demo first: sudo cp /var/www/swagger-ui/openapi.json ~/openapi.json.demo)

If you prefer to keep multiple definitions, drop them into the served root and change the url value in /var/www/swagger-ui/swagger-initializer.js to point at the one you want, or add a urls array for a definition picker. No service restart is needed; nginx serves the files directly.

Change the Basic Auth password

The per VM password is stored, apr1 hashed, in /etc/nginx/auth/swagger-ui.htpasswd (user admin). To set your own password, generate a new hash and reload nginx:

sudo sh -c 'openssl passwd -apr1 "your-new-password" | sed "s#^#admin:#" > /etc/nginx/auth/swagger-ui.htpasswd'
sudo nginx -t
sudo systemctl reload nginx

To add more users, append additional user:hash lines to the same file.

Offline and air-gapped use

The documentation runs entirely offline: the bundle, styles, scripts and the demo definition are all served from the VM, so it works with no internet access. The external spec validator badge, which some Swagger UI deployments call out to validator.swagger.io from the browser, is disabled in this image (validatorUrl is set to null), so the browser makes no third party calls. The appliance is ready for fully offline or air gapped networks as shipped.

Bring your own TLS certificate

The image serves HTTPS with a self signed certificate that is regenerated per VM at first boot, so it is unique to your instance but not trusted by browsers. For production, replace it with a certificate for your own domain. Put your certificate and key in place and reload nginx:

  • Point a DNS record at the VM's public IP.

  • Copy your certificate chain to /etc/nginx/tls/swagger-ui.crt and your private key to /etc/nginx/tls/swagger-ui.key (keep the key mode 0600).

  • Alternatively, place the VM behind an Azure Application Gateway or another reverse proxy that terminates TLS with a managed certificate.

After replacing the files, validate the configuration before you reload the web server:

sudo nginx -t

A successful nginx -t confirms the configuration is valid before you reload.

Support

This image is maintained by cloudimg with 24/7 support and a guaranteed 24 hour response SLA. Swagger UI is free and open source software licensed under the Apache License 2.0; the cloudimg charge covers packaging, security patching, image maintenance and support. For help, contact support@cloudimg.co.uk.