Install & Deploy
The licensed Gostly product ships as a Docker Compose stack backed by container images you pull from a registry — there is no host binary to install. This page covers system sizing, the .env you fill in, the ports each service exposes, the Lite and Full installation choices, and the first record/replay check.
What you're installing
The licensed product is delivered as a docker-compose.yml plus a set of pre-built images. You authenticate to the image registry with a short-lived token from your dashboard, pull the images, fill in an .env, and run docker compose up. Lite includes the proxy, local dashboard/control API, database, and one-shot database setup. Active Pro trials default to Lite and can opt into Full to add AI services. Paid and manually granted Pro/Team accounts retain Full as their default and can also select Lite. The downloaded file defines the exact services and volumes:
ghost-proxy8080 · 8443The Rust proxy. The only service your application talks to. Runs the match cascade and the four operating modes. Plain HTTP on 8080; the TLS-MITM listener binds on 8443 when enabled.
ghost-web3000 · 8000Control plane API (8000) plus the operator dashboard (3000), one container. Owns services, mocks, transitions, drift, and the SSO/RBAC auth layer.
ghost-migrateone-shotApplies database setup and migrations before the control plane starts. A successful exit is expected; retain this dependency in your Compose file.
ghost-postgresinternalPostgreSQL 16. The persistent store for the mock library, services, and audit log. Not published to the host.
ghost-inferenceinternalThe AI inference engine (Pro/Team). Runs RAG retrieval and — when generation is enabled — serves cached LoRA-adapter responses. This is the memory-hungry container.
ghost-llamacppisolated, Full stackLocal model service, included when Full starts. Its dedicated Docker network is internal; it has no published host port.
Lite includes ghost-web and its local dashboard and omits the AI containers. Lite is an installation choice within an active entitlement, not an ongoing free plan. Keep the generated stack intact for capture, service routing, and library builds.
Compose + registry images, not a CLI
The licensed product is distributed exclusively as Docker Compose plus registry images. There is no gostly command to install on your host. If you came here looking for a host CLI with brew / package-manager install, that's the open-source proxy — a separate product with its own binary and its own command line. This page is about the licensed self-hosted stack.
Prerequisites
- → Docker and Docker Compose installed (Docker Desktop, or Docker Engine + the Compose plugin on Linux)
- → A Gostly license key — start a free Pro trial. Verify your email before issuing a key. New accounts receive 14 days of Pro without a credit card; a paid plan is required to continue after the trial.
- → A registry login token (issued from your dashboard, valid 12 hours) to pull the images
- → Any HTTP service you want to mock — local, staging, or third-party. Production access is not required.
Choose Lite or Full
Lite is the default trial download. Start with Lite for recording and replaying your own API traffic. It omits ghost-inference and ghost-llamacpp; choosing Lite does not change your license, trial deadline, or data limits.
Choose Full — includes AI services in the account dashboard when you want to evaluate AI functionality. Authenticated API downloads can opt in with /v1/install/docker-compose.yml?variant=full or request Lite with ?variant=lite. When the Pro trial expires, a paid subscription is required to continue; Lite does not provide a free fallback. Expired trials are blocked from either download until access is restored.
Preview, clipboard, and download use the same server-returned file. When switching stacks, keep the same private .env, database credentials, tenant ID, and volumes. Compare services and data mounts before changing an existing deployment; selecting a stack does not change running containers.
System sizing
Lite avoids the AI image pulls and model services. Full starts both ghost-inference and ghost-llamacpp and needs additional disk and memory. The served Full template currently sets memory ceilings of 12G for inference and 6G for the model service, with four-CPU limits by default. These are configured limits, not measured minimum requirements or guaranteed memory use. Inspect docker compose config and your Docker resource allocation before starting Full.
A timed clean-machine install, total download size, and peak-memory measurement are still needed before publishing reliable hardware or setup-time recommendations. Choose Lite for the initial record/replay workflow.
Disabling generation within an AI service does not remove its image or container from Full. Select Lite to omit both AI services entirely. Optional AI settings in a Pro/Team .env are unused by Lite; keeping them lets you reuse the same private environment if you later choose Full.
Ports
The generated stack publishes the HTTP proxy, dashboard, and control API ports. TLS interception also needs a published 8443 mapping; check your downloaded file, Postgres and AI services remain on internal Docker networks.
| Port | Service | What it is |
|---|---|---|
8080 | ghost-proxy | Plain-HTTP proxy. Point your application here instead of its upstream URL. This is the only port your app needs. |
8443 | ghost-proxy | TLS-MITM listener. Enable ENABLE_TLS_INTERCEPTION on the proxy and ensure its Compose ports publish 8443. The port is unused while interception is disabled. |
3000 | ghost-web | Operator dashboard. Watch traffic, manage services, switch modes. |
8000 | ghost-web | Control plane API. Browser calls and curl scripts hit it here (the /v1/* endpoints). |
On HTTPS, fetch and trust the proxy's MITM CA once — it serves the cert at GET /ca.crt on port 8080 (which returns 503 while interception is off, so flip the knob first):
curl http://localhost:8080/ca.crt > gostly-ca.crt # then add gostly-ca.crt to your client / OS trust store
See Proxy Setup → TLS for the per-OS trust-install steps.
.env setup
For a fresh installation, use the environment template downloaded with your Compose file. Keep it private and set your upstream, license, and local administrator credentials. Preserve its generated database passwords and stable tenant ID. Do not copy a fresh template over an existing deployment:
# Save the downloaded environment template as .env chmod 600 .env docker compose config --quiet
| Variable | What to set |
|---|---|
GOSTLY_LICENSE_KEY | The key from your dashboard. Gates tier-specific capabilities. Same key on the proxy and the control plane. |
BACKEND_URL | The upstream the proxy forwards to in LEARN mode and falls back to in PASSTHROUGH. Any reachable HTTP endpoint. |
POSTGRES_PASSWORD / GOSTLY_APP_DB_PASSWORD / GOSTLY_SERVICE_DB_PASSWORD | Keep all three generated database credentials. They must be distinct. Preserve existing values during upgrades; do not replace them with a fresh template. |
GOSTLY_ADMIN_EMAIL / GOSTLY_ADMIN_PASSWORD | Set private credentials for the local operator dashboard before its first boot. Keep GOSTLY_AUTH_MODE=password. |
GHOST_API_KEY | Optional shared service-authentication override. If configured, pass the same private value to both ghost-web and ghost-proxy and use it in the X-API-Key header for API scripts. See the setup below. |
Service authentication
If you use a private GHOST_API_KEY override, add the same environment reference under both services in the downloaded Compose file. A value in .env alone is not injected automatically. These entries extend your existing services; retain their other settings:
services:
ghost-web:
environment:
GHOST_API_KEY: ${GHOST_API_KEY:?Set a private shared key in .env}
ghost-proxy:
environment:
GHOST_API_KEY: ${GHOST_API_KEY:?Set a private shared key in .env}After changing this key, recreate both services together and confirm their configuration synchronization succeeds without authentication errors. Keep password login enabled; use the same key in the X-API-Keyheader for API requests. Never put its value in a shared transcript.
docker compose up -d --force-recreate ghost-web ghost-proxy
For Full, these variables are referenced by the served Compose file:
INFERENCE_CPU_LIMIT=4 # choose within Docker's available CPU allocation INFERENCE_NUM_THREADS=4 # inference BLAS threads LLAMACPP_CPU_LIMIT=4 # local model service CPU ceiling LLAMACPP_MEM_LIMIT=6G # local model service memory ceiling ENABLE_RAG=true # inference retrieval
The inference memory ceiling is currently 12G in the Compose file itself; setting INFERENCE_MEM_LIMIT in .env does not override that literal value. These AI settings do not start AI containers in Lite. Preserve the generated GOSTLY_TENANT_ID; do not replace it while updating an existing installation. TLS interception requires explicit proxy environment and port changes described above.
Single-tenant per deployment
Each self-hosted stack is a single tenant. A fresh platform-generated install pins GOSTLY_TENANT_ID to its organization UUID. Manual installs must choose one stable value before persisting data. Isolation comes from the deployment boundary itself: one stack, one tenant, one customer's data on that customer's volume. Per-tenant row-level-security policies are defined in the schema as defense-in-depth, but in the shipped single-tenant configuration the isolation is the deployment boundary, not engine-enforced row filtering. See Configuration for the full env-var reference.
License-key rotation without losing tenant identity
Existing raw-key deployments may store data under a tenant derived from the old key. Before rotating that key—or before adding the first key to an existing keyless deployment—capture the tenant currently resolved by ghost-web. Never replace it with a newly displayed organization UUID.
# Run while the old key (or keyless deployment) is still active
docker compose exec -T -w /app/api ghost-web python3 -c \
'from deps import _resolve_tenant_id; print(_resolve_tenant_id())'
# Put the printed value in .env and ensure ghost-web.environment contains:
GOSTLY_TENANT_ID=<captured-value>
GOSTLY_TENANT_ID: ${GOSTLY_TENANT_ID:-}
# Recreate under the old configuration, then verify injection and resolution
docker compose up -d --force-recreate ghost-web
docker compose exec -T ghost-web python3 -c \
'import os; print(os.environ.get("GOSTLY_TENANT_ID", "<unset>"))'
docker compose exec -T -w /app/api ghost-web python3 -c \
'from deps import _resolve_tenant_id; print(_resolve_tenant_id())'
# Only after both outputs match the captured value: change/add the key
docker compose up -d --force-recreate ghost-web ghost-proxyRecreating only the web container leaves the proxy using the revoked old key. Preserve all existing database passwords and the exact tenant pin during every upgrade.
On secrets and the data directory
Keep .env out of version control. The shared ./data bind-mount holds recorded traffic, the mock library, and license_cache.json (your license JWT) — review before committing any of it. The Quick Start has safe .gitignore defaults. Credential headers are stripped to a non-overridable 16-header floor before anything is written to disk; PII in bodies is kept verbatim only on the local replay library and scrubbed out of the Postgres store and any export.
Pulling the images
The licensed images live in a private registry. From your dashboard, click Get registry token under Quick Start to generate a login command. The token is valid for 12 hours; refresh it any time.
# Use the registry host and temporary token from your account dashboard. # Read the token from a private file, then remove that file when finished. docker login -u AWS --password-stdin <your-registry-host> < registry-token.txt # Then pull and start the stack docker compose pull docker compose up -d
The dashboard also generates a docker-compose.yml pre-configured for your plan — download it with the matching environment template. Lite includes ghost-proxy, ghost-web,ghost-postgres, and ghost-migrate. Full adds AI services. Both require an active entitlement.
Keep the server-selected image digests
The downloaded Compose file pins Gostly images to immutable release digests (@sha256:…). Preserve those references; do not replace them with :latest or a guessed release tag. The server selects one complete image set, including the same image for the web service and database migration.
First boot
Run docker compose ps -a and confirm thatghost-migrate exited successfully and the serving containers are ready. Open http://localhost:3000 and sign in with your local administrator credentials. Register a test service with an upstream reachable from the proxy container and a host or path rule matching your client request. Wait for the service configuration to reach the proxy before sending traffic; a healthy process is not proof of capture readiness.
Select LEARN and send one authorized test request through port 8080. Confirm the expected response, an upstream request, and capture under the registered service. Resolve any agent_not_ready, missing-upstream, or authentication error before continuing. Choose Build & switch to MOCK in the service's dashboard. This processes the captured traffic and switches that service to MOCK as part of the same transition. Wait for completion with processed records and no error, then confirm the service is in MOCK and repeat the request: the response should match without another upstream call. For durable replay evidence, repeat after restarting only the test proxy.
To skip pointing at a real upstream and start with a seed instead, drag a HAR, Postman collection, or OpenAPI spec onto the dashboard — it posts to the cold-start importer:
POST /v1/seed/har # also: /v1/seed/postman, /v1/seed/openapi
The inference container's first /generate call after startup may briefly return 503 while the model loads (only relevant when generation is enabled). From there, drive the LEARN → MOCK pipeline as described in Quick Start.
What you can record & replay
Gostly records and replays HTTP and HTTPS (HTTP/1.1 and HTTP/2 over TLS). WebSocket frames are captured for observability only — they are not replayed. There is no gRPC, async-messaging, or database mocking today (roadmap). Webhook traffic is captured automatically; replay is operator-triggered through the control-plane API, not auto-fired by the proxy.
Metrics & health
Each service exposes a /health endpoint used by the compose healthchecks. The proxy also exports Prometheus metrics at /metrics for scraping into your own monitoring:
ghost_requests_total{match_type}Request counter, one increment per match-path outcome (exact, smart_swap, session_verbatim, generated_cached, miss, …).
ghost_mock_library_sizeGauge of the current mock-library size.
ghost_io_errors_total{operation}Disk-sink open/write failures, labelled by operation.
axum_http_requests_total / _durationHTTP rate and latency for the proxy's own endpoints.
gostly_tls_*The TLS-MITM subsystem family — ALPN negotiation, cert-cache hit/miss/eviction, and listener state.
Next steps
Quick Start →
Record traffic, build a library, and verify replay.
Configuration Reference →
Every environment variable, the redaction floor, scrub rules, and feature flags by tier.
How It Works →
The four modes and the match cascade — why AI is the last resort, never the hot path.
Proxy Setup →
Multiple upstreams, TLS interception, CI integration, and chaos injection.