Deployment guide

Hasura CE

Overview

Hasura GraphQL Engine gives you an instant, realtime GraphQL API over a relational database. It also provides a web console for exploring your schema, composing queries and managing row and column permissions.

The SecureAnyCloud image ships the free and open source Community Edition (the Apache-2.0 v2 engine, hasura/graphql-engine). It runs the officially supported way, as the upstream container alongside a bundled PostgreSQL, orchestrated by Docker Compose under systemd and fronted by nginx. Both images are pinned by digest and captured into the VM, so your instance starts in seconds.

What you get:

  • Hasura GraphQL Engine Community Edition v2.49.4 (the Apache-2.0 v2 engine), pinned by image digest
  • A bundled PostgreSQL 16 database, pinned by image digest and reachable only inside a private Docker network. It is never published to a host port
  • Docker Engine (Docker CE) with the engine published to the loopback interface only, fronted by nginx on port 80
  • hasura.service, hasura-firstboot.service and nginx.service as systemd units, enabled and active on boot
  • A unique HASURA_GRAPHQL_ADMIN_SECRET and a unique PostgreSQL password generated per VM on first boot, before the port is reachable and never baked into the image. The console and the GraphQL endpoint are locked down from the first request
  • A clean, empty database on first boot, with no default account, no shipped secret and no prior data
  • 24/7 SecureAnyCloud support

Hasura is a trademark of its respective owner. SecureAnyCloud produces this image and is not affiliated with, endorsed by, or sponsored by Hasura. The image ships only the free and open source Apache-2.0 v2 Community Edition engine. It does not ship Hasura v3 / DDN.

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting size. Choose a larger size for heavier workloads.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the console and the GraphQL API. Add 443/tcp once you add TLS.

The engine serves plain HTTP on port 80. For production, put it behind TLS with your own domain (see Step 9).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Hasura GraphQL Engine by SecureAnyCloud, and select Create.

On the Basics tab, pick 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).

Select Review + create, then Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:hasura-ce:default:latest
az vm create \
  --resource-group <your-rg> \
  --name hasura \
  --image sac1647283583153:hasura-ce: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 hasura --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

On first boot, the image generates a unique admin secret and database password, initialises a clean PostgreSQL database and starts the engine. Confirm that the systemd services are active and that both containers, the engine and the bundled PostgreSQL, are healthy:

systemctl is-active docker hasura nginx
sudo docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'

All three services report active, and both hasura-graphql-engine-1 and hasura-postgres-1 report healthy.

The engine is published to the loopback interface only and fronted by nginx. The bundled PostgreSQL is never exposed on a host port. The public liveness endpoint returns 200 with no credentials:

curl -s -o /dev/null -w 'health: HTTP %{http_code}\n' http://127.0.0.1/healthz

Step 5 - Confirm the admin secret gates everything

The engine ships locked down. Any request to an admin endpoint (metadata, run SQL, the console) without the exact per-VM admin secret is rejected with 401. Confirm it yourself. This request sends no secret:

curl -s -o /dev/null -w 'no secret: HTTP %{http_code}\n' \
  -X POST http://127.0.0.1/v1/metadata \
  -H 'Content-Type: application/json' \
  -d '{"type":"export_metadata","args":{}}'

The request returns HTTP 401. The same is true for the GraphQL endpoint and the console: nothing is readable or writable without your admin secret.

Your unique admin secret is written to /root/hasura-notes.txt, which only root can read. Check the file permissions:

sudo stat -c '%a %U:%G' /root/hasura-notes.txt

The command reports 600 root:root. The notes include your admin secret, the console URL and the GraphQL endpoint. View them with:

sudo cat /root/hasura-notes.txt

Step 6 - Open the console

Browse to http://<vm-public-ip>/console. The console prompts for your admin secret before it loads anything. This prompt is the gate that protects your database.

Paste the admin secret from /root/hasura-notes.txt and select Enter. The console opens on the API tab with GraphiQL. There you can compose and run GraphQL queries, mutations and subscriptions against your data, and browse the auto-generated schema in the Explorer panel.

Use the Data tab to manage your database: connect schemas, create and track tables, define relationships and set permissions. The bundled database is reported here as PostgreSQL 16.

Step 7 - Call the GraphQL API from the command line

Every request to the GraphQL endpoint must carry your admin secret in the x-hasura-admin-secret header. The block below reads the secret from your notes file, so it never appears on screen. It then runs a GraphQL query that confirms the endpoint is authenticated and serving:

S=$(sudo grep '^HASURA_ADMIN_SECRET=' /root/hasura-notes.txt | cut -d= -f2-)
curl -s -X POST http://127.0.0.1/v1/graphql \
  -H "x-hasura-admin-secret: $S" \
  -H 'Content-Type: application/json' \
  -d '{"query":"query { __typename }"}'

It returns {"data":{"__typename":"query_root"}}. This proves an authenticated GraphQL round trip against the bundled PostgreSQL.

When you create and track a table in the Data tab, for example a products table, Hasura exposes it as GraphQL immediately. From your own machine, substitute your VM public IP and your admin secret:

curl -X POST http://<vm-public-ip>/v1/graphql \
  -H 'x-hasura-admin-secret: <HASURA_ADMIN_SECRET>' \
  -H 'Content-Type: application/json' \
  -d '{"query":"query { products { id name category price in_stock } }"}'

Step 8 - Rotate the admin secret

The admin secret is your master key. To set your own, edit the environment file, then restart the engine:

sudo sed -i 's/^HASURA_GRAPHQL_ADMIN_SECRET=.*/HASURA_GRAPHQL_ADMIN_SECRET=<your-new-secret>/' /etc/hasura/hasura.env
sudo systemctl restart hasura

Step 9 - Use your own domain with TLS

For production, front the engine with your own domain and TLS. Point a DNS record at the VM public IP. Then install a certificate with your preferred tool, for example Certbot with the nginx plugin, and reload nginx.

Once TLS is in place, restrict inbound access in your NSG to 443/tcp, plus 22/tcp from your management network. Keep the admin secret confidential. It grants full read and write access to your database.

Support

SecureAnyCloud supports this image 24/7. For help with deployment or configuration, contact support through secureanycloud.com.

Deploy on Azure

Launch Hasura GraphQL Engine (CE v2) 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