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:
mkdir hasura-klutchcd hasura-klutchgit initStep 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 portEXPOSE 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 directoryWORKDIR /hasura
# Copy migrations and metadataCOPY migrations ./migrationsCOPY metadata ./metadataCOPY config.yaml ./config.yaml
# Expose the default Hasura portEXPOSE 8080Create a config.yaml file for Hasura CLI configuration:
version: 3endpoint: http://localhost:8080admin_secret: your-admin-secretmetadata_directory: metadatamigrations_directory: migrationsactions: kind: synchronous handler_webhook_baseurl: http://localhost:3000Important: 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:
docker-compose up -d
# Stop when donedocker-compose downNote: 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:
git add Dockerfilegit commit -m "Add Hasura Dockerfile configuration"git remote add origin https://github.com/yourusername/hasura-klutch.gitgit push -u origin mainSetting 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
-
Log in to Klutch.sh
Navigate to klutch.sh/app and sign in to your account.
-
Create a New Project
Go to Create Project and give your project a meaningful name (e.g., “Hasura GraphQL API”).
-
Create a New App
Navigate to Create App and configure the following settings:
-
Select Your Repository
- Choose GitHub as your Git source
- Select the repository containing your Dockerfile
- Choose the branch you want to deploy (usually
mainormaster)
-
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)
-
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 totrueto enable the web consoleHASURA_GRAPHQL_ENABLED_LOG_TYPES:startup, http-log, webhook-log, websocket-log, query-logHASURA_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 CORSHASURA_GRAPHQL_ENABLE_TELEMETRY:falseto disable telemetry
Security Note: Always use strong, unique secrets for production deployments. Never commit secrets to your repository.
-
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)
-
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
-
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/consoleYou’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
- Click on the DATA tab
- Click Add Table
- Create a sample
userstable:- Table name:
users - Columns:
id(UUID, Primary Key, Default: gen_random_uuid())name(Text)email(Text, Unique)created_at(Timestamp, Default: now())
- Table name:
- 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/graphqlAuthentication
Include your admin secret or JWT token in the headers:
x-hasura-admin-secret: your-admin-secretOr 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:
- Navigate to the DATA tab
- Select your table
- Click the Permissions tab
- 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_DOMAINto your specific domains instead of using* - Disable Console in Production: Set
HASURA_GRAPHQL_ENABLE_CONSOLEtofalsefor 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:
# Install Hasura CLInpm install -g hasura-cli
# Initialize Hasura projecthasura init
# Create a migrationhasura migrate create init --from-server
# Apply migrationshasura migrate apply
# Export metadatahasura metadata exportStore 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-logBackup Strategy
- Database Backups: Implement regular PostgreSQL backups using
pg_dumpor 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_CONSOLEis set totrue - 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_URLis 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
- Klutch.sh Documentation
- Official Hasura Documentation
- Hasura Learn Tutorials
- Hasura Docker Image Documentation
- Hasura Blog
- Klutch.sh Deployments Guide
- Klutch.sh Networking Guide
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.