Nhost on AlmaLinux 9 (Docker Compose + PostgreSQL + Hasura + GraphQL + SSL)
Nhost is an open-source backend-as-a-service (BaaS) platform that provides a full suite of backend tools — including PostgreSQL, Hasura GraphQL APIs, authentication, file storage, and serverless functions — in one integrated stack. It’s designed as an open-source alternative to Firebase, giving developers instant access to scalable backend features while maintaining full control over their infrastructure.
Running Nhost on AlmaLinux 9, a RHEL-compatible enterprise distribution, ensures a secure, stable, and long-term supported base for production deployments. AlmaLinux 9 offers SELinux enforcement, systemd 252, and OpenSSL 3, combined with modern Docker and Compose packages — making it an excellent choice for hosting a self-contained Nhost environment with SSL and reverse proxy integration.
Architecture Overview
| Layer | Component | Role |
|---|---|---|
| OS | AlmaLinux 9 | Enterprise-grade, RHEL-compatible base system with SELinux |
| Container Runtime | Docker Engine + Compose | Orchestrates Nhost and dependent services |
| Database | PostgreSQL 15 | Stores app schemas, user data, and authentication records |
| GraphQL Engine | Hasura | Auto-generates real-time GraphQL APIs from PostgreSQL schemas |
| Auth Service | Nhost Auth (GoTrue) | Manages user authentication, sessions, and JWT tokens |
| Storage | Nhost Storage | Handles file uploads and secure access (S3-compatible) |
| Functions | Nhost Functions (Node.js) | Executes serverless backend logic |
| Reverse Proxy | Nginx / Traefik (optional) | TLS termination, caching, and routing |
| TLS | Let’s Encrypt / PKI | Enables secure HTTPS for APIs and dashboard access |
Why Use Nhost?
- Open-source Firebase alternative – full control, no vendor lock-in.
- GraphQL-first backend powered by Hasura for instant API generation.
- Built-in authentication – supports JWT, OAuth, and magic links.
- File storage and access control – integrated S3-compatible system.
- Serverless functions – run custom backend logic seamlessly.
- Self-hosted and scalable – ideal for startups, SaaS, or enterprise use.
Nhost vs Other Backend Platforms
| Feature/Capability | Nhost (Self-hosted) | Supabase (Self-hosted) | Firebase (Google) | Appwrite (Self-hosted) |
|---|---|---|---|---|
| Database | PostgreSQL | PostgreSQL | Firestore (NoSQL) | MariaDB / PostgreSQL |
| API Type | GraphQL (Hasura) | REST + GraphQL | Proprietary SDK | REST + GraphQL |
| Authentication | GoTrue (JWT) | GoTrue (JWT) | Firebase Auth | Custom JWT |
| File Storage | S3-compatible | S3-compatible | Cloud Storage | Local/S3 drivers |
| Serverless Logic | Node.js Functions | Limited (Edge) | Cloud Functions | Node.js Functions |
| Open-source | Yes | Yes | No | Yes |
Nhost stands out for teams who need a powerful, self-hosted GraphQL backend with modern authentication and real-time APIs — without depending on proprietary cloud services.
Security & Best Practices
- Run Nhost behind Nginx or Traefik with HTTPS enabled.
- Use Docker secrets or environment variables for all keys and credentials.
- Restrict PostgreSQL and internal services to the Docker network.
- Enable SELinux enforcing mode and configure ports via
semanage. - Rotate JWT secrets and OAuth keys periodically.
- Schedule PostgreSQL backups with
pg_dumpor Docker jobs. - Keep Docker images and AlmaLinux packages regularly updated.
- Automate SSL renewals using Certbot or Traefik’s ACME integration.
Typical Use Cases
- Web and mobile app backends with real-time GraphQL APIs.
- SaaS platforms requiring authentication, storage, and functions.
- Internal dashboards powered by PostgreSQL and Hasura.
- Prototypes and MVPs needing rapid backend setup.
- Enterprise environments requiring data sovereignty and compliance.
Deploying Nhost on AlmaLinux 9 with Docker Compose gives you a secure, scalable, and enterprise-ready backend platform that merges PostgreSQL, Hasura, and authentication into a single stack — offering all the power of Firebase with full self-hosted freedom.
Step 1: Create a Server Instance on Shape.Host
Log in to your Shape.Host account.
Click Create → Instance.

Choose your desired server location.

Select a plan with at least 4 CPUs, 8 GB RAM, and 40 GB SSD (recommended).
Choose AlmaLinux 9 (64-bit) as your operating system.

Click Create Instance.

Once the instance is ready, copy its public IP address from the Resources section.

Step 2: Connect to Your Server
Use SSH to connect:
- Linux / macOS:
ssh root@your_server_ip - Windows (PuTTY):
- Open PuTTY.
- Enter your server’s IP.
- Click Open → log in as root.
Step 3: Install Docker and Docker Compose
Install the DNF plugin that allows managing external repositories:
dnf install dnf-plugins-core

