Deployment guide

grpcUI

Overview

grpcUI is an interactive web interface for gRPC servers, the graphical counterpart to command-line tools such as grpcurl. Point it at a running gRPC service and it discovers the service's methods through server reflection or from .proto/protoset files you supply, then renders an HTML form for each method. You fill in the request in the browser and invoke the method. grpcUI makes the real gRPC call server-side and shows the response message, status code and response metadata.

The SecureAnyCloud image runs the pinned grpcUI 1.5.2 Go binary under systemd and includes a small demo gRPC server (grpcbin) with server reflection enabled, so the console lists callable methods as soon as it boots. grpcUI is bound to loopback 127.0.0.1:8080 and the demo server to 127.0.0.1:9000. An nginx reverse proxy on port 80 adds a per-VM HTTP Basic Auth gate, because grpcUI has no authentication of its own. The user is admin, and the password is generated on first boot.

What you get:

  • grpcUI 1.5.2 installed as a single Go binary and running as the grpcui systemd service
  • A bundled demo gRPC server (grpcbin) with server reflection enabled, running as the grpc-demo-server systemd service, so grpcUI can list and call methods immediately
  • The grpcUI web console on :80, fronted by nginx with grpcUI bound to loopback only
  • Per-VM HTTP Basic Auth (user admin) protecting the console, with a unique password generated on first boot
  • grpcUI and the demo server bound to 127.0.0.1 only, so nothing is exposed to the network except nginx
  • grpcui.service, grpc-demo-server.service and nginx.service as systemd units, enabled and active
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a virtual network and subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size, because grpcUI is light on resources.

In your network security group, allow inbound 22/tcp from your management network, 80/tcp for the console, and 443/tcp if you add TLS. grpcUI serves plain HTTP on port 80. For production, terminate TLS in front of it with your own domain and restrict access to trusted IP ranges (see Maintenance).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, select Create a resource, search the Marketplace for grpcUI by SecureAnyCloud, and select Create.

On the Basics tab, choose your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80). Then select Review + create, followed by Create.

Step 2 - Deploy from the Azure CLI

Accept the Marketplace terms once per subscription, create the VM, and open port 80:

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:grpcui-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name grpcui \
  --image sac1647283583153:grpcui-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name grpcui --port 80 --priority 1010

Step 3 - Connect to your VM

Connect over SSH as the azureuser admin user:

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

Check the three systemd services:

systemctl is-active grpc-demo-server.service grpcui.service nginx.service

All three report active. grpc-demo-server is the bundled demo gRPC server (grpcbin, reflection on), bound to 127.0.0.1:9000. grpcui is the web console, bound to 127.0.0.1:8080. nginx fronts grpcUI on port 80 with the per-VM Basic Auth gate, and it is the only service that listens on a public interface.

To confirm the listeners, run:

sudo ss -tlnp | grep -E ':(9000|9001|8080|80) '

Step 5 - Review the binaries and how grpcUI is wired

The image includes two pinned static Go binaries. The grpcUI systemd unit connects it to the demo server over plaintext on the loopback address, and the demo server binds only to loopback. Run these commands to inspect the setup:

grpcui -version grep ExecStart /etc/systemd/system/grpcui.service grep -E 'insecure-addr|metrics-addr' /etc/systemd/system/grpc-demo-server.service

grpcUI reports grpcui v1.5.2. Its ExecStart shows -plaintext -bind 127.0.0.1 -port 8080 127.0.0.1:9000, and the demo server binds its plaintext listener to 127.0.0.1:9000. To point grpcUI at your own gRPC service instead of the demo server, see Step 10.

Step 6 - Retrieve your web console password

nginx protects the grpcUI console with HTTP Basic Auth. The username is admin. A unique password is generated on the first boot of your VM and written to a root-only file:

sudo cat /root/grpcui-credentials.txt

The file contains GRPCUI_USERNAME, GRPCUI_PASSWORD and the GRPCUI_URL to open in a browser. The password is stored on disk only as a bcrypt hash in /etc/nginx/.grpcui.htpasswd, so no plaintext password ships in the image. Store the password somewhere safe.

Step 7 - Confirm the health endpoint and the auth gate

nginx serves an unauthenticated health endpoint for load balancers and probes, and gates everything else behind the per-VM password. The following commands read the password from the credentials file and test four cases: the health endpoint is open, an unauthenticated request is rejected, a wrong password is rejected, and the correct password authenticates.

PW=$(sudo grep '^GRPCUI_PASSWORD=' /root/grpcui-credentials.txt | cut -d= -f2-)
echo "healthz : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/healthz)"
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/)"
echo "wrongpw : $(curl -s -o /dev/null -w '%{http_code}' -u admin:wrong-pw http://127.0.0.1/)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/)"

