Skip to content

Deploying Hasura

Introduction

Hasura is an open-source GraphQL engine that provides instant, real-time GraphQL APIs over new or existing databases. It connects to your databases, REST servers, and GraphQL servers to provide a unified, real-time GraphQL API. Hasura is designed to be highly performant and scalable, making it ideal for modern application development.

Hasura is known for its:

  • Instant GraphQL APIs: Automatically generates GraphQL APIs from your database schema
  • Real-time Subscriptions: Built-in support for real-time data through GraphQL subscriptions
  • Role-based Access Control: Fine-grained authorization and access control
  • Remote Schemas: Combine multiple GraphQL APIs into a single unified endpoint
  • Event Triggers: Execute webhooks on database events (insert, update, delete)
  • Performance: Highly optimized query compilation and execution
  • Database Support: Works with PostgreSQL (and PostgreSQL-compatible databases), MySQL, SQL Server, and more

This comprehensive guide walks you through deploying Hasura GraphQL Engine on Klutch.sh using Docker, including detailed installation steps, database configuration, sample Dockerfiles, connection examples, and production-ready best practices.

Prerequisites

Before you begin, ensure you have the following:

  • A Klutch.sh account
  • A GitHub account with a repository for your Hasura project
  • Docker installed locally for testing (optional but recommended)
  • A PostgreSQL database (you can deploy one on Klutch.sh or use an external provider)
  • Basic understanding of Docker, GraphQL, and database concepts

Installation and Setup

Step 1: Create Your Project Directory

First, create a new directory for your Hasura deployment project:

Terminal window
mkdir hasura-klutch
cd hasura-klutch
git init

Step 2: Create the Dockerfile

Create a Dockerfile in your project root directory. This will define your Hasura container configuration:

FROM hasura/graphql-engine:v2.38.0
# Expose the default Hasura port
EXPOSE 8080
# The Hasura GraphQL Engine will automatically use environment variables
# for configuration. These should be set in the Klutch.sh dashboard.

Note: Pin to a specific Hasura version for production deployments. Check the Docker Hub tags for the latest version.

Step 3: (Optional) Create a Custom Dockerfile with Migrations

If you want to include database migrations and metadata in your container, create a more advanced Dockerfile:

FROM hasura/graphql-engine:v2.38.0
# Set working directory
WORKDIR /hasura
# Copy migrations and metadata
COPY migrations ./migrations
COPY metadata ./metadata
COPY config.yaml ./config.yaml
# Expose the default Hasura port
EXPOSE 8080

Create a config.yaml file for Hasura CLI configuration:

version: 3
endpoint: http://localhost:8080
admin_secret: your-admin-secret
metadata_directory: metadata
migrations_directory: migrations
actions:
kind: synchronous
handler_webhook_baseurl: http://localhost:3000

Important: Do not commit sensitive values like admin_secret in your config file. Use environment variables instead.

Step 4: Test Locally with Docker Compose

Before deploying to Klutch.sh, you can test your Hasura setup locally using Docker Compose. Create a docker-compose.yml file:

version: '3.8'
services:
postgres:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_DB: hasura
POSTGRES_USER: hasura
POSTGRES_PASSWORD: hasurapassword
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
hasura:
image: hasura/graphql-engine:v2.38.0
restart: unless-stopped
ports:
- "8080:8080"
depends_on:
- postgres
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://hasura:hasurapassword@postgres:5432/hasura
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
HASURA_GRAPHQL_DEV_MODE: "true"
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
HASURA_GRAPHQL_ADMIN_SECRET: myadminsecret
volumes:
postgres-data:

Run locally:

8080/console
docker-compose up -d
# Stop when done
docker-compose down

Note: This Docker Compose setup is for local development only. Klutch.sh does not support Docker Compose for deployments.

Step 5: Push to GitHub

Commit your Dockerfile to your GitHub repository:

Terminal window
git add Dockerfile
git commit -m "Add Hasura Dockerfile configuration"
git remote add origin https://github.com/yourusername/hasura-klutch.git
git push -u origin main

Setting Up PostgreSQL Database

Hasura requires a PostgreSQL database. You have two options:

Option 1: Deploy PostgreSQL on Klutch.sh

Follow the PostgreSQL deployment guide to set up a database on Klutch.sh.

Option 2: Use an External PostgreSQL Provider

You can use managed PostgreSQL services like:

Make sure to note your database connection details:

  • Host
  • Port
  • Database name
  • Username
  • Password

Deploying to Klutch.sh

Now that your Hasura project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh.

