Guide

Self-hosting Hoppscotch for your team.

An operational guide for teams running Hoppscotch on their own infrastructure — Docker Compose setup, auth providers, PostgreSQL backups, upgrade workflow, and Kubernetes.

May 2026

Comparing API clients before committing to self-hosting?

API clients comparison →

// Why teams self-host Hoppscotch

Teams self-host Hoppscotch for four reasons that come up consistently in regulated industries and data-conscious organisations. Full data sovereignty: collections, environments, team workspaces, and credentials never leave your infrastructure — no cloud account, no third-party data residency, no dependency on Hoppscotch's SaaS uptime. License freedom: Hoppscotch is MIT-licensed, meaning you can fork, modify, or extend it without restriction. No per-user pricing: self-hosted Hoppscotch is free for any team size. And control over upgrade timing: you decide when to move from one release to the next.

The honest cost: none of these benefits are free. Self-hosting trades cloud convenience for operational responsibility. You will need to handle database backups, TLS certificate renewal, auth provider configuration, monitoring, and occasional debugging when something breaks. Teams without an existing platform or DevOps function will find this ongoing burden meaningful. Size the effort before deciding.

When self-hosting fits — and when it doesn't

Self-hosting Hoppscotch is a strong fit for teams with existing platform capacity — a DevOps function or infrastructure team that already runs Docker-based services on cloud VMs or Kubernetes. It also fits regulated industries with strict data-residency requirements: healthcare (HIPAA), finance (SOC 2, PCI DSS), government, and any team whose compliance scope rules out routing API request metadata through a third-party SaaS. And it fits teams large enough that cloud per-seat pricing is a real budget consideration.

  • You have an engineer or platform team comfortable with Docker Compose and PostgreSQL operations
  • Compliance requirements mandate data residency that rules out SaaS API tools
  • Your team is large enough that cloud per-seat pricing is a meaningful cost
  • You already run a similar self-hosted service (GitLab, Confluence, etc.) and have established patterns for backups, monitoring, and upgrades

Note:Self-hosting does not fit small teams of 3–5 people without dedicated infrastructure capacity. The cloud-hosted version at hoppscotch.io is free for individuals and covers basic team workspaces. Fully-local tools like Yaak require no backend at all. If running a PostgreSQL database and maintaining a Docker service is a distraction from your core work, the cloud version is the honest answer.

// Architecture in one diagram

A self-hosted Hoppscotch deployment has three active components and one optional admin interface. The web app (frontend) is what your team uses in the browser. The backend API handles authentication, team workspaces, and data sync — it exposes both a GraphQL endpoint and a REST API. PostgreSQL persists everything. The admin dashboard (optional but recommended) is a separate interface for managing users, invitations, and instance configuration.

The All-In-One Docker image on Docker Hub (hoppscotch/hoppscotch) bundles all four into a single container on three ports: 3000 for the frontend, 3170 for the backend API, and 3100 for the admin dashboard. Separate images exist for scaling individual components, but the AIO image is the right starting point for most teams.

Self-hosted deployment layout

┌──────────────────────────────┐
  Hoppscotch App (port 3000)  │  ← team uses this in browser
└──────────────┬───────────────┘

┌──────────────▼───────────────┐
  Backend API (port 3170)     │  ← GraphQL + REST, auth
└──────────────┬───────────────┘

┌──────────────▼───────────────┐
  PostgreSQL 15 (port 5432)   │  ← collections, users, envs
└──────────────────────────────┘

┌──────────────────────────────┐
  Admin Dashboard (port 3100) │  ← team mgmt, invitations
└──────────────────────────────┘
   (connects to Backend API)

Note:All persistent data lives in PostgreSQL — collections, environments, team workspaces, and user accounts. The frontend and backend are stateless: destroy and recreate them from the Docker image at any time without data loss. Your backup story is therefore simple: back up the PostgreSQL database. If your team already has a Postgres backup pattern from another self-hosted service, you are most of the way there.

// Docker Compose setup

Prerequisites

