Dokploy

systemprompt

Self-owned AI control plane: governance gateway for Claude, OpenAI, and Gemini with policy checks, audit trails, rate limits, and MCP orchestration. Requires at least one AI provider API key.

systemprompt logo

Configuration

# Dokploy blueprint compose for the systemprompt gateway.
# Canonical copy: systempromptio/systemprompt-template deploy/dokploy/,
# published to Dokploy/templates blueprints/systemprompt/.
# Dokploy conventions: version 3.8, no ports/container_name/networks,
# main service name MUST equal the blueprint folder name (systemprompt).
version: "3.8"
services:
  systemprompt:
    image: ghcr.io/systempromptio/systemprompt-template:0
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DATABASE_URL: postgres://systemprompt:${POSTGRES_PASSWORD}@postgres:5432/systemprompt
      ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      GEMINI_API_KEY: ${GEMINI_API_KEY}
      EXTERNAL_URL: ${EXTERNAL_URL}
      HOST: 0.0.0.0
      PORT: 8080
    expose:
      - 8080
    volumes:
      - systemprompt_web:/app/web
      - systemprompt_storage:/app/storage/data
      - systemprompt_profiles:/app/services/profiles/docker
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"]
      interval: 30s
      timeout: 10s
      start_period: 300s
      retries: 3

  postgres:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: systemprompt
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: systemprompt
    volumes:
      # postgres:18+ stores data under major-version subdirectories of
      # /var/lib/postgresql — mounting the old .../data path aborts startup.
      - postgres_data:/var/lib/postgresql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U systemprompt -d systemprompt"]
      interval: 5s
      timeout: 5s
      retries: 10

volumes:
  systemprompt_web:
  systemprompt_storage:
  systemprompt_profiles:
  postgres_data:
[variables]
main_domain = "${domain}"
postgres_password = "${password:32}"

[config]
[[config.domains]]
serviceName = "systemprompt"
port = 8080
host = "${main_domain}"

[config.env]
POSTGRES_PASSWORD = "${postgres_password}"
EXTERNAL_URL = "https://${main_domain}"
ANTHROPIC_API_KEY = ""
OPENAI_API_KEY = ""
GEMINI_API_KEY = ""

Base64

To import this template in Dokploy: create a Compose service → AdvancedBase64 import and paste the content below:

