Documentation

Deploy with Docker Compose

Everything you need to run InsightPrompts on a laptop, a VM, or on-prem — configuration, persistence, updates, and the full compose reference.

Architecture

The stack is four containers on a private Docker network:

frontend — the web UI (nginx). The only service published to the host (port 8080). It proxies /api to the backend.

backend — the API. Runs database migrations and creates the admin user on startup. Not exposed to the host.

mysql — the database, persisted on a named volume. Not exposed to the host.

seed — a one-shot job that creates the demo login and sample data, then exits.

Because only the UI port is published, the database and API are not reachable from outside the Docker network — clients interact only through the web UI (and its /api proxy).

Prerequisites

Docker Desktop (macOS/Windows) or Docker Engine 24+ with the Compose v2 plugin (Linux).

• ~4 GB free disk; ~720 MB first-run download.

• Host port 8080 free (configurable via UI_PORT).

• A registry login if the images are private (see Private registry).

1. Get the files

You only need two files in an empty folder — no source code:

docker-compose.client.yml — the stack definition (full text in the reference below).

.env — your configuration (copy from .env.example).

2. Configure (.env)

Create .env next to the compose file. All values have sensible defaults; change passwords for anything beyond local testing.

VariableDefaultWhat it does
IMAGE_NAMESPACEverticalserveRegistry namespace the images come from
IMAGE_TAGlatestVersion to run (e.g. 1.1.0)
UI_PORT8080Host port for the web UI
MYSQL_DBinsightpromptsDatabase name
MYSQL_USERappuserDatabase user the app connects as
MYSQL_PASSWORDapppassDatabase user password
MYSQL_ROOT_PASSWORDrootpassMySQL root password
DEMO_EMAILdemo@verticalserve.comSeeded login email
DEMO_PASSWORDdemo1234Seeded login password
AWS_REGION / AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEYOptional — enable live model calls (see below)

Example .env:

IMAGE_NAMESPACE=verticalserve
IMAGE_TAG=1.1.0
UI_PORT=8080
MYSQL_DB=insightprompts
MYSQL_USER=appuser
MYSQL_PASSWORD=change-me
MYSQL_ROOT_PASSWORD=change-me-too
DEMO_EMAIL=demo@verticalserve.com
DEMO_PASSWORD=demo1234

3. Pull and run

# authenticate if the images are private
docker login

docker compose -f docker-compose.client.yml pull
docker compose -f docker-compose.client.yml up -d

First start takes a minute while the database initializes, migrations run, and the demo data is seeded. Check progress with:

docker compose -f docker-compose.client.yml ps
docker compose -f docker-compose.client.yml logs -f seed   # watch the seed finish

First login & what’s seeded

Open http://localhost:8080 and sign in:

email:    demo@verticalserve.com
password: demo1234

The seed creates two ready-to-run examples under Insights:

Coverage Gap Analysis — uses inline context (works fully offline).

Loss by Peril — runs live SQL against a seeded sample table, parameterized by the policy number you enter.

Building, testing (resolve/preview), evaluation and certification all work out of the box. Generating a final model answer requires model credentials — see Models & connectors.

Data persistence & backup

MySQL stores data on the mysql_data named volume, so your work persists across restart, stop/start, and up/down (without -v).

# stop (keeps data)
docker compose -f docker-compose.client.yml down

# back up the database to a file
docker compose -f docker-compose.client.yml exec mysql \
  sh -c 'exec mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE"' > backup.sql

# wipe everything INCLUDING data
docker compose -f docker-compose.client.yml down -v

Updating to a new version

Set the new IMAGE_TAG in .env (or use latest), then pull and recreate. Database migrations run automatically on the backend’s next start; your data is preserved.

docker compose -f docker-compose.client.yml pull
docker compose -f docker-compose.client.yml up -d

Enabling live model calls & connectors

The platform resolves context (documents, SQL, dashboards) and fills prompts out of the box. To generate the final AI answer, provide model credentials in .env:

AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret

Cloud connectors (SharePoint, warehouses, Power BI, …) are configured in-app under Data Locations with your own credentials. Nothing leaves your environment.

Private registry access

For commercial deployments the images are private. Authenticate with the credentials we provide before pulling:

# with a read-only access token we issue you
docker login -u <namespace> -p <access-token>

For air-gapped sites we provide an offline image bundle instead:

docker load -i insightprompts-images.tgz
docker compose -f docker-compose.client.yml up -d

Common commands

docker compose -f docker-compose.client.yml ps            # status
docker compose -f docker-compose.client.yml logs -f backend
docker compose -f docker-compose.client.yml restart backend
docker compose -f docker-compose.client.yml run --rm seed  # re-seed demo data (idempotent)
docker compose -f docker-compose.client.yml down           # stop, keep data

Troubleshooting

Port 8080 in use — set a different UI_PORT in .env and re-run up -d.

UI loads but API calls fail — the backend is still starting; logs -f backend until you see “Application startup complete”.

Seed didn’t run — run it manually: docker compose -f docker-compose.client.yml run --rm seed.

pull denied — you need docker login with access to the private images.

docker-compose.client.yml (reference)

Copy this into docker-compose.client.yml:

name: insightprompts

services:
  mysql:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpass}
      MYSQL_DATABASE: ${MYSQL_DB:-insightprompts}
      MYSQL_USER: ${MYSQL_USER:-appuser}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:-apppass}
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-p${MYSQL_ROOT_PASSWORD:-rootpass}"]
      interval: 5s
      timeout: 10s
      retries: 12
      start_period: 30s

  backend:
    image: ${IMAGE_NAMESPACE:-verticalserve}/insightprompts-api:${IMAGE_TAG:-latest}
    platform: linux/amd64
    restart: unless-stopped
    environment:
      MYSQL_HOST: mysql
      MYSQL_PORT: "3306"
      MYSQL_DB: ${MYSQL_DB:-insightprompts}
      MYSQL_USER: ${MYSQL_USER:-appuser}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:-apppass}
      DATABASE_URL: "mysql+pymysql://${MYSQL_USER:-appuser}:${MYSQL_PASSWORD:-apppass}@mysql:3306/${MYSQL_DB:-insightprompts}"
      AWS_REGION: ${AWS_REGION:-us-east-1}
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
    depends_on:
      mysql:
        condition: service_healthy

  seed:
    image: ${IMAGE_NAMESPACE:-verticalserve}/insightprompts-api:${IMAGE_TAG:-latest}
    platform: linux/amd64
    command: ["python", "-m", "app.commands.seed_demo"]
    environment:
      MYSQL_HOST: mysql
      MYSQL_PORT: "3306"
      MYSQL_DB: ${MYSQL_DB:-insightprompts}
      MYSQL_USER: ${MYSQL_USER:-appuser}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:-apppass}
      DATABASE_URL: "mysql+pymysql://${MYSQL_USER:-appuser}:${MYSQL_PASSWORD:-apppass}@mysql:3306/${MYSQL_DB:-insightprompts}"
      DEMO_EMAIL: ${DEMO_EMAIL:-demo@verticalserve.com}
      DEMO_PASSWORD: ${DEMO_PASSWORD:-demo1234}
    depends_on:
      backend:
        condition: service_healthy
    restart: "no"

  frontend:
    image: ${IMAGE_NAMESPACE:-verticalserve}/insightprompts-ui:${IMAGE_TAG:-latest}
    platform: linux/amd64
    restart: unless-stopped
    ports:
      - "${UI_PORT:-8080}:80"
    depends_on:
      backend:
        condition: service_healthy

volumes:
  mysql_data:

Want help deploying in your environment?

On-prem, air-gapped, Kubernetes, SSO — we’ll get InsightPrompts running the way your security team needs.

Talk to us