Before running the stack, confirm you have these in place:

  • Docker 20.10+ and Docker Compose v2+ — verify with docker compose version
  • A Linux host with at least 2 GB RAM — a cloud VM (EC2, GCE, DigitalOcean Droplet) is the typical choice; Mac or WSL2 work for local testing but are not recommended for production
  • A domain name with DNS A records pointing to your host's IP — required for valid TLS certificates in production
  • An SMTP relay or email provider for sending auth emails (verification, password resets, team invitations)
  • If using OAuth: an OAuth app registered with at least one provider (Google Cloud Console, GitHub Settings, or Azure AD)

docker-compose.yml and .env

Create a working directory (for example /opt/hoppscotch) and add two files: docker-compose.yml and .env. Docker Compose reads .env automatically from the working directory — keep both files together.

The compose file below uses the pre-built All-In-One image from Docker Hub. A health-checked Postgres service ensures Hoppscotch starts only after the database is ready. All Hoppscotch configuration goes in the .env file — not inline in the compose file — to keep secrets out of version control.

docker-compose.yml

services:
  hoppscotch:
    image: hoppscotch/hoppscotch:latest
    restart: unless-stopped
    ports:
      - "3000:3000"   # frontend
      - "3100:3100"   # admin dashboard
      - "3170:3170"   # backend API
    env_file:
      - .env
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:15
    restart: unless-stopped
    environment:
      POSTGRES_USER: hoppscotch
      POSTGRES_PASSWORD: CHANGEME
      POSTGRES_DB: hoppscotch
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "sh -c 'pg_isready -U hoppscotch -d hoppscotch'"]
      interval: 5s
      timeout: 5s
      retries: 10

volumes:
  postgres-data:

.env (core variables — expand with auth section)

# Database
DATABASE_URL=postgresql://hoppscotch:CHANGEME@postgres:5432/hoppscotch

# Encryption key — exactly 32 characters
# Generate with: openssl rand -hex 16
DATA_ENCRYPTION_KEY=your-32-character-encryption-key

# Frontend URLs — set to your actual domain
VITE_BASE_URL=https://hoppscotch.example.com
VITE_SHORTCODE_BASE_URL=https://hoppscotch.example.com
VITE_ADMIN_URL=https://admin.hoppscotch.example.com

# Backend URLs — set to your backend domain/port
VITE_BACKEND_GQL_URL=https://api.hoppscotch.example.com/graphql
VITE_BACKEND_WS_URL=wss://api.hoppscotch.example.com/graphql
VITE_BACKEND_API_URL=https://api.hoppscotch.example.com/v1

# CORS — must include all origins that communicate with the backend
WHITELISTED_ORIGINS=https://hoppscotch.example.com,https://admin.hoppscotch.example.com

# Auth providers — see Section 4 for full config
VITE_ALLOWED_AUTH_PROVIDERS=EMAIL

First run: database migration

Hoppscotch uses Prisma for database schema management. On a fresh deployment, run migrations before starting the full stack. The AIO image ships with the Prisma CLI — use it as a one-off container before bringing up the main service:

Migrate then start

# Run database migrations (first deployment and every upgrade)
docker run --rm --env-file .env hoppscotch/hoppscotch \
  sh -c "pnpm exec prisma migrate deploy"

# Start the stack
docker compose up -d

# Verify all containers are running
docker compose ps

# Tail logs to confirm a clean start
docker compose logs hoppscotch -f

Note:Pin the image version in production. Replace :latest with a specific release tag — for example hoppscotch/hoppscotch:2026.4.1. The latest tag changes without notice on every new release. Pinning gives you explicit control over when you absorb each upgrade and makes rollbacks straightforward.

// Authentication providers

Email and password — simplest to start

Email/password login requires no OAuth app registration. Enable it via VITE_ALLOWED_AUTH_PROVIDERS and configure SMTP so Hoppscotch can send verification emails, password resets, and team invitations. Hoppscotch supports both a single SMTP URL and individual host/port/credential variables.

SMTP configuration in .env

VITE_ALLOWED_AUTH_PROVIDERS=EMAIL

