Environment Reference
The configuration variables a self-hosted Solana Developer Platform reads from .env.
The self-hosted stack reads its configuration from a single .env file next to
compose.yml. The configurator is the
authoritative source of the field list, defaults, and validation — it always
matches the release you installed. This page explains how the configuration is
organized and the variables you are most likely to set by hand.
The configurator groups variables into sections:
| Section | What it covers |
|---|---|
| Basic | Core runtime — environment, deployment mode, Transactional Email sender and Resend key. |
| Database | Bundled Postgres or an external database. |
| Cache | Bundled Redis or an external cache. |
| Solana RPC | Network and RPC endpoint. |
| Authentication (Clerk) | Required Clerk keys and JWT settings. |
| Signing provider | Which signer(s) to enable and their credentials. |
| Fee payment | How transaction fees are paid. |
| Secrets | App secrets, generated locally. |
| Advanced | Image source, ports, and internal service URLs. |
Required variables
These must be set or the stack will refuse to start:
| Variable | Description |
|---|---|
POSTGRES_PASSWORD | Password for the bundled Postgres. Always required — the bundled postgres service starts even when the API points at an external DATABASE_URL. |
API_KEY_PEPPER | Server-side pepper for API key hashing. Generate with openssl rand -hex 32. |
CUSTODY_ENCRYPTION_KEY | Encryption key for custody material at rest. Generate with openssl rand -base64 32. |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | Clerk publishable key for the web app. |
CLERK_SECRET_KEY | Clerk secret key for the API. |
CLERK_ISSUER | Clerk issuer URL used to validate tokens. |
SOLANA_RPC_URL | Solana RPC endpoint the API calls. |
SIGNING_PROVIDER | The default signing provider. Each non-local provider adds its own required credentials. |
The configurator generates API_KEY_PEPPER and CUSTODY_ENCRYPTION_KEY for you
and can auto-generate POSTGRES_PASSWORD.
Transactional Email
SDP-owned Transactional Email uses Resend. Set EMAIL_FROM to the sender address
and RESEND_API_KEY to the Resend API key before enabling product flows that send
email. Organization member invitation emails are handled by Clerk and do not use
these settings.
Database
In the configurator, DATABASE_MODE chooses between the bundled Postgres and an
external database. It is a generation-time selector and is not written to .env.
For the bundled database, set POSTGRES_DB, POSTGRES_USER, and
POSTGRES_PASSWORD; the API and migration services build their connection string
from them. To use an external database, set DATABASE_URL to your own
postgresql://… string and the API and migrations connect there instead. Note
that compose.yml always starts the bundled postgres container — with an
external DATABASE_URL it simply goes unused, and POSTGRES_PASSWORD is still
required for it to start.
The configurator hides POSTGRES_PASSWORD once you select an external database
but still emits an auto-generated value for it, since the bundled postgres
container needs one to start even when nothing connects to it.
Cache
Like DATABASE_MODE, CACHE_MODE is a configurator-only selector and is not
written to .env. To use an external cache, set REDIS_URL to your own
redis://… endpoint; the bundled redis container still starts but goes unused.
Signing providers
SIGNING_PROVIDER is the default signer written to .env. Supported values are
local, fireblocks, privy, coinbase_cdp, para, turnkey, and utila.
The configurator also tracks a SIGNING_PROVIDERS selection to decide which
fields to show, but that key is configurator-only and is not written to .env.
Each non-local provider requires its own credentials — for example Fireblocks
needs an API key, secret, and vault ID — and the configurator only prompts for
the providers you enable.
For provider-managed co-signer runtimes that live outside the default stack, see External co-signers.
Advanced
| Variable | Default | Description |
|---|---|---|
SDP_IMAGE_REGISTRY | ghcr.io/solana-foundation/sdp | Registry the service images are pulled from. |
SDP_VERSION | latest | Image tag for every SDP service. Pin this to a release tag in production. |
SDP_API_PORT | 8787 | Host port for the API. |
SDP_WEB_PORT | 3000 | Host port for the dashboard. |
SDP_DOCS_PORT | 3001 | Host port for these docs. |
SDP_API_BASE_URL defaults to the in-network service name http://sdp-api:8787
for server-to-server calls. The browser-facing NEXT_PUBLIC_* URLs default to
localhost (for example http://localhost:8787 and http://localhost:3000) and
need changing when you put the services behind your own domains or ingress.