Install on Docker
This guide brings up the EDK enterprise stack on Docker Compose behind the single-port Traefik gateway, using the published nexus.sphereon.com/edk-docker/enterprise-* images and the Docker Compose files from the Enterprise Development Kit Deployment repository. Customer deployments use the repository's compose/ and scripts/ directories.
The result matches the deployment architecture: one external port on 443, the operator host and tenant hosts on TLS certificates valid for those hosts, and the gateway routing by host and path. The same steps work for local evaluation and for a Docker-based environment, because the gateway implements the same contract as the Kubernetes and cloud paths. This Compose path is for evaluation; for a cluster use the Kubernetes install.
Pull the Published Images
The service images are published as nexus.sphereon.com/edk-docker/enterprise-platform, nexus.sphereon.com/edk-docker/enterprise-tenant-kms, nexus.sphereon.com/edk-docker/enterprise-did, nexus.sphereon.com/edk-docker/enterprise-tenant-as, nexus.sphereon.com/edk-docker/enterprise-issuer, and nexus.sphereon.com/edk-docker/enterprise-verifier; the admin UI uses nexus.sphereon.com/edk-docker/admin-console when enabled. The deployment repository Compose files reference these tags, so Docker pulls them on first bring-up. See Images and Helm chart for the registry coordinates and the pull secret.
The Traefik Gateway Overlay
The deployment repository ships a base Compose file for the enterprise services and admin console, plus a gateway overlay that adds Traefik in front of them, under compose/.
Traefik is the Docker equivalent of the Kubernetes Cilium Gateway. Its static configuration terminates TLS on 443, redirects 80 to 443, and loads a hot-reloaded dynamic routing table. The dynamic configuration matches the operator host and the tenant wildcard host and forwards by path to each service, with passHostHeader: true so the inbound Host reaches the backend unchanged. Traefik sets X-Forwarded-Proto on the TLS entrypoint and overwrites untrusted client X-Forwarded-* values, which is exactly what the services rely on for https scheme detection. That satisfies the gateway contract.
Local Wildcard DNS
The base domain for local runs is saas.localtest.me. The localtest.me domain and all of its subdomains resolve to 127.0.0.1 with no host-file edits and no local DNS server. So https://platform.saas.localtest.me and https://<tenant>.saas.localtest.me both reach the gateway on your machine.
The default deployment provisions three tenants at acme.saas.localtest.me, globex.saas.localtest.me, and initech.saas.localtest.me, plus the operator host platform.saas.localtest.me.
Local Wildcard TLS Certificate
The gateway terminates TLS, so it needs a certificate valid for *.saas.localtest.me and platform.saas.localtest.me. Generate it with the script in the deployment repository:
scripts/gen-local-wildcard-cert.sh
On Windows, run the PowerShell variant:
scripts\gen-local-wildcard-cert.ps1
The script writes to compose/gateway/certs/:
wildcard.crtandwildcard.key: the server certificate for*.saas.localtest.meand the platform host, mounted into Traefik.local-ca.crt: the local certificate authority. Trust this in your operating system, browser, and wallet.local-truststore.p12: a JVM truststore holding the CA, mounted into the service containers so they trust the gateway when they fetch per-tenant JWKS over TLS in development. The default password ischangeit.
If mkcert is installed, the script uses it and its CA is auto-trusted once you run mkcert -install. Otherwise it falls back to a self-signed OpenSSL CA that you trust manually. You can re-run the script at any time; it overwrites the certificate material.
Trust the Local CA
Browsers and wallets reject a certificate signed by an untrusted CA, so the local CA must be trusted before TLS connections succeed.
- With
mkcert, runmkcert -installonce. The browser then trusts the generated certificate. - Without
mkcert, importcompose/gateway/certs/local-ca.crtinto your operating system or browser trust store.
A real phone wallet on a separate device needs the same trust and public DNS; for that, see Local multi-domain development.
Run the Stack
Start the stack with the base Compose file and the gateway overlay from the deployment repository:
docker compose \
-f compose/docker-compose.yml \
-f compose/docker-compose.gateway.yml \
up -d
Compose pulls the six published nexus.sphereon.com/edk-docker/enterprise-* images, brings up the services, and starts Traefik on the single port. Generate the local wildcard certificate first if it is missing, as described above.
With the gateway overlay, all public traffic goes through 443 and the host-based routing described in the architecture takes effect. Without the overlay, the base Compose file runs the services on their individual container ports for direct testing.
Provide the deployment license during first-run setup, covered in Provisioning and onboarding and Platform onboarding.
For a real domain, replace the local certificate with a publicly trusted wildcard certificate for *.<base-domain> plus platform.<base-domain>, or configure individual certificates for every tenant host and the operator host. Because tenants are hosted as <tenant>.<base-domain>, wildcard TLS is the simplest production model. Let's Encrypt is supported; use DNS-01 validation for wildcard issuance.
Open the Platform
Once the stack reports healthy, open the operator host:
https://platform.saas.localtest.me
Complete first-run setup there: activate the license and create the first platform operator account. After that first run, sign in with that operator account at:
https://platform.saas.localtest.me/admin-console
The two onboarding paths, interactive and scripted, are covered in Provisioning and onboarding. The platform first-run flow itself is detailed in Platform onboarding.
Next Steps
- Provisioning and onboarding: onboard a platform with three fully deployed tenants.
- Local multi-domain development: expose the local stack to a real phone wallet.
- Install on Kubernetes (Cilium): the same contract on a cluster.