The output is healthz : 200, unauth : 401, wrongpw : 401 and authed : 200. The /healthz endpoint never requires authentication, so it is safe to use as an Azure Load Balancer health probe. The grpcUI console is reachable only with the per-VM password.

Step 8 - Invoke a gRPC method from the shell through grpcUI

grpcUI exposes an HTTP invoke endpoint that makes the real gRPC call server-side. The endpoint is CSRF-protected, so first fetch the page to obtain the _grpcui_csrf_token cookie, then POST the request to /invoke/<fully.qualified.Method>. The following commands invoke hello.HelloService/SayHello on the bundled demo server:

PW=$(sudo grep '^GRPCUI_PASSWORD=' /root/grpcui-credentials.txt | cut -d= -f2-)
CJ=$(mktemp)
curl -s -c "$CJ" -u admin:$PW http://127.0.0.1/ -o /dev/null
TK=$(awk '/_grpcui_csrf_token/{print $NF}' "$CJ")
curl -s -u admin:$PW -b "$CJ" \
  -H 'Content-Type: application/json' \
  -H "x-grpcui-csrf-token: $TK" \
  -d '{"data":[{"greeting":"sac"}]}' \
  http://127.0.0.1/invoke/hello.HelloService.SayHello \
  | jq -c '{status:.headers[0].value, reply:.responses[0].message.reply}'

grpcUI calls the demo server and returns the response, with a reply of hello SecureAnyCloud. A successful invoke proves the whole path, because grpcUI exposes only methods it discovered from the target through server reflection. The browser form makes exactly the same call.

Step 9 - Explore and call methods in the web console

Browse to http://<vm-public-ip>/. When your browser prompts for credentials, enter admin and the password from Step 6. grpcUI opens with the Service name and Method name selectors already populated from the demo server's reflection data: addsvc.Add, grpc.gateway.examples.examplepb.ABitOfEverythingService, grpcbin.GRPCBin and hello.HelloService.

Select hello.HelloService and the SayHello method. grpcUI renders a Request Form with a field for each message field, here an optional greeting string.

Select the checkbox next to greeting to include the field, and type SecureAnyCloud. The Raw Request tab shows the exact JSON grpcUI will send, and the Request Metadata section lets you add gRPC metadata (headers) to the call.

Select Invoke. grpcUI makes the gRPC call and switches to the Response tab, which shows the response headers, the response data ({ "reply": "hello SecureAnyCloud" }) and any trailers. This is the same result you saw from the shell in Step 8.

Step 10 - Repoint grpcUI at your own gRPC service

The demo server exists so the console works as soon as it boots. To explore your own gRPC service, override the grpcUI target with a systemd drop-in and restart the service. If your service supports server reflection, that is all you need.

Open the drop-in editor:

sudo systemctl edit grpcui

In the editor, add an override that replaces the ExecStart with your service's host:port. If your service uses TLS, drop -plaintext and use -cacert/-cert/-key.

[Service] ExecStart= ExecStart=/usr/local/bin/grpcui -plaintext -bind 127.0.0.1 -port 8080 your-service-host:50051

Apply the change by restarting the service:

sudo systemctl restart grpcui

If your service does not support reflection, supply its schema instead by adding -proto yourservice.proto (with -import-path) or -protoset yourservice.protoset to the ExecStart line. The demo server's other reflected services, such as grpcbin.GRPCBin, stay available for reference.

Maintenance

  • Password: The console password is set on first boot and stored as a bcrypt entry in /etc/nginx/.grpcui.htpasswd. To change it, run sudo htpasswd -B /etc/nginx/.grpcui.htpasswd admin, then sudo systemctl reload nginx.
  • Target service: The grpcUI target is set in /etc/systemd/system/grpcui.service or in your drop-in from Step 10. After changing it, run sudo systemctl daemon-reload && sudo systemctl restart grpcui. grpcUI reconnects and re-reads the schema on restart.
  • Demo server: The bundled demo server is grpc-demo-server.service. It listens on 127.0.0.1:9000 (plaintext) and 127.0.0.1:9001 (TLS, loopback only). It is a reference target only. Once grpcUI points at your own service, you can run sudo systemctl disable --now grpc-demo-server. Update the grpcUI target first, so that it still has something to connect to.
  • Restrict access: grpcUI serves plain HTTP on port 80. For production, restrict access to trusted IP ranges in your network security group, and front it with TLS (for example, certbot with your own domain) terminating on :443.
  • Loopback binding: grpcUI is bound to 127.0.0.1:8080 and the demo server to 127.0.0.1, so nginx is the only way in. Do not change the bind address to a public interface. Put access control in nginx or your network security group instead.
  • Security patches: unattended-upgrades stays enabled, so the OS keeps receiving security updates automatically.

Support

SecureAnyCloud provides 24/7 support for this image. Contact sales@secureanycloud.com.

Deploy on Azure

Launch grpcUI 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