#6618·hoppscotch

[Improvement]: Document idempotent migrate service pattern for docker compose self-hosting

Author: ganderCreated Aug 30, 2026Updated Sep 8, 2026

Description The self-hosting docs walk through running migrations as a separate manual step (docker run -it --entrypoint sh --env-file .env hoppscotch/hoppscotch then pnpm exec prisma migrate deploy inside the shell), then starting the app container separately. That works, but it's easy to mess up the order on a fresh deploy or after a restart, and it doesn't compose well with orchestrators like Portainer where people expect docker compose up -d to just work.

Since prisma migrate deploy is idempotent, migrations can be modeled as a proper one-shot service in the compose file instead, wired up with depends_on conditions so the whole stack starts correctly with a single command, on first deploy and on every restart.

Proposed solution Add (or link to) a docker-compose example along these lines in the self-hosting guide:

name: hoppscotch

services:
  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: <db_user>
      POSTGRES_PASSWORD: <db_pass>
      POSTGRES_DB: hoppscotch
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U <db_user> -d hoppscotch"]
      interval: 5s
      timeout: 5s
      retries: 10

  migrate:
    image: hoppscotch/hoppscotch
    restart: "no"
    env_file: .env
    command: sh -c 'pnpm exec prisma migrate deploy'
    depends_on:
      postgres:
        condition: service_healthy

  hoppscotch:
    image: hoppscotch/hoppscotch
    restart: unless-stopped
    env_file: .env
    ports:
      - "3000:3000"
      - "3100:3100"
      - "3170:3170"
    depends_on:
      postgres:
        condition: service_healthy
      migrate:
        condition: service_completed_successfully

volumes:
  postgres_data:

Key points worth calling out in the docs:

  • migrate stays in the compose file permanently, it doesn't need to be run manually or cleaned up.
  • depends_on: condition: service_completed_successfully on the app service guarantees migrations always finish before the app boots, even on a fresh volume.
  • The postgres healthcheck prevents migrate from racing a not-yet-ready database, which is the root cause behind reports like #3696.

This turns self-hosting into a single docker compose up -d, no manual docker run/docker exec steps required, and removes a common source of "backend keeps restarting" issues caused by running migrations too early or forgetting to run them at all