MAILER_SMTP_ENABLE=true
MAILER_USE_CUSTOM_CONFIGS=true
MAILER_ADDRESS_FROM=noreply@example.com

# Custom SMTP credentials (use these OR MAILER_SMTP_URL below)
MAILER_SMTP_HOST=smtp.example.com
MAILER_SMTP_PORT=587
MAILER_SMTP_SECURE=true
MAILER_SMTP_USER=your-smtp-user
MAILER_SMTP_PASSWORD=your-smtp-password

# Alternatively, a single SMTP URL:
# MAILER_SMTP_URL=smtp://user:password@smtp.example.com:587

Google, GitHub, and Microsoft OAuth

Hoppscotch Community Edition supports OAuth via Google, GitHub, and Microsoft. All three follow the same pattern: register an OAuth app with the provider, get a client ID and secret, set the callback URL pointing to your backend, then add the env vars.

Google: create OAuth 2.0 credentials in Google Cloud Console (APIs & Services → Credentials). Add your callback URL to Authorized redirect URIs. GitHub: register an OAuth App in Settings → Developer Settings → OAuth Apps. Microsoft: register an app in Azure AD → App registrations, add a Redirect URI, note your tenant ID (or use 'common' for multi-tenant). The callback URL pattern for all three providers is the same format: your backend API URL plus /v1/auth/{provider}/callback.

OAuth provider variables in .env

# Enable multiple providers (comma-separated, no spaces)
VITE_ALLOWED_AUTH_PROVIDERS=GOOGLE,GITHUB,MICROSOFT,EMAIL

# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_CALLBACK_URL=https://api.hoppscotch.example.com/v1/auth/google/callback
GOOGLE_SCOPE=email,profile

# GitHub OAuth
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_CALLBACK_URL=https://api.hoppscotch.example.com/v1/auth/github/callback
GITHUB_SCOPE=user:email

# Microsoft OAuth
MICROSOFT_CLIENT_ID=your-azure-app-client-id
MICROSOFT_CLIENT_SECRET=your-azure-app-client-secret
MICROSOFT_CALLBACK_URL=https://api.hoppscotch.example.com/v1/auth/microsoft/callback
MICROSOFT_TENANT=common

Note:SAML-based SSO and OpenID Connect are Enterprise Edition features. The Community Edition supports email/password, Google, GitHub, and Microsoft OAuth only. If your organisation requires SAML, you need either the Hoppscotch Enterprise Edition ($19/user/month) or a workaround via an OAuth-based identity proxy such as Keycloak. Verify current SAML support at docs.hoppscotch.io before committing to a deployment path.

// TLS and reverse proxy

Hoppscotch does not handle TLS — put a reverse proxy in front. The example below uses Caddy, which handles Let's Encrypt certificate provisioning and renewal automatically with no Certbot or renewal cron required. If your team already runs Nginx, Traefik, or an ingress controller, use those instead — the proxy requirement is not Caddy-specific.

The three-subdomain pattern maps cleanly to Hoppscotch's three components: the app on the main domain, the backend API on an api. subdomain, and the admin dashboard on an admin. subdomain. Point DNS A records for all three subdomains to your server's IP before running Caddy.

Caddyfile (three-subdomain layout)

hoppscotch.example.com {
  reverse_proxy localhost:3000
}

api.hoppscotch.example.com {
  reverse_proxy localhost:3170
}

admin.hoppscotch.example.com {
  reverse_proxy localhost:3100
}

Note:With Nginx, you need Certbot for certificate management and a renewal cron. With Traefik, Docker labels on the compose services trigger automatic cert provisioning — a good fit if your team is already Traefik-based. For Kubernetes, an Ingress controller with cert-manager handles the same role. The Hoppscotch repository includes Caddyfiles for each component under packages/ — review those before writing your own proxy config.

// Database backup strategy

PostgreSQL is the only stateful component — everything else is rebuildable from the Docker image. Back up Postgres and you have protected all of Hoppscotch's data. The standard approach is a daily pg_dump cron job that produces a compressed SQL dump you can restore to any compatible Postgres instance.