ewogICJjb21wb3NlIjogIiMgRG9rcGxveSBibHVlcHJpbnQgY29tcG9zZSBmb3IgdGhlIHN5c3RlbXByb21wdCBnYXRld2F5LlxuIyBDYW5vbmljYWwgY29weTogc3lzdGVtcHJvbXB0aW8vc3lzdGVtcHJvbXB0LXRlbXBsYXRlIGRlcGxveS9kb2twbG95LyxcbiMgcHVibGlzaGVkIHRvIERva3Bsb3kvdGVtcGxhdGVzIGJsdWVwcmludHMvc3lzdGVtcHJvbXB0Ly5cbiMgRG9rcGxveSBjb252ZW50aW9uczogdmVyc2lvbiAzLjgsIG5vIHBvcnRzL2NvbnRhaW5lcl9uYW1lL25ldHdvcmtzLFxuIyBtYWluIHNlcnZpY2UgbmFtZSBNVVNUIGVxdWFsIHRoZSBibHVlcHJpbnQgZm9sZGVyIG5hbWUgKHN5c3RlbXByb21wdCkuXG52ZXJzaW9uOiBcIjMuOFwiXG5zZXJ2aWNlczpcbiAgc3lzdGVtcHJvbXB0OlxuICAgIGltYWdlOiBnaGNyLmlvL3N5c3RlbXByb21wdGlvL3N5c3RlbXByb21wdC10ZW1wbGF0ZTowXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBkZXBlbmRzX29uOlxuICAgICAgcG9zdGdyZXM6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICBEQVRBQkFTRV9VUkw6IHBvc3RncmVzOi8vc3lzdGVtcHJvbXB0OiR7UE9TVEdSRVNfUEFTU1dPUkR9QHBvc3RncmVzOjU0MzIvc3lzdGVtcHJvbXB0XG4gICAgICBBTlRIUk9QSUNfQVBJX0tFWTogJHtBTlRIUk9QSUNfQVBJX0tFWX1cbiAgICAgIE9QRU5BSV9BUElfS0VZOiAke09QRU5BSV9BUElfS0VZfVxuICAgICAgR0VNSU5JX0FQSV9LRVk6ICR7R0VNSU5JX0FQSV9LRVl9XG4gICAgICBFWFRFUk5BTF9VUkw6ICR7RVhURVJOQUxfVVJMfVxuICAgICAgSE9TVDogMC4wLjAuMFxuICAgICAgUE9SVDogODA4MFxuICAgIGV4cG9zZTpcbiAgICAgIC0gODA4MFxuICAgIHZvbHVtZXM6XG4gICAgICAtIHN5c3RlbXByb21wdF93ZWI6L2FwcC93ZWJcbiAgICAgIC0gc3lzdGVtcHJvbXB0X3N0b3JhZ2U6L2FwcC9zdG9yYWdlL2RhdGFcbiAgICAgIC0gc3lzdGVtcHJvbXB0X3Byb2ZpbGVzOi9hcHAvc2VydmljZXMvcHJvZmlsZXMvZG9ja2VyXG4gICAgaGVhbHRoY2hlY2s6XG4gICAgICB0ZXN0OiBbXCJDTURcIiwgXCJjdXJsXCIsIFwiLWZcIiwgXCJodHRwOi8vbG9jYWxob3N0OjgwODAvYXBpL3YxL2hlYWx0aFwiXVxuICAgICAgaW50ZXJ2YWw6IDMwc1xuICAgICAgdGltZW91dDogMTBzXG4gICAgICBzdGFydF9wZXJpb2Q6IDMwMHNcbiAgICAgIHJldHJpZXM6IDNcblxuICBwb3N0Z3JlczpcbiAgICBpbWFnZTogcG9zdGdyZXM6MTgtYWxwaW5lXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIFBPU1RHUkVTX1VTRVI6IHN5c3RlbXByb21wdFxuICAgICAgUE9TVEdSRVNfUEFTU1dPUkQ6ICR7UE9TVEdSRVNfUEFTU1dPUkR9XG4gICAgICBQT1NUR1JFU19EQjogc3lzdGVtcHJvbXB0XG4gICAgdm9sdW1lczpcbiAgICAgICMgcG9zdGdyZXM6MTgrIHN0b3JlcyBkYXRhIHVuZGVyIG1ham9yLXZlcnNpb24gc3ViZGlyZWN0b3JpZXMgb2ZcbiAgICAgICMgL3Zhci9saWIvcG9zdGdyZXNxbCDigJQgbW91bnRpbmcgdGhlIG9sZCAuLi4vZGF0YSBwYXRoIGFib3J0cyBzdGFydHVwLlxuICAgICAgLSBwb3N0Z3Jlc19kYXRhOi92YXIvbGliL3Bvc3RncmVzcWxcbiAgICBoZWFsdGhjaGVjazpcbiAgICAgIHRlc3Q6IFtcIkNNRC1TSEVMTFwiLCBcInBnX2lzcmVhZHkgLVUgc3lzdGVtcHJvbXB0IC1kIHN5c3RlbXByb21wdFwiXVxuICAgICAgaW50ZXJ2YWw6IDVzXG4gICAgICB0aW1lb3V0OiA1c1xuICAgICAgcmV0cmllczogMTBcblxudm9sdW1lczpcbiAgc3lzdGVtcHJvbXB0X3dlYjpcbiAgc3lzdGVtcHJvbXB0X3N0b3JhZ2U6XG4gIHN5c3RlbXByb21wdF9wcm9maWxlczpcbiAgcG9zdGdyZXNfZGF0YTpcbiIsCiAgImNvbmZpZyI6ICJbdmFyaWFibGVzXVxubWFpbl9kb21haW4gPSBcIiR7ZG9tYWlufVwiXG5wb3N0Z3Jlc19wYXNzd29yZCA9IFwiJHtwYXNzd29yZDozMn1cIlxuXG5bY29uZmlnXVxuW1tjb25maWcuZG9tYWluc11dXG5zZXJ2aWNlTmFtZSA9IFwic3lzdGVtcHJvbXB0XCJcbnBvcnQgPSA4MDgwXG5ob3N0ID0gXCIke21haW5fZG9tYWlufVwiXG5cbltjb25maWcuZW52XVxuUE9TVEdSRVNfUEFTU1dPUkQgPSBcIiR7cG9zdGdyZXNfcGFzc3dvcmR9XCJcbkVYVEVSTkFMX1VSTCA9IFwiaHR0cHM6Ly8ke21haW5fZG9tYWlufVwiXG5BTlRIUk9QSUNfQVBJX0tFWSA9IFwiXCJcbk9QRU5BSV9BUElfS0VZID0gXCJcIlxuR0VNSU5JX0FQSV9LRVkgPSBcIlwiXG4iCn0=

Instructions

systemprompt

Getting started

  1. Before the first deploy, set at least one AI provider key in Environment: ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY. The container will not boot without one.
  2. Enable HTTPS (Let's Encrypt) on the generated domain. The app validates EXTERNAL_URL and refuses plain http:// origins other than localhost — with HTTPS off it restart-loops with an "Invalid CORS origin" error.
  3. Deploy. The first boot runs database migrations and the publish pipeline; allow up to 5 minutes before the healthcheck goes green.
  4. Verify at https://<your-domain>/api/v1/health, then open the domain root for the admin UI.

Notes

  • POSTGRES_PASSWORD is auto-generated by the template; EXTERNAL_URL is derived from the domain you assign.
  • Web assets, storage, profile state, and Postgres data persist in the systemprompt_web, systemprompt_storage, systemprompt_profiles, and postgres_data volumes.
  • Docs: https://systemprompt.io/documentation/

Tags

ai, self-hosted


Version: 0.21.0

On this page