From nhost
Activate when using Hasura CLI commands in a self-hosted Docker environment, including migrations, metadata management, and console access via docker exec.
npx claudepluginhub jovermier/claude-code-plugins-ip-labs --plugin nhostThis skill uses the workspace's default tool permissions.
This skill guides you through using Hasura CLI in a self-hosted Docker Compose environment where the Hasura CLI runs inside a container.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
This skill guides you through using Hasura CLI in a self-hosted Docker Compose environment where the Hasura CLI runs inside a container.
Claude automatically uses this skill when you:
In a self-hosted setup, the Hasura CLI runs inside a Docker container rather than on your host machine.
Self-Hosted Docker Stack:
┌──────────────────────────────────────────────────┐
│ console service (hasura/graphql-engine) │
│ • Runs hasura-cli console command │
│ • Port 9695: Hasura Console UI │
│ • Has hasura-cli installed │
│ • Working dir: /app (mounted nhost/ directory) │
└──────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────┐
│ graphql service (hasura/graphql-engine) │
│ • Main Hasura GraphQL Engine │
│ • Port 8080: GraphQL API │
└──────────────────────────────────────────────────┘
❌ TRADITIONAL HASURA CLI DOES NOT WORK DIRECTLY:
# ❌ These fail because CLI is inside container
hasura-cli migrate status
hasura-cli metadata export
✅ INSTEAD, USE DOCKER EXEC:
# ✅ Correct way to access Hasura CLI in Docker
docker exec {console-container-name} hasura-cli [command]
# Example:
docker exec backend-console-1 hasura-cli version
docker exec backend-console-1 hasura-cli migrate status
# List all containers to find the console
docker ps | grep console
# Common naming patterns:
# - backend-console-1
# - nhost-console-1
# - hasura-console-1
# - {project}-console-1
The Hasura Console is typically already running when your Docker stack is up:
# Console URL (configure in docker-compose.yaml)
http://localhost:9695
# Or via environment variable:
https://${CONSOLE_URL}
Docker Compose Configuration:
services:
console:
image: hasura/graphql-engine:{version}
entrypoint: ["hasura-cli"]
command: ["console", "--no-browser", "--endpoint=http://graphql:8080"]
ports:
- "9695:9695"
volumes:
- ./nhost:/app # Mount nhost directory
working_dir: /app
This means:
# Access the console container shell
docker exec -it {console-container-name} bash
# Inside container, run hasura-cli commands directly
hasura-cli migrate status
hasura-cli metadata export
All commands must be prefixed with docker exec {container-name}:
# Set your container name as environment variable for convenience
export CONSOLE_CONTAINER={your-console-container-name}
export HASURA_ADMIN_SECRET={your-admin-secret}
# Check migration status
docker exec $CONSOLE_CONTAINER hasura-cli migrate status \
--database-name default \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Apply pending migrations
docker exec $CONSOLE_CONTAINER hasura-cli migrate apply \
--database-name default \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Create new migration
docker exec $CONSOLE_CONTAINER hasura-cli migrate create "add_users_table" \
--database-name default \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Rollback last migration
docker exec $CONSOLE_CONTAINER hasura-cli migrate apply \
--down 1 \
--database-name default \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Rollback to specific version
docker exec $CONSOLE_CONTAINER hasura-cli migrate apply \
--version {timestamp} \
--database-name default \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Export metadata
docker exec $CONSOLE_CONTAINER hasura-cli metadata export \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Apply metadata
docker exec $CONSOLE_CONTAINER hasura-cli metadata apply \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Reload metadata (refresh GraphQL schema)
docker exec $CONSOLE_CONTAINER hasura-cli metadata reload \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Check metadata inconsistencies
docker exec $CONSOLE_CONTAINER hasura-cli metadata inconsistency list \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Apply seed data
docker exec $CONSOLE_CONTAINER hasura-cli seed apply \
--database-name default \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
# Apply specific seed file
docker exec $CONSOLE_CONTAINER hasura-cli seed apply \
--file seeds/default/1234_initial_data.sql \
--database-name default \
--endpoint http://graphql:8080 \
--admin-secret $HASURA_ADMIN_SECRET
The Hasura CLI typically needs these environment variables:
# Inside the console container (configured in docker-compose.yaml)
HASURA_GRAPHQL_ADMIN_SECRET=${GRAPHQL_ADMIN_SECRET}
HASURA_GRAPHQL_DATABASE_URL=postgres://${PGUSER}:${PGPASSWORD}@${PGHOST}:${PGPORT}/${PGDATABASE}
The console container should mount your project directory:
# In docker-compose.yaml
volumes:
- ./nhost:/app
working_dir: /app
This means the CLI can find:
/app/config.yaml - Hasura config/app/migrations/ - Migration files/app/metadata/ - Metadata files/app/seeds/ - Seed filesCreate shell aliases for convenience:
# Add to ~/.bashrc or ~/.zshrc
export CONSOLE_CONTAINER={your-container-name}
export HASURA_ADMIN_SECRET=${GRAPHQL_ADMIN_SECRET}
alias hasura='docker exec $CONSOLE_CONTAINER hasura-cli'
# Then use like:
hasura migrate status --database-name default
hasura metadata export
Scenario: Add a new database table
# 1. Open Hasura Console in browser
open http://localhost:9695
# 2. Make schema changes via UI
# - Go to DATA tab
# - Click "Create Table"
# - Define columns, constraints, relationships
# - Save
# 3. Console automatically creates migration files in:
# nhost/migrations/default/{timestamp}_{operation}/
# ├── up.sql (forward migration)
# └── down.sql (rollback migration)
# 4. Check migration status
docker exec $CONSOLE_CONTAINER hasura-cli migrate status \
--database-name default \
--endpoint http://graphql:8080
# 5. If needed, manually apply migrations
docker exec $CONSOLE_CONTAINER hasura-cli migrate apply \
--database-name default \
--endpoint http://graphql:8080
# 6. Export metadata to sync permissions
docker exec $CONSOLE_CONTAINER hasura-cli metadata export \
--endpoint http://graphql:8080
# 7. Reload Hasura metadata
docker exec $CONSOLE_CONTAINER hasura-cli metadata reload \
--endpoint http://graphql:8080
# 8. Commit migration files
git add nhost/migrations/
git add nhost/metadata/
git commit -m "feat(db): add users table"
Symptoms:
docker exec commands failSolutions:
# 1. Check if console container is running
docker ps | grep console
# 2. If not running, start Docker stack
docker compose up -d
# 3. Wait for services to be healthy
docker compose ps
# 4. Check console logs
docker logs {console-container-name}
Symptoms:
Solutions:
# 1. Check admin secret in .env file
grep HASURA_ADMIN_SECRET .env
# 2. Pass admin secret explicitly
docker exec $CONSOLE_CONTAINER hasura-cli migrate status \
--admin-secret "your-actual-secret-here" \
--database-name default
# 3. Or set environment variable
export HASURA_GRAPHQL_ADMIN_SECRET=$(grep HASURA_ADMIN_SECRET .env | cut -d '=' -f2)
Symptoms:
Solutions:
# 1. Verify migration files exist
ls -la nhost/migrations/default/
# 2. Check docker volume mount
docker inspect {console-container-name} | grep -A 10 Mounts
# 3. Verify working directory in container
docker exec $CONSOLE_CONTAINER pwd
# Should output: /app
# 4. List files in container
docker exec $CONSOLE_CONTAINER ls -la /app/migrations/default/
Symptoms:
Solutions:
# 1. Check if console service is running
docker ps | grep console
# 2. Check console service health
docker compose ps console
# 3. Check console logs for errors
docker logs {console-container-name} -f
# 4. Verify port mapping
docker port {console-container-name}
# 5. Try accessing via environment URL
echo "https://${CONSOLE_URL}"
| Feature | Managed (Nhost Cloud/Hasura Cloud) | Self-Hosted Docker |
|---|---|---|
| Console access | nhost dev hasura | Browser: http://localhost:9695 |
| CLI commands | hasura-cli [cmd] | docker exec {container} hasura-cli |
| Migration apply | Auto-applied | Manual via CLI or auto on startup |
| Console startup | On-demand | Always running with Docker stack |
| Endpoint | Managed by service | http://graphql:8080 (internal) |
| Admin secret | Auto-configured | From .env file |
| Working directory | Auto-detected | /app in container |
--database-name default for clarity| Task | Command |
|---|---|
| Check CLI version | docker exec $CONSOLE_CONTAINER hasura-cli version |
| Migration status | docker exec $CONSOLE_CONTAINER hasura-cli migrate status --database-name default |
| Apply migrations | docker exec $CONSOLE_CONTAINER hasura-cli migrate apply --database-name default |
| Export metadata | docker exec $CONSOLE_CONTAINER hasura-cli metadata export |
| Reload metadata | docker exec $CONSOLE_CONTAINER hasura-cli metadata reload |
| Access console | Open browser to http://localhost:9695 or https://${CONSOLE_URL} |
Remember: In self-hosted Docker environments, the Hasura CLI runs inside a container. Always use docker exec {container-name} hasura-cli to run CLI commands, and access the console via web browser.