Deployment Steps

    1. Log in to Klutch.sh

      Navigate to klutch.sh/app and sign in to your account.

    2. Create a New Project

      Go to Create Project and give your project a meaningful name (e.g., “Hasura GraphQL API”).

    3. Create a New App

      Navigate to Create App and configure the following settings:

    4. Select Your Repository

      • Choose GitHub as your Git source
      • Select the repository containing your Dockerfile
      • Choose the branch you want to deploy (usually main or master)
    5. Configure Traffic Type

      • Traffic Type: Select HTTP (Hasura serves a web-based GraphQL API and Console)
      • Internal Port: Set to 8080 (the default Hasura port that your container listens on)
    6. Set Environment Variables

      Add the following environment variables for your Hasura configuration:

      Required:

      • HASURA_GRAPHQL_DATABASE_URL: Your PostgreSQL connection string (format: postgres://username:password@host:port/database)
      • HASURA_GRAPHQL_ADMIN_SECRET: A strong secret key for admin access (use a secure password generator)

      Recommended:

      • HASURA_GRAPHQL_ENABLE_CONSOLE: Set to true to enable the web console
      • HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
      • HASURA_GRAPHQL_UNAUTHORIZED_ROLE: anonymous (optional, for public access to certain queries)

      Optional:

      • HASURA_GRAPHQL_JWT_SECRET: JWT configuration for authentication (JSON format)
      • HASURA_GRAPHQL_CORS_DOMAIN: * or specify allowed domains for CORS
      • HASURA_GRAPHQL_ENABLE_TELEMETRY: false to disable telemetry

      Security Note: Always use strong, unique secrets for production deployments. Never commit secrets to your repository.

    7. Configure Additional Settings

      • Region: Select the region closest to your users for optimal latency
      • Compute Resources: Choose CPU and memory based on your workload (minimum 512MB RAM recommended, 1GB+ for production)
      • Instances: Start with 1 instance (scale horizontally as needed)
    8. Deploy Your Application

      Click “Create” to start the deployment. Klutch.sh will:

      • Automatically detect your Dockerfile in the repository root
      • Build the Docker image
      • Start your Hasura container with the configured environment variables
      • Assign a URL for external connections
    9. Access Your Hasura Console

      Once deployment is complete, you’ll receive a URL like example-app.klutch.sh. Access the Hasura Console at:

      https://example-app.klutch.sh/console

      You’ll be prompted for your admin secret (the value you set in HASURA_GRAPHQL_ADMIN_SECRET).


Configuring Your First Table and GraphQL API

Step 1: Access the Hasura Console

Navigate to your Hasura Console at https://example-app.klutch.sh/console and enter your admin secret.

Step 2: Create a Table

  1. Click on the DATA tab
  2. Click Add Table
  3. Create a sample users table:
    • Table name: users
    • Columns:
      • id (UUID, Primary Key, Default: gen_random_uuid())
      • name (Text)
      • email (Text, Unique)
      • created_at (Timestamp, Default: now())
  4. Click Add Table

Step 3: Insert Sample Data

In the DATA tab, select your users table and click the Insert Row tab:

{
"name": "John Doe",
"email": "john@example.com"
}

Click Save to insert the data.

Step 4: Test Your GraphQL API

Navigate to the API tab to open the GraphiQL interface. Try this query:

query GetUsers {
users {
id
name
email
created_at
}
}

You should see your inserted data returned!


Using the GraphQL API in Your Application

Once Hasura is deployed, you can connect to it from any application using the GraphQL endpoint:

GraphQL Endpoint

https://example-app.klutch.sh/v1/graphql

Authentication

Include your admin secret or JWT token in the headers:

x-hasura-admin-secret: your-admin-secret

Or for user authentication:

Authorization: Bearer <jwt-token>

Example: JavaScript/Node.js (using graphql-request)

import { GraphQLClient, gql } from 'graphql-request';
const endpoint = 'https://example-app.klutch.sh/v1/graphql';
const client = new GraphQLClient(endpoint, {
headers: {
'x-hasura-admin-secret': 'your-admin-secret',
},
});
const query = gql`
query GetUsers {
users {
id
name
email
created_at
}
}
`;
async function fetchUsers() {
const data = await client.request(query);
console.log(data);
}
fetchUsers();

Example: Python (using requests)

import requests
url = "https://example-app.klutch.sh/v1/graphql"
headers = {
"x-hasura-admin-secret": "your-admin-secret",
"Content-Type": "application/json"
}
query = """
query GetUsers {
users {
id
name
email
created_at
}
}
"""
response = requests.post(
url,
json={"query": query},
headers=headers
)
print(response.json())

Example: React (using Apollo Client)

import { ApolloClient, InMemoryCache, ApolloProvider, useQuery, gql } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://example-app.klutch.sh/v1/graphql',
cache: new InMemoryCache(),
headers: {
'x-hasura-admin-secret': 'your-admin-secret',
},
});
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
created_at
}
}
`;
function Users() {
const { loading, error, data } = useQuery(GET_USERS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{data.users.map(user => (
<li key={user.id}>
{user.name} - {user.email}
</li>
))}
</ul>
);
}
function App() {
return (
<ApolloProvider client={client}>
<Users />
</ApolloProvider>
);
}

Example: Go (using graphql package)

package main
import (
"context"
"fmt"
"log"
"github.com/machinebox/graphql"
)
func main() {
client := graphql.NewClient("https://example-app.klutch.sh/v1/graphql")
req := graphql.NewRequest(`
query GetUsers {
users {
id
name
email
created_at
}
}
`)
req.Header.Set("x-hasura-admin-secret", "your-admin-secret")
var response map[string]interface{}
if err := client.Run(context.Background(), req, &response); err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", response)
}

Advanced Features

Real-time Subscriptions

Hasura supports GraphQL subscriptions for real-time data:

subscription OnUserAdded {
users(order_by: {created_at: desc}, limit: 1) {
id
name
email
created_at
}
}

Mutations

Create, update, and delete data using mutations:

mutation CreateUser {
insert_users_one(object: {
name: "Jane Smith"
email: "jane@example.com"
}) {
id
name
email
}
}

Relationships

Define relationships between tables in the Hasura Console to enable nested queries:

query GetUsersWithPosts {
users {
id
name
posts {
id
title
content
}
}
}

Permissions and Roles

Configure role-based access control in the Hasura Console:

  1. Navigate to the DATA tab
  2. Select your table
  3. Click the Permissions tab
  4. Define permissions for different roles (user, anonymous, etc.)

Production Best Practices

Security Recommendations

  • Use Strong Admin Secrets: Generate a strong, random admin secret using a password manager or secure generator
  • Environment Variables: Always store sensitive credentials as environment variables in Klutch.sh, never in your Dockerfile or repository
  • JWT Authentication: Implement JWT-based authentication for production applications instead of using the admin secret for client apps
  • CORS Configuration: Restrict HASURA_GRAPHQL_CORS_DOMAIN to your specific domains instead of using *
  • Disable Console in Production: Set HASURA_GRAPHQL_ENABLE_CONSOLE to false for production and use the Hasura CLI for migrations
  • Rate Limiting: Implement rate limiting at the application or infrastructure level
  • Network Security: Use private networks or VPNs for database connections when possible

Performance Optimization

  • Database Indexes: Create indexes on frequently queried columns
  • Query Caching: Enable Hasura’s query caching features for better performance
  • Resource Allocation: Monitor your application and adjust compute resources as needed
  • Connection Pooling: Hasura handles connection pooling automatically, but monitor your database connections
  • Optimize Queries: Use the query performance analyzer in the Hasura Console

Database Migrations

Use the Hasura CLI for managing database migrations:

Terminal window
# Install Hasura CLI
npm install -g hasura-cli
# Initialize Hasura project
hasura init
# Create a migration
hasura migrate create init --from-server
# Apply migrations
hasura migrate apply
# Export metadata
hasura metadata export

Store migrations in your Git repository and apply them during deployment.

Monitoring and Logging

Monitor your Hasura instance for:

  • API response times
  • Error rates
  • Query performance
  • Database connection health
  • CPU and memory utilization
  • Active subscriptions

Enable detailed logging with:

HASURA_GRAPHQL_ENABLED_LOG_TYPES=startup,http-log,webhook-log,websocket-log,query-log

Backup Strategy

  • Database Backups: Implement regular PostgreSQL backups using pg_dump or your provider’s backup features
  • Metadata Exports: Regularly export and version control your Hasura metadata
  • Migrations: Keep all migrations in version control for reproducibility

Troubleshooting

Cannot Access Hasura Console

  • Verify that HASURA_GRAPHQL_ENABLE_CONSOLE is set to true
  • Check that you’re using the correct admin secret
  • Ensure your app is running and accessible at the Klutch.sh URL
  • Verify that the internal port is set to 8080 in your app configuration

Database Connection Issues

  • Verify your HASURA_GRAPHQL_DATABASE_URL is correct
  • Ensure your database is accessible from Klutch.sh
  • Check database credentials and connection limits
  • For Klutch.sh-hosted databases, verify the connection URL format

GraphQL API Errors

  • Check the logs in the Klutch.sh dashboard for detailed error messages
  • Verify your GraphQL schema and queries are valid
  • Ensure proper permissions are set for your roles
  • Check that required environment variables are set

Performance Issues

  • Review your database query performance and add indexes where needed
  • Monitor resource usage and scale up compute resources if necessary
  • Optimize complex GraphQL queries
  • Consider implementing query caching

Subscription Connection Issues

  • Verify WebSocket connections are allowed
  • Check CORS configuration
  • Ensure your client is properly configured for subscriptions
  • Verify network connectivity

Additional Resources


Conclusion

Deploying Hasura GraphQL Engine to Klutch.sh provides a powerful, scalable solution for building modern applications with instant GraphQL APIs. By following this guide, you’ve set up a production-ready Hasura instance with proper database connectivity, security configurations, and access to all of Hasura’s powerful features including real-time subscriptions, role-based access control, and remote schemas. Your GraphQL API is now ready to power your applications with fast, type-safe, and flexible data access.