Deploy with Docker Compose
Start the API, the console, the documentation, PostgreSQL and Redis with Docker Compose, put them behind TLS and connect sign-in.
Do this once to bring up your own deployment from a clone of the repository. The compose file starts five containers: the API, the console, this documentation, PostgreSQL 18 and Redis 7.
Before you start#
You need:
- Docker with Compose v2.
- A public HTTPS hostname, such as
consent.example.in. Customer sites load the banner from it and send consent to it. - A reverse proxy that you run, to end TLS.
- The PIEDAP IAM service. The console has no accounts of its own.
- A safe place to keep secrets. Some of them can never change.
- Outbound HTTPS from the API to webhook endpoints, scanned sites and
vendor-list.consensu.org.
Start the stack#
-
Create the secrets. Store each one in your secret manager.
Shell openssl rand -hex 16 # DB_PASSWORD openssl rand -hex 16 # REDIS_PASSWORD openssl rand -hex 32 # ENCRYPTION_KEY openssl rand -hex 32 # SUBJECT_HASH_PEPPER openssl rand -hex 32 # the secret half of EVIDENCE_CHAIN_KEYS openssl rand -base64 32 # RECEIPT_SIGNING_PRIVATE_KEY openssl rand -hex 32 # RECEIPT_SIGNING_KEY openssl rand -hex 32 # PLATFORM_API_KEY openssl rand -hex 32 # METRICS_TOKEN -
Write them to a file named
.envnext todocker-compose.yml. Add your public address and the values from IAM. Keep the file out of version control..envConfig DB_PASSWORD=... REDIS_PASSWORD=... ENCRYPTION_KEY=... SUBJECT_HASH_PEPPER=... EVIDENCE_CHAIN_KEYS=2026a:... EVIDENCE_CHAIN_ACTIVE_KEY=2026a RECEIPT_SIGNING_PRIVATE_KEY=... RECEIPT_SIGNING_KEY=... PLATFORM_API_KEY=... METRICS_TOKEN=... PUBLIC_API_URL=https://consent.example.in UI_URL=https://consent.example.in LOGIN_COOKIE=... LOGIN_SECRET=... VERIFY_LOGIN_COOKIE=... REFRESH_COOKIE=... COOKIE_DOMAIN=... BASE_IAM_URL=... IAM_LOGIN_URL=... SERVER_SIDE_API_KEY=... -
Build the images and start the stack.
Shell docker compose up -d --build -
Check that the API is up and reaches the database.
Shell curl -s http://127.0.0.1:8080/health
The answer is 200 with "status": "ok" and "database": "up". On first start the API builds the schema in an empty database.
Set every key before the first consent
An empty SUBJECT_HASH_PEPPER, EVIDENCE_CHAIN_KEYS or RECEIPT_SIGNING_PRIVATE_KEY is taken from another secret. A different value later breaks search and proof for older records. See values that must never change.
Without PUBLIC_API_URL, install snippets, links and receipts point at localhost.
Put it behind TLS#
End TLS in your own proxy and send every request to the console on port 8080. The console passes /api/, /sdk/ and /health on to the API, so browsers see one origin.
server {
listen 443 ssl;
server_name consent.example.in;
ssl_certificate /etc/ssl/consent.example.in/fullchain.pem;
ssl_certificate_key /etc/ssl/consent.example.in/privkey.pem;
client_max_body_size 200m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Check three things:
- Client addresses. If your proxy reaches the stack from a public address, set
TRUST_PROXY. - API reference. The API serves
/api/docswithout sign-in. Block that path if you do not want it public. - Imports. A property import can be 200 MB. Add
client_max_body_size 200m;toweb/nginx.conftoo, or large files fail with413.
Less common proxy settings
- Metrics. The console does not forward
/metrics. Scrape port 3003 of the API. - Country. If your CDN sets a country header such as
CF-IPCountry, the API uses it. - A CDN for the runtime. Published runtime files never change, so a CDN may serve them. Set
RUNTIME_CDN_URLso install snippets point at it. - Framing. The console allows framing only by itself and PIEDAP domains. To embed it elsewhere, change the
frame-ancestorsheader inweb/nginx.confand in the API.
Connect sign-in#
Users, organisations and projects all come from IAM. There is no admin account to create.
- IAM writes each session to Redis and the API reads it there. Both must use the same Redis.
LOGIN_COOKIEandLOGIN_SECRETmust match IAM. If they differ, every console request gets403.COOKIE_DOMAINmust match IAM and cover the console's hostname.
The compose file points the API at its own Redis and passes only the variables it lists. To change either, add an override file as shown under the compose file.
The Platform area needs five permissions in IAM, under the Consent application and its PlatformServices module. To list the ones IAM lacks, run the script below with an IAM admin token; add --apply to create them. Then give them to the platform roles in IAM.
IAM_URL=https://iam.example.in IAM_TOKEN=<admin token> \
CONSENT_APPLICATION_ID=<uuid> PLATFORM_MODULE_ID=<uuid> \
node scripts/register-platform-permissions.mjsCheck the result#
Open https://consent.example.in and sign in. The console opens in the project IAM gives you. New keys are test keys until you approve them.