/etc/cron.daily/hoppscotch-backup

#!/bin/bash
BACKUP_DIR=/var/backups/hoppscotch
mkdir -p $BACKUP_DIR

docker compose -f /opt/hoppscotch/docker-compose.yml exec -T postgres \
  pg_dump -U hoppscotch hoppscotch \
  | gzip > $BACKUP_DIR/hoppscotch-$(date +%F).sql.gz

# Retain 30 days of local backups
find $BACKUP_DIR -name 'hoppscotch-*.sql.gz' -mtime +30 -delete

Off-site storage and restore testing

Never rely solely on backups stored on the same host as the database. Disk failures, accidental deletes, and server compromises affect both the live database and any local backups simultaneously. Pipe the dump to off-site storage: S3, Google Cloud Storage, Backblaze B2, or your team's object storage. Most cloud storage CLIs support piping directly from a dump command.

Test the restore quarterly. Restore the latest backup to a staging Hoppscotch instance, log in, open collections, and verify team workspaces are intact. An untested backup is an assumption, not a backup.

Note:Hoppscotch's official documentation is thin on backup procedures at the time of writing — check docs.hoppscotch.io for any guidance added since this article was published. The pg_dump approach above is standard PostgreSQL practice that works regardless of application-layer documentation. If Hoppscotch introduces application-level export or snapshot features in a future release, that guidance would complement rather than replace a database-level backup.

// Upgrade workflow

Upgrades follow a consistent pattern: read the release notes, back up, update the image tag, migrate, restart, verify. Prisma migrations run as part of the migrate step and are safe to run repeatedly — they only apply changes not yet in the database.

  • Read the release notes at github.com/hoppscotch/hoppscotch/releases for breaking changes, migration warnings, or required env var additions
  • Back up the database before upgrading — run the pg_dump script manually or trigger it ad-hoc
  • Update the image tag in docker-compose.yml: image: hoppscotch/hoppscotch:NEW_VERSION
  • Pull the new image: docker compose pull
  • Run migrations: docker run --rm --env-file .env hoppscotch/hoppscotch:NEW_VERSION sh -c "pnpm exec prisma migrate deploy"
  • Restart the stack: docker compose up -d
  • Check logs: docker compose logs hoppscotch -f — watch for migration errors or startup failures
  • Smoke test: log in, open a collection, send a request, verify team workspaces are intact

Note:Major version bumps (for example v2025.x to v2026.x) warrant extra caution. Read the full changelog, check GitHub Discussions for community upgrade reports, and schedule the upgrade during low-traffic hours with a rollback plan ready. Rollback means: restore the pre-upgrade database backup, revert the image tag in docker-compose.yml, run docker compose pull, then docker compose up -d. The DATA_ENCRYPTION_KEY must not change between versions — rotating it invalidates all encrypted data in the database.

// Monitoring and observability

The minimal viable monitoring layer covers two concerns: endpoint availability and database health.

Endpoint availability: any uptime monitoring service works — Uptime Robot, Better Stack, Grafana Cloud free tier, or your team's existing tool. Poll the Hoppscotch frontend URL (port 3000) every minute. Alert on two or more consecutive failures to avoid noise from transient network hiccups.

Container health: Docker's built-in health check covers Postgres via pg_isready, already configured in the docker-compose above. Monitor container restarts with docker ps or your existing container observability stack (Prometheus + cAdvisor, Datadog Agent, Grafana Alloy). A restarting container almost always means a database connectivity issue or a misconfigured env var — check logs before assuming a Hoppscotch bug.

Database disk usage: Postgres data grows slowly for typical API collection use, but Docker log accumulation and local backup files on the same volume can fill disk unexpectedly. Monitor disk usage on the volume mount and alert at 70% capacity to give headroom for daily backups. All other Postgres monitoring (slow queries, connection count, table bloat) follows standard PostgreSQL patterns — not Hoppscotch-specific.

Note:Hoppscotch does not expose Prometheus-format metrics natively as of this writing — verify current state at docs.hoppscotch.io. For deep observability you will rely on standard Docker and Postgres tooling. Application logs stream via docker compose logs hoppscotch -f; pipe these to your existing log aggregation system (Loki, Splunk, Datadog Logs) if your team has one.

// Kubernetes deployment

Hoppscotch maintains an official Helm chart repository at github.com/hoppscotch/helm-charts. The charts cover both Community and Enterprise editions and were actively maintained through May 2026. Add the chart repository and install using your own values file:

Install via Helm

# Add the official Hoppscotch Helm repository
helm repo add hoppscotch https://hoppscotch.github.io/helm-charts
helm repo update

# Inspect default values before installing
helm show values hoppscotch/hoppscotch > default-values.yaml

# Install Hoppscotch Community Edition
helm install hoppscotch hoppscotch/hoppscotch \
  --namespace hoppscotch \
  --create-namespace \
  --values my-values.yaml

Note:The Helm chart has known gaps — review open issues at github.com/hoppscotch/helm-charts before deploying to production. A reported issue at the time of writing (issue #19) showed Microsoft OAuth settings not being added correctly to the default secret template. Treat the chart as a solid starting point that requires review of all generated manifests before production use. For the database in Kubernetes, the chart supports an external Postgres instance — using a managed database service (AWS RDS, Cloud SQL, Azure Database for PostgreSQL) is strongly recommended over running Postgres as a StatefulSet without a dedicated DBA.

// Common operational issues

These are the most commonly reported operational issues from community GitHub Discussions and Issues.

  • Users can't log in after an upgrade — usually a DATA_ENCRYPTION_KEY change. This key must stay constant across upgrades; rotating it invalidates all encrypted data in the database. Also check OAuth callback URL drift if your DNS or domain configuration changed since the last deployment.
  • Backend container restarts in a loop — almost always a database connectivity issue. Check DATABASE_URL in .env, verify the Postgres container is healthy (docker compose logs postgres), and confirm WHITELISTED_ORIGINS includes all frontend and admin origins. A missing or incorrect WHITELISTED_ORIGINS will cause auth flows to fail on startup.
  • Auth emails not arriving — SMTP misconfiguration. Test SMTP independently with a one-off command (swaks or curl to your SMTP server) before debugging Hoppscotch. Verify MAILER_ADDRESS_FROM is an address your SMTP provider accepts as a sender.
  • PostgreSQL running out of disk — check for accumulated Docker logs, local backup files stored on the same volume, or an unusually large number of workspace objects. Postgres data itself stays small for typical collection use.
  • OAuth not working after domain or TLS change — callback URL mismatch. The GOOGLE_CALLBACK_URL (and equivalents for other providers) must exactly match the redirect URI registered in each OAuth app, including the correct protocol (https, not http) and any path or port differences.
  • Slow performance with very large collections — Hoppscotch handles mid-thousands of requests per workspace comfortably on modest hardware. For teams pushing past that, split workspaces by domain area rather than running a single giant workspace.

Note:Hoppscotch's primary community support channel is GitHub Discussions at github.com/hoppscotch/hoppscotch/discussions. There is no community-tier paid support — the team responds on a best-effort basis. For production deployments, factor self-reliance into your ops model: plan for a mean time-to-self-resolve measured in hours, not minutes.

// What next

Once Hoppscotch is running, the next operational step for most teams is establishing Git-based collection workflow patterns — versioning collections, environment files, and PR conventions alongside code. The Git-based API collections guide covers these patterns for teams using Hoppscotch's JSON export in a version-controlled workflow.

For the broader API client comparison — how Hoppscotch compares to Bruno, Insomnia, Yaak, and Postman across CLI maturity, collaboration model, environment handling, and data sovereignty — the API clients comparison covers 14 dimensions side-by-side.

If you are still deciding whether a GUI API client is the right tool category at all — versus code-first libraries like REST Assured or Supertest — the code-first vs GUI tools guide covers six decision factors including team composition, CI strategy, and data sovereignty.