Nhost
Overview
Nhost is an open source backend as a service. It is a self-hosted alternative to Firebase and Supabase that gives you a complete application backend out of the box.
You get a PostgreSQL database exposed over an instant GraphQL API, user authentication, S3-compatible file storage, serverless functions and a management dashboard. The SecureAnyCloud image installs Nhost as a pinned, single-node Docker Compose stack and runs it as a systemd service, so a complete backend is online within minutes of launch.
What you get:
- The Nhost self-host stack, with every image pinned at build time. The appliance ships the exact release and never silently upgrades.
- PostgreSQL 16, the database, internal to the stack only
- Hasura GraphQL Engine v2.46.0 Community Edition, the instant GraphQL API plus console, on port 8080
- Nhost auth service 0.40.2, on port 4000, with the API served under
/v1 - Nhost storage service 0.7.2, on port 4001, backed by MinIO, the S3 object store (internal only)
- Nhost serverless functions runtime on Node.js 22, on port 4002
- Nhost management dashboard 2.34.0, on port 80
- MailHog, an SMTP catcher for development email (internal only)
- Docker Engine (Docker CE) and the Docker Compose plugin, installed from the official Docker package repository
- All stateful data (the PostgreSQL database, the MinIO object store, and the Hasura, auth and storage state) on a dedicated 40 GiB data disk mounted at
/var/lib/nhost. Docker's data root is relocated there. The disk is independently resizable and re-provisioned on every VM. - Per-VM secrets minted on first boot, including the PostgreSQL password, the Hasura admin secret, the Hasura JWT signing key and the MinIO access and secret keys
- Three systemd units:
docker.service,nhost.service(a oneshot wrapper around Docker Compose) andnhost-firstboot.service - 24/7 SecureAnyCloud support
Prerequisites
Before you launch the VM, make sure you have:
- An active Azure subscription
- An SSH key
- A VNet and subnet
- A Standard_B4ms VM size (4 vCPU / 16 GB RAM), which is the recommended size and is comfortable for the eight-container Nhost stack
- NSG inbound rules that allow
22/tcpfrom your management CIDR for SSH - NSG inbound rules that allow the following from the CIDR that needs the backend:
80/tcp(dashboard),8080/tcp(Hasura GraphQL and console),4000/tcp(auth),4001/tcp(storage) and4002/tcp(functions)
PostgreSQL, MinIO and MailHog are never published to the network and need no rules.
Connect over SSH
Replace <vm-ip> with the public IP of your VM. The default login user is azureuser.
Connect to the VM.
ssh azureuser@<vm-ip>Confirm the services are active
Check that Docker and the Nhost service are running.
sudo systemctl is-active docker.service nhost.service docker --version && docker compose versionYou should see active printed twice, the Docker Engine version, and the Docker Compose v2 plugin version.
Confirm the Nhost containers are running
List the containers in the Compose stack.
cd /opt/nhost && sudo docker compose psThe core containers, nhost-postgres-1, nhost-graphql-1, nhost-auth-1, nhost-storage-1, nhost-minio-1, nhost-dashboard-1 and nhost-mailhog-1, run in the Up state. Where a health check is defined, they also show healthy.
The nhost-functions-1 container restarts until you deploy a functions project. This is expected on a fresh appliance (see Step 10).
Confirm the data disk is mounted
All stateful Nhost data lives on a dedicated data disk mounted at /var/lib/nhost. Docker's data root is relocated there. Check the mount.
findmnt /var/lib/nhost df -h /var/lib/nhost docker info --format '{{.DockerRootDir}}'findmnt shows the device backing /var/lib/nhost, df confirms the 40 GiB volume, and Docker's data root reports as /var/lib/nhost/docker.
Check the endpoints and read the per-VM credentials
The Hasura GraphQL Engine, the auth service and the storage service each expose a health or version endpoint.
A unique set of secrets is created for your instance on its first boot and written to a root-only file. Check the endpoints, then read the file.
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/healthz
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:4000/healthz
curl -s http://localhost:4001/v1/version; echo
sudo cat /root/nhost-credentials.txtThe three checks return 200, and the credentials file lists the dashboard URL, the Hasura console URL, the Hasura admin secret and the backend endpoint URLs for the GraphQL, auth, storage and functions services. Store the admin secret somewhere safe.
Open the Nhost dashboard
Browse to http://<vm-ip>/ to open the Nhost management dashboard. It shows the local project, with sections for the database, the GraphQL API, Hasura, auth, storage, serverless functions and settings.
Manage your data in the database
Open the Database section of the dashboard to create tables, add columns and browse rows in the managed PostgreSQL database.
Every table you create is instantly exposed over the GraphQL API.
Query your data over the GraphQL API
Open the GraphQL section of the dashboard to explore the schema and run queries and mutations against your data. The built-in API explorer is already authenticated with your project's admin secret.
You can also query the API directly. The admin secret from Step 5 authorises full access.
curl -s -X POST http://localhost:8080/v1/graphql \
-H "x-hasura-admin-secret: <HASURA_ADMIN_SECRET>" \
-H "Content-Type: application/json" \
-d '{"query":"query { __typename }"}'; echoA {"data":{"__typename":"query_root"}} response confirms that the GraphQL API is up and the admin secret authenticates.
Administer the engine in the Hasura console
The Hasura GraphQL Engine ships its own console on port 8080. Browse to http://<vm-ip>:8080/console, and enter the Hasura admin secret from Step 5. You can then manage the data model, permissions, relationships, event triggers and remote schemas.
Authentication, storage and serverless functions
The auth service signs users up and issues JWTs. This command creates a user and returns an access token.
curl -s -X POST http://localhost:4000/v1/signup/email-password \
-H "Content-Type: application/json" \
-d '{"email":"demo@example.com","password":"Sup3r-Secret-123"}'; echoThe storage service serves files over an S3-compatible API on port 4001. Check that it is serving.
curl -s http://localhost:4001/v1/version; echoThe serverless functions runtime is published on port 4002 and runs the JavaScript and TypeScript functions you deploy.
On a fresh appliance, the functions container has no project to serve and restarts until you deploy one. To activate it, add a functions/ directory with your handlers (and a lock file for npm, yarn or pnpm) under /opt/nhost, then recreate the stack.
Manage the stack
The nhost.service systemd unit manages the whole stack. It wraps Docker Compose under /opt/nhost.
sudo systemctl status nhost.service --no-pager | head -n 6To inspect the logs for a specific service, run this command.
cd /opt/nhost && sudo docker compose logs --tail 20 graphqlEnabling HTTPS on your own domain
The image serves plain HTTP out of the box. To serve the dashboard and the backend over HTTPS on your own domain:
- Point a DNS A record at the VM public IP.
- Place a reverse proxy such as Caddy or Nginx, with a certbot certificate for your domain, in front of the published ports.
- Update the
NEXT_PUBLIC_NHOST_*_URLvalues and the CORS settings in/opt/nhost/.envto your HTTPS URLs. - Restart the service.
- Add
443/tcpto your NSG inbound rules.
First-boot security model
On the first boot of each VM, nhost-firstboot.service runs once and:
- Mints every per-VM secret in the stack: the PostgreSQL password, the Hasura admin secret, the Hasura JWT signing key and the MinIO storage access and secret keys. The JWT key is an HS256 key, regenerated per VM so tokens cannot be forged across deployments.
- Resolves the VM IP through Azure IMDS, falling back to the first non-loopback address, and points the browser-facing URLs and CORS at it
- Recreates the Compose stack on a fresh, empty database with the rotated secrets
- Refuses to start the stack if any secret still equals a published example literal (a fail-closed guard), and writes the credentials to
/root/nhost-credentials.txt(root only, mode 0600)
No shared or default secret and no preexisting data ship in the image.
Support
24/7 technical support is included. Contact SecureAnyCloud at sales@secureanycloud.com for help with deployment, the database and GraphQL API, authentication, storage, serverless functions, the dashboard, TLS and backups.
Nhost is a trademark of Nhost. Hasura is a trademark of Hasura Inc. PostgreSQL is a trademark of the PostgreSQL Community Association. MinIO is a trademark of MinIO, Inc. All other product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch Nhost 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