If you haven't configured your environment variables yet, review the Configuration page first.
Complete instructions for deploying OFFER-HUB Orchestrator on your own infrastructure using Docker.
Run OFFER-HUB Orchestrator on your own server with full control over data, uptime, and configuration. This guide covers everything from initial setup to ongoing maintenance using Docker.
If you haven't configured your environment variables yet, review the Configuration page first.
Before you begin, make sure your host machine meets the following requirements:
Verify that Docker is installed and running:
docker --version && docker compose versionOn older installations you may need to use docker-compose (with a hyphen) instead of docker compose.
The repository's root Compose file starts only the infrastructure dependencies. The API is built and run from the repository separately:
The API runs alongside PostgreSQL and Redis, and connects to the Stellar network.
The topology is verified against the Orchestrator root docker-compose.yml, apps/api/src/main.ts, and apps/api/src/modules/webhooks/webhooks.controller.ts: Compose provides PostgreSQL and Redis while the API hosts both REST endpoints and inbound webhook handling.
Create a deployment directory:
mkdir offer-hub-deploy && cd offer-hub-deployYour directory will contain:
Create a docker-compose.yml file:
This Compose file provides PostgreSQL and Redis only. Run the API from the repository with the commands below, or deploy it with a build-based platform configuration.
If you prefer managed databases, remove postgres and redis services and update the environment:
Clone the source repository, install its dependencies, and run the API directly. No published application images are required.
git clone https://github.com/OFFER-HUB/OFFER-HUB.git && cd OFFER-HUBnpm ci && npm run build && npm start -w @offerhub/apiCreate a .env file in the same directory as your docker-compose.yml.
| Variable | Description |
|---|---|
NODE_ENV | Runtime environment: development, staging, production |
DATABASE_URL | PostgreSQL connection string |
REDIS_URL | Redis connection string |
OFFERHUB_MASTER_KEY | Master key for creating API keys |
WALLET_ENCRYPTION_KEY | 64 hex chars - AES-256-GCM key for wallet encryption |
TRUSTLESS_API_KEY | Trustless Work API key for escrow |
PLATFORM_USER_ID | Platform user ID for escrow operations |
PUBLIC_BASE_URL | Your Orchestrator's public URL |
| Variable | Default | Description |
|---|---|---|
PORT | 4000 | HTTP server port |
LOG_LEVEL | info | Logging level: debug, info, warn, error |
PAYMENT_PROVIDER | crypto | Payment mode for the PaymentProvider strategy. Only crypto is implemented — airtm throws at startup |
STELLAR_NETWORK | testnet | Stellar network: testnet or mainnet |
STELLAR_USDC_ISSUER | Testnet issuer | USDC asset issuer address |
Never commit your .env file to version control. Treat every value as a secret.
Once your .env file is ready, bring everything up in detached mode:
docker compose up -dWatch the logs to confirm all services start cleanly:
docker compose logs -fApply Prisma migrations before the first launch (or after pulling a new source revision):
npm run prisma:generate && npx prisma migrate deploy --schema packages/database/prisma/schema.prismaTo understand exactly what gets created — every table, field, and relationship — see the Data Model reference.
Always back up your database before running migrations in production.
Make sure NODE_ENV=production is set in your .env file. This enables:
For production deployments you should terminate TLS at your hosting platform or an external reverse proxy. The dependency Compose file does not include an application or proxy service.
Example nginx.conf:
Let's Encrypt with Certbot is the easiest way to obtain free TLS certificates.
The Orchestrator exposes a /health endpoint that returns the current service status. The Docker Compose file already configures a health check against it.
curl http://localhost:4000/healthExpected response:
Docker reports health status directly:
docker compose psA healthy deployment shows (healthy) next to each service. If a service is (unhealthy), inspect its logs:
docker compose logs orchestrator --tail 50/health.200 responses or response times above 2 seconds.The Orchestrator uses BullMQ for background job processing:
| Queue | Purpose |
|---|---|
webhooks | Process inbound provider webhooks (AirTM, Trustless Work) |
reconciliation | Periodic sync jobs with external providers |
notifications | Send notifications (email, push, etc.) |
dead-letter-queue | Jobs that exhausted all retry attempts |
Monitor job queues:
git pull --ff-onlydocker compose up -dThis starts or updates the PostgreSQL and Redis dependencies. Rebuild and restart the API separately.
The recommended update procedure:
If something goes wrong, roll back the source checkout to a known-good commit:
Then restart the API:
npm start -w @offerhub/apiBefore going to production, verify:
NODE_ENV=production is setOFFERHUB_MASTER_KEY is a strong, unique valueWALLET_ENCRYPTION_KEY is backed up securely?sslmode=require)rediss://)AIRTM_WEBHOOK_SECRET / TRUSTLESS_WEBHOOK_SECRET)