> For the complete documentation index, see [llms.txt](https://opencred.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://opencred.gitbook.io/docs/docker-image/docker.md).

# Docker overview

The OpenCred Docker image is the headless variant of the Desktop Client. It exposes an HTTP API for issuing and verifying W3C Verifiable Credentials and is intended for cloud deployments, on-prem servers, automation pipelines, and CI/CD integration.

## Important: OpenCred is not a hosted service

OpenCred is **not** a SaaS. There is no `api.opencred.com` to call. You deploy the Docker image into **your** infrastructure, you manage the signing key, and the credentials are produced inside your environment. NFH Trust Labs operates no hosted endpoints and never receives your credential data or your keys.

## Pages in this section

* [Deployment](/docs/docker-image/deployment.md) — `docker run`, `docker compose`, environment variables, volumes, persistent state
* [API reference](/docs/docker-image/api-reference.md) — HTTP endpoints exposed by your deployment
* [CLI reference](/docs/docker-image/cli-reference.md) — `opencred` command-line tool for offline operations
* [Verifying credentials](/docs/docker-image/verifying-credentials.md) — HTTP, CLI, library, and DeDi-backed verification surfaces
* [Cloud HSM](/docs/docker-image/cloud-hsm.md) — AWS KMS, Azure Key Vault, GCP Cloud KMS setup
* [Observability](/docs/docker-image/observability.md) — logging, metrics, health checks, structured output
* [OID4VCI](/docs/docker-image/oid4vci.md) — OpenID for Verifiable Credential Issuance (planned)

## Quick start

```bash
# 1. Pull the public image (no auth required)
docker pull ghcr.io/nfh-trust-labs/opencred/opencred-server:latest

# 2. Run with a mounted signing key
docker run -p 3100:3100 \
  -e OPENCRED_PORT=3100 \
  -e OPENCRED_API_KEY=your-secret-token \
  -e OPENCRED_KEY_PATH=/secrets/issuer-key.pem \
  -v /path/to/your/key.pem:/secrets/issuer-key.pem:ro \
  ghcr.io/nfh-trust-labs/opencred/opencred-server:latest

# 3. Verify it's running
curl http://localhost:3100/v1/health
```

> **Building from source instead?** See [Deployment → Build from source](/docs/docker-image/deployment.md#build-from-source).

A successful health check returns `200 OK`:

```json
{
  "status": "ok",
  "ready": true,
  "signingKeyLoaded": true,
  "dediConfigured": false,
  "timestamp": "2026-04-07T10:00:00.000Z"
}
```

If `signingKeyLoaded` is `false`, the server returns `503` and cannot issue credentials — see the [Deployment guide](/docs/docker-image/deployment.md) for the supported key sources.

## Providing a signing key

Your signing key stays in your infrastructure — it is loaded at startup and never transmitted.

**File-based** (default): Set `OPENCRED_KEY_PATH` to a PEM, JWK, PKCS#8, or PFX file. For PFX, also set `OPENCRED_KEY_PASSWORD`.

**Cloud HSM**: Set `OPENCRED_KMS_PROVIDER` to `aws`, `azure`, or `gcp` with the provider-specific variables. See [Cloud HSM](/docs/docker-image/cloud-hsm.md).

## Local development

```bash
# From the repo root
pnpm install
pnpm build

# Set environment variables
export OPENCRED_PORT=3100
export OPENCRED_KEY_PATH=/path/to/your/key.pem
export OPENCRED_DEV_MODE_NO_AUTH=true  # local dev only; never use in production

# Start the dev server
cd apps/server
pnpm dev
```

## Architecture

The Docker image is built from `apps/server/Dockerfile` and runs `apps/server/dist/index.js`:

| Component       | Path                                     | Responsibility                                                                                                                                                                                                                 |
| --------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| HTTP server     | `apps/server/src/index.ts`               | Hono app, route registration, error handler                                                                                                                                                                                    |
| Configuration   | `apps/server/src/config.ts`              | Zod-validated environment variables                                                                                                                                                                                            |
| Logger          | `apps/server/src/logger.ts`              | pino structured logging to stdout                                                                                                                                                                                              |
| Auth middleware | `apps/server/src/middleware/auth.ts`     | Required Bearer token check (fail-closed; see [API reference → Authentication](/docs/docker-image/api-reference.md#authentication))                                                                                            |
| Routes          | `apps/server/src/routes/*.ts`            | `/health`, `/keys`, `/schemas`, `/credentials/issue`, `/credentials/verify`, `/credentials/batch`, `/credentials/revocation-hash`, `/credentials/revoke`, `/credentials/revocation-status`, `/credentials/package`, `/metrics` |
| Signer          | `apps/server/src/signing/key-manager.ts` | Loads the active signer from a file or Cloud HSM                                                                                                                                                                               |
| CLI             | `apps/server/src/cli.ts`                 | `opencred` command for one-off operations                                                                                                                                                                                      |

The server consumes the same `@opencred/*` packages used by the Desktop Client, so issuance and verification logic are shared.

## Security defaults

The Docker image is built and configured with security defaults that follow the [seven OpenCred invariants](/docs/security/invariants.md):

* Runs as the non-root `node` user
* Multi-stage build with pinned base image digests for reproducibility
* No secrets baked into image layers — keys and tokens are mounted at runtime
* `docker-compose.yml` enables `read_only: true`, drops all capabilities, adds only `NET_BIND_SERVICE`, and sets `no-new-privileges: true`
* JSON-LD contexts are bundled at build time and never fetched at runtime
* The pino logger writes to stdout in JSON; key material is never logged

See [Security](/docs/security/security.md) for the full model.

## Related documentation

* [Deployment](/docs/docker-image/deployment.md)
* [API reference](/docs/docker-image/api-reference.md)
* [CLI reference](/docs/docker-image/cli-reference.md)
* [Cloud HSM](/docs/docker-image/cloud-hsm.md)
* [Observability](/docs/docker-image/observability.md)
* [Security model](/docs/security/security.md)
* [Concepts: Verifiable Credentials](/docs/concepts/verifiable-credentials.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://opencred.gitbook.io/docs/docker-image/docker.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