This enables the config-manager command for adding repositories.
Add Docker’s official repository for CentOS/AlmaLinux:
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
This adds the Docker CE repository to your system.
Install Docker Engine, CLI tools, and the Compose plugin:
dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
This command installs all required Docker components.

Enable Docker to start automatically on boot:
systemctl enable docker
Start the Docker service:
systemctl start docker

Verify Docker installation:
docker --version
Check Docker Compose version:
docker compose version

Step 4: Set Up Nhost Directory
Create the Nhost working directory:
mkdir -p /opt/nhost
cd /opt/nhost
This will store your docker-compose.yml and function files.
Step 5: Create the Docker Compose Configuration
Open the configuration file:
nano /opt/nhost/docker-compose.yml
Paste the following content:
services:
postgres:
container_name: nhost-postgres-1
image: postgres:15
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: "W9b2U8vTKp"
POSTGRES_DB: nhost
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
hasura:
container_name: hasura
image: hasura/graphql-engine:v2.41.0
restart: always
depends_on:
- postgres
ports:
- "8080:8080"
environment:
HASURA_GRAPHQL_DATABASE_URL: "postgres://postgres:W9b2U8vTKp@postgres:5432/nhost"
HASURA_GRAPHQL_ADMIN_SECRET: "0f8c85264d9d04998fe00881c3c61d9147b51004f5cd1cb7c17d5740d7ab30ef"
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS256","key":"0f8c85264d9d04998fe00881c3c61d9147b51004f5cd1cb7c17d5740d7ab30ef"}'
HASURA_GRAPHQL_UNAUTHORIZED_ROLE: anonymous
HASURA_GRAPHQL_CORS_DOMAIN: "*"
auth:
container_name: auth
image: nhost/hasura-auth:latest
restart: always
depends_on:
- postgres
- hasura
ports:
- "4000:4000"
environment:
HASURA_GRAPHQL_DATABASE_URL: "postgres://postgres:W9b2U8vTKp@postgres:5432/nhost"
HASURA_GRAPHQL_ADMIN_SECRET: "0f8c85264d9d04998fe00881c3c61d9147b51004f5cd1cb7c17d5740d7ab30ef"
HASURA_GRAPHQL_ENDPOINT: "http://hasura:8080/v1/graphql"
HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS256","key":"0f8c85264d9d04998fe00881c3c61d9147b51004f5cd1cb7c17d5740d7ab30ef"}'
AUTH_CLIENT_URL: "http://YOUR_SERVER_IP"
AUTH_JWT_SECRET: '{"type":"HS256","key":"0f8c85264d9d04998fe00881c3c61d9147b51004f5cd1cb7c17d5740d7ab30ef"}'
AUTH_ADMIN_PASSWORD: "StrongAdminPass123!"
AUTH_ADMIN_EMAIL: "contact@shape.host"
minio:
container_name: nhost-minio-1
image: minio/minio
restart: always
command: server /data --console-address ":9001"
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: "minioadmin"
MINIO_ROOT_PASSWORD: "minioadminpass"
volumes:
- minio_data:/data
functions:
container_name: nhost-functions-1
image: nhost/functions:latest
restart: always
depends_on:
- hasura
ports:
- "1337:1337"
volumes:
- ./functions:/opt/nhost/functions
volumes:
postgres_data:
minio_data:
Explanation of services:
| Service | Description |
|---|---|
| Postgres | Stores application and user data. |
| Hasura | Provides a powerful GraphQL API layer. |
| Auth | Handles user authentication and JWT sessions. |
| MinIO | Acts as an S3-compatible storage system. |
| Functions | Enables custom backend logic with serverless functions. |
Save and exit using CTRL + O, then CTRL + X.

Step 6: Create a Directory for Functions
mkdir -p /opt/nhost/functions
This folder will later store your custom JavaScript or TypeScript serverless functions.
Step 7: Deploy Nhost
Start all containers using Docker Compose:
docker compose up -d

Check if all services are running:
docker compose ps
You should see each service (postgres, hasura, auth, minio, functions) marked as Up.

Step 8: Access Nhost Services
- Hasura GraphQL Console:
http://YOUR_SERVER_IP:8080 - Authentication API:
http://YOUR_SERVER_IP:4000 - MinIO Dashboard:
http://YOUR_SERVER_IP:9001
To verify the Auth service health:
http://YOUR_SERVER_IP:8080
If it returns OK, your Nhost stack is working properly.


Step 9 (Optional): Secure with HTTPS
If you have a domain name, install Certbot for Nginx or Apache:
dnf install certbot python3-certbot-nginx
certbot --nginx -d yourdomain.com
This will automatically install and configure free SSL certificates from Let’s Encrypt.
You installed Nhost on AlmaLinux 9 using Docker Compose.
You now have a complete, self-hosted backend system with:
- GraphQL APIs (via Hasura)
- Authentication and authorization (via Nhost Auth)
- File storage (via MinIO)
- PostgreSQL database
- Serverless functions
For best results, deploy Nhost on a Shape.Host Cloud VPS, optimized for Docker environments and high-performance backend workloads.