Nginx UI on Ubuntu 24.04 on Azure User Guide
Overview
This image runs Nginx UI, a web management interface for nginx. Nginx UI reads and writes the nginx configuration directly, so you can create and edit sites, streams and upstreams from a browser, issue and renew Let's Encrypt certificates, browse and analyse access and error logs, and test and reload the configuration without hand editing files over SSH. Every change is validated with nginx -t before it is applied, so a bad edit is caught before it reaches a running server.
The image ships nginx and Nginx UI together and the two are deliberately independent. nginx serves your sites on port 80 and 443 and is the thing under management. Nginx UI runs as its own service on port 9000 and manages it. Nginx UI is not itself served through nginx, so a configuration mistake that takes a site down never locks you out of the tool you need to fix it.
The image contains no account and no password. Nginx UI's normal first run opens a setup wizard where the first visitor creates the administrator, which is not safe on a public cloud image. Instead, on the first boot of every deployed VM a one shot service generates a password unique to that server, brings Nginx UI up bound to the loopback interface only, completes the setup locally, proves the new credential works and that guessable passwords are rejected, and only then exposes the service on port 9000. There is no window in which the setup wizard is reachable from the network, and no two cloudimg deployments share a password.
What is included:
- Nginx UI 2.4.2 running as the
nginx-uiservice on port 9000 - nginx 1.24.0 (Ubuntu 24.04 archive) running as the
nginxservice on port 80, under Nginx UI's management - Per VM first boot bootstrap: a unique administrator password generated on the server, written to a root only file
- Setup completed over the loopback interface, so the first run wizard is never exposed to the network
- Full nginx management: sites, streams, upstreams, configuration editor, Let's Encrypt certificates, log analysis
- Configuration validated with
nginx -tbefore every apply and reload - All packages from the Ubuntu archive plus the official upstream Nginx UI release, verified against its published SHA-512 digest
- 24/7 cloudimg support
Nginx UI is published under the GNU Affero General Public License v3.0 and is shipped unmodified. The full licence text is retained on the image at /opt/nginx-ui/LICENSE.
Prerequisites
Before you deploy this image you need:
- An active Microsoft Azure subscription where you can create virtual machines
- An SSH key pair for administrator access to the VM
- A virtual network and subnet in the target region
- A network security group (NSG) that allows inbound TCP 22 from your administrator network, TCP 9000 from your administrator network only, and TCP 80 and TCP 443 from wherever your sites need to be reachable
- The Azure CLI installed locally if you plan to deploy from the command line
Standard_B2s (2 vCPU / 4 GiB RAM) is a balanced default. Size the VM to the traffic your nginx sites will serve; Nginx UI itself is lightweight.
Step 1: Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, and search the Marketplace for Nginx UI by cloudimg. Select the listing and choose Create.
On the Basics tab pick your subscription and resource group, a region, and a VM size (Standard_B2s or larger). Under Administrator account select SSH public key, set the username, and paste your public key. Under Inbound port rules allow SSH (22) for administration. Add the management port (9000) and your site ports (80 and 443) afterwards, scoped to the right source ranges. Select Review + create, then Create.
First boot initialisation takes a few seconds after the VM reaches the Running state. Nginx UI is not reachable until it completes, which is by design.
Step 2: Deploy from the Azure CLI
The following block creates a VM from the cloudimg Nginx UI image into an existing VNet and subnet. Replace the placeholders with your own values.
az vm create \
--resource-group <your-rg> \
--name nginx-ui \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
# The management interface. Scope this to your administrator network, never the internet.
az network nsg rule create --resource-group <your-rg> --nsg-name <your-nsg> \
--name allow-nginx-ui --priority 1010 \
--source-address-prefixes <your-admin-cidr> --destination-port-ranges 9000 \
--access Allow --protocol Tcp
# The sites nginx serves.
az vm open-port --resource-group <your-rg> --name nginx-ui --port 80 --priority 1020
az vm open-port --resource-group <your-rg> --name nginx-ui --port 443 --priority 1030
Step 3: Connect as the Administrator over SSH
Connect to the VM with SSH as the administrator user you set at deploy time (azureuser by default on Ubuntu). The administrator account is SSH key only.
ssh azureuser@<vm-public-ip>
Step 4: Confirm Nginx UI and nginx are Running
Both services start automatically. Confirm they are active, check the listeners, and read the build provenance recorded on the image:
systemctl is-active nginx-ui.service nginx.service
sudo ss -tlnp | grep -E ':(9000|80|443) '
nginx-ui --version
nginx -v
cat /opt/nginx-ui/VERSION
Nginx UI listens on port 9000 and nginx listens on port 80. Nothing listens on 443 until you add a TLS site, which you can do from the interface in Step 8. The VERSION file records the exact upstream release and the SHA-512 digest the image was built from.

Step 5: Retrieve Your Sign In Credentials
First boot generated an administrator password unique to this server and wrote it to a root only file along with the URLs you need. Read it:
sudo stat -c '%a %U:%G %n' /root/nginx-ui-credentials.txt
sudo grep -E '^(NGINX_UI_ADMIN_USERNAME|NGINX_UI_URL|NGINX_SITE_URL)=' /root/nginx-ui-credentials.txt
The file is mode 600 and owned by root, so only an administrator who can already reach the server can read it. To display the password itself, read the whole file:
sudo cat /root/nginx-ui-credentials.txt
The first boot journal records exactly what happened: the setup was completed over the loopback interface, the credential was proven, and only then was the service exposed on port 9000.

Step 6: Sign In to Nginx UI
Browse to http://<vm-public-ip>:9000/ and sign in with the username and password from Step 5.

After signing in you land on the server dashboard, which reports the nginx process state alongside live CPU, memory, storage, network and disk metrics for the VM.

Change the password immediately. Open the user menu and set a password of your own. The generated password exists so the server is never unprotected on first boot; it is not intended to be your long term credential.
Step 7: Manage nginx Sites
Choose Manage Sites then Sites List. Nginx UI reads the site definitions straight from /etc/nginx/sites-available and shows their enabled state. A fresh image has one site, default, which serves the landing page you get on port 80.
From here you can Add a site, Edit one in the built in editor, Duplicate an existing site as a starting point, or enable and disable sites. Nginx UI runs nginx -t whenever you save and shows the result at the top of the page, so a syntax error is reported before the configuration is applied.

Step 8: Edit the nginx Configuration and Issue Certificates
Manage Configs exposes the whole of /etc/nginx as an editable tree: conf.d, modules-available, modules-enabled, sites-available and sites-enabled, plus nginx.conf itself. Edits are made in a syntax highlighted editor and validated before they are saved.

To serve a site over HTTPS, point a DNS name at the VM's public IP, make sure port 80 is reachable from the internet so the ACME HTTP challenge can complete, then use Certificates to request a Let's Encrypt certificate for that name. Nginx UI writes the certificate, wires it into the site, and renews it automatically. Add the port 443 NSG rule from Step 2 before you expose the site.
The Terminal entry in the sidebar opens an in browser root shell on the server. This is an upstream Nginx UI feature and is shipped unmodified. Treat access to port 9000 as equivalent to root SSH access, and restrict it accordingly in Step 10.
Step 9: Verify nginx Management from the Command Line
Everything the interface does is available through Nginx UI's API. This block signs in with your credentials, asks Nginx UI to report on the nginx it manages, lists the sites it can see, and runs nginx -t through the API:
. /usr/local/sbin/nginx-ui-api.sh
JWT=$(nui_login '<NGINX_UI_ADMIN_USERNAME>' '<NGINX_UI_ADMIN_PASSWORD>')
if [ -n "$JWT" ]; then
echo "signed in OK"
nui_get "$JWT" /api/nginx/status; echo
nui_get "$JWT" /api/sites | head -c 300; echo
curl -s -o /dev/null -w 'nginx -t via the API: HTTP %{http_code}\n' \
-X POST -H "Authorization: $JWT" http://127.0.0.1:9000/api/nginx/test
else
echo "sign in skipped: substitute the username and password from Step 5"
fi
sudo nginx -t
"running": true confirms Nginx UI is reading the live nginx process state, the site list confirms it is reading /etc/nginx, and the HTTP 200 confirms it can run a configuration test on demand.

Reload nginx after a change, from the interface or from the shell:
sudo nginx -t
sudo systemctl reload nginx
systemctl is-active nginx.service
Step 10: Security and Restricting the Management Port
The image ships no account, so there is no default credential to find. You can confirm the setup wizard is closed and that the generated password is the only one that works:
curl -s http://127.0.0.1:9000/api/install; echo
sudo /usr/local/sbin/nginx-ui-roundtrip.sh
{"lock":true,...} means the setup wizard is closed and cannot be used to claim the server. OK from the round trip means the per VM password authenticates, the resulting session can drive nginx, and every guessable password was rejected.

For production, apply all of the following:
- Restrict port 9000 to your administrator network in the NSG. Access to the management interface includes an in browser root terminal, so treat it as you would SSH. Never expose it to the internet.
- Change the generated password from the user menu, and consider enabling two factor authentication or a passkey under the user settings.
- Put the management interface behind your own TLS if you need to reach it across an untrusted network, or reach it over an SSH tunnel instead:
ssh -L 9000:127.0.0.1:9000 azureuser@<vm-public-ip>
Then browse to http://127.0.0.1:9000/ on your own machine, with port 9000 closed in the NSG entirely.
- Keep the VM patched. Unattended upgrades are enabled, and you can apply updates on demand at any time.
Troubleshooting
The interface is not reachable on port 9000. Confirm the service is up and that first boot finished. First boot must complete before the port is opened, which is deliberate.
systemctl is-active nginx-ui.service
test -f /var/lib/cloudimg/nginx-ui-firstboot.done && echo "first boot completed"
sudo journalctl -u nginx-ui-firstboot.service --no-pager | tail -20
If the service is active and the sentinel exists, the problem is the network path: check the NSG rule for TCP 9000.
You have lost the administrator password. Reset it from the server. The command prints a newly generated password for the initial user:
sudo nginx-ui --config /usr/local/etc/nginx-ui/app.ini reset-password
A site is down after a configuration change. Nginx UI validates before applying, but if nginx is refusing to start, test the configuration and read the error:
sudo nginx -t
sudo journalctl -u nginx.service --no-pager | tail -20
Because Nginx UI is not served through nginx, the interface stays reachable on port 9000 while nginx is down, so you can fix the site from the browser.
Where things live.
ls -1 /etc/nginx/
ls -1 /usr/local/etc/nginx-ui/
cat /opt/nginx-ui/VERSION
nginx configuration is in /etc/nginx, Nginx UI's own configuration and database are in /usr/local/etc/nginx-ui, and nginx logs are in /var/log/nginx.
Support
cloudimg provides 24/7 support for this image. Contact support@cloudimg.co.uk with your Azure subscription ID and the VM name.
Nginx UI is an open source project published under the GNU Affero General Public License v3.0. Upstream documentation is at nginxui.com and the source is at github.com/0xJacky/nginx-ui. cloudimg is not affiliated with, endorsed by, or sponsored by the Nginx UI project or by F5, Inc.