Complete guide for setting up and configuring Hasura GraphQL Engine for the Brackeys Web application.
This project uses Hasura v2 GraphQL Engine with the following features:
┌─────────────────────────────────────────────────────────────┐
│                      Frontend (React)                        │
│                     GraphQL Client                           │
└──────────────────────────┬──────────────────────────────────┘
                           │
                           │ GraphQL Queries/Mutations
                           │
┌──────────────────────────▼──────────────────────────────────┐
│                  Hasura GraphQL Engine                       │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  - Query Engine                                       │  │
│  │  - Permission System                                  │  │
│  │  - Real-time Subscriptions                           │  │
│  │  - Naming Convention (camelCase)                     │  │
│  └───────────────────────────────────────────────────────┘  │
└──────────────────────────┬──────────────────────────────────┘
                           │
                           │ SQL Queries
                           │
┌──────────────────────────▼──────────────────────────────────┐
│                   PostgreSQL Database                        │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  Schemas:                                             │  │
│  │  - users (authentication data)                        │  │
│  │  - collab (collaboration posts, profiles, etc.)      │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
Docker and Docker Compose
docker --version  # Should be 20.10+
docker-compose --version  # Should be 1.29+
Hasura CLI (optional, for local development)
curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash
hasura version
Clone and Configure
cd brackeys-web
cp .env.example .env
Set Environment Variables
Edit .env and configure:
# Required
POSTGRES_PASSWORD=<secure-password>
HASURA_GRAPHQL_ADMIN_SECRET=<secure-admin-secret>
# Optional (for authentication)
HASURA_GRAPHQL_JWT_SECRET='{"type":"RS256","jwk_url":"https://..."}'
Start Services
docker-compose up -d postgres hasura
Verify Installation
For a simplified getting started guide, see hasura/QUICKSTART.md.
Option 1: CLI Console (Recommended)
cd hasura
hasura console
# Make changes in the console
# Metadata and migrations are automatically tracked
Option 2: Manual Migration
cd hasura
hasura migrate create "add_new_table" --database-name default
# Edit the generated files:
# migrations/default/<timestamp>_add_new_table/up.sql
# migrations/default/<timestamp>_add_new_table/down.sql
Option 3: From Existing Database
cd hasura
hasura migrate create "import_schema" --database-name default --sql-from-server
# Local
cd hasura && npm run migrate:apply
# Development
cd hasura && npm run migrate:apply:dev
# Using Makefile
cd hasura && make migrate-apply ENV=dev
# Rollback last migration
cd hasura && npm run migrate:rollback
# Rollback multiple steps
cd hasura
hasura migrate apply --down 3 --database-name default
# Using Makefile
make migrate-rollback STEPS=3 ENV=local
After making changes via the console:
cd hasura
npm run metadata:export
# or
make metadata-export
cd hasura
hasura metadata apply
metadata/
├── version.yaml                    # Metadata version
├── databases/
│   ├── databases.yaml             # Database connections
│   └── default/
│       └── tables/
│           └── tables.yaml        # Table tracking and relationships
├── actions.yaml                   # Custom actions
├── allow_list.yaml               # Query allowlist
├── api_limits.yaml               # API rate limits
├── cron_triggers.yaml            # Scheduled triggers
├── inherited_roles.yaml          # Role inheritance
├── query_collections.yaml        # Saved queries
├── remote_schemas.yaml           # Remote schema integrations
└── rest_endpoints.yaml           # REST endpoints
Hasura is configured with graphql-default naming convention:
| Feature | Database | GraphQL | 
|---|---|---|
| Table names | collaboration_post | collaborationPost | 
| Column names | user_id | userId | 
| Foreign keys | profile_id | profileId | 
This provides a seamless experience with camelCase in your frontend code.
hasura-pr-check.yml)Runs on every PR that modifies Hasura files:
hasura-deploy.yml)Triggers on push to main/staging/develop branches:
Steps:
develop → Development environmentstaging → Staging environmentmain → Production environment (with safety checks)Configure these in GitHub Settings → Secrets:
# Development
HASURA_DEV_ENDPOINT
HASURA_DEV_ADMIN_SECRET
# Staging
HASURA_STAGING_ENDPOINT
HASURA_STAGING_ADMIN_SECRET
# Production
HASURA_PROD_ENDPOINT
HASURA_PROD_ADMIN_SECRET
PROD_DATABASE_URL  # For backups
The hasura/Dockerfile creates a migration image:
# Build
cd hasura
docker build -t brackeys-hasura-migrations:latest .
# Run
docker run --rm \
  -e HASURA_GRAPHQL_DATABASE_URL="postgres://..." \
  -e HASURA_GRAPHQL_ADMIN_SECRET="..." \
  brackeys-hasura-migrations:latest
This image is automatically built and pushed to GitHub Container Registry on every push.
cd hasura
./scripts/apply-migrations.sh dev
cd hasura
./scripts/apply-migrations.sh staging
cd hasura
./scripts/apply-migrations.sh prod
# Requires confirmation
Deployments happen automatically via GitHub Actions:
If a migration causes issues:
cd hasura
# Check current status
hasura migrate status --endpoint $PROD_ENDPOINT --admin-secret $SECRET --database-name default
# Rollback
./scripts/rollback-migration.sh 1 prod
X-Hasura-User-Id etc.* in productionIf migrations conflict:
cd hasura
hasura migrate status --database-name default
# Identify conflicting version
# Rollback or fix manually
If metadata differs from files:
cd hasura
hasura metadata diff
hasura metadata apply  # Apply from files
# or
hasura metadata export  # Export from server
Debug permissions:
# Check role variables
X-Hasura-Role: user
X-Hasura-User-Id: 12345
# View in Hasura console
Data → [Table] → Permissions → [Role]
# Check Hasura logs
docker-compose logs hasura
# Check database connection
docker-compose exec postgres psql -U postgres -d brackeys
Use the hasura scope for all Hasura-related commits:
feat(hasura): add collaboration post queries
fix(hasura): correct profile relationship
chore(hasura): update permissions for user role
docs(hasura): document custom naming convention
See HASURA_VERSIONING.md for details.