Backend for Gardenia — a gardening companion that keeps your green spaces organized, shared, and easy to look after. DDD + CQRS + Hexagonal architecture on NestJS, TypeORM/PostgreSQL, JWT + OAuth (Google/GitHub/Apple) auth with multi-tenant spaces, optional Kafka event forwarding, REST (Swagger) + GraphQL (Apollo) transports, OpenTelemetry traces + metrics + logs, and an MCP endpoint.
# OAUTH_TOKEN_ENC_KEY must be a 32-byte base64 key, e.g. `openssl rand -base64 32`
docker run -p 3000:3000 \
-e DATABASE_HOST=host.docker.internal \
-e DATABASE_PORT=5432 \
-e DATABASE_USERNAME=gardenia \
-e DATABASE_PASSWORD=secret \
-e DATABASE_DATABASE=gardenia_db \
-e JWT_SECRET=change_me_in_production \
-e OAUTH_TOKEN_ENC_KEY=change_me_in_production \
-e OAUTH_STATE_SECRET=change_me_in_production \
sisqueslabs/gardenia-api:latest
The container needs a reachable PostgreSQL instance — it does not bundle one.
| Port | Purpose |
|---|---|
3000 | HTTP — REST (/api/*), GraphQL (/graphql), Swagger docs, health, MCP (see routes below) |
| Path | Purpose |
|---|---|
GET /api/health/live | Liveness probe |
GET /api/health/ready | Readiness probe (checks DB connectivity) |
POST /api/mcp | MCP (Model Context Protocol) endpoint — auth required, exposes every bounded context's commands/queries as tools |
POST /graphql | GraphQL (Apollo) |
GET /docs | Swagger UI |
Traces, metrics, and logs are pushed via OTLP to a collector (see
OTEL_EXPORTER_OTLP_ENDPOINT below) — there is no in-process /metrics
endpoint to scrape. Logs still go to stdout/file regardless.
| Variable | Default | Required | Notes |
|---|---|---|---|
PORT | 3000 | No | HTTP port |
NODE_ENV | production | No | |
DATABASE_DRIVER | postgres | No | Only postgres is supported |
DATABASE_HOST | — | Yes | |
DATABASE_PORT | 5432 | No | |
DATABASE_USERNAME | — | Yes | |
DATABASE_PASSWORD | — | Yes | |
DATABASE_DATABASE | — | Yes | |
JWT_SECRET | — | Yes | Signs access tokens |
JWT_EXPIRES_IN | 7d | No | |
REFRESH_TOKEN_TTL_DAYS | 30 | No | |
OAUTH_TOKEN_ENC_KEY | — | Yes | 32-byte base64 key (AES-256-GCM) encrypting stored OAuth provider tokens |
OAUTH_STATE_SECRET | — | Yes | Signs the OAuth state JWT (CSRF protection) |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET / GOOGLE_CALLBACK_URL | — | Only if Google sign-in is used | |
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET / GITHUB_CALLBACK_URL | — | Only if GitHub sign-in is used | |
APPLE_CLIENT_ID / APPLE_TEAM_ID / APPLE_KEY_ID / APPLE_PRIVATE_KEY / APPLE_CALLBACK_URL | — | Only if Sign in with Apple is used | |
QR_BASE_URL | http://localhost:3000 | No | Base URL embedded in plant QR deep links |
CORS_ORIGINS | — | Production only | Comma-separated allowed origins |
OTEL_EXPORTER_OTLP_ENDPOINT | — | No | OpenTelemetry traces+metrics+logs disabled when unset |
KAFKA_ENABLED | false | No | Domain event forwarding; app boots fine without a broker when disabled |
KAFKA_BROKERS | — | If Kafka enabled | Comma-separated broker list |
FILES_STORAGE_DRIVER | database | No | database or s3; S3 vars only required when set to s3 |
See the project's .env.example for the full list, including per-provider
OAuth variables and S3 file-storage settings.
latest — most recent stable release (main branch)x.y.z — specific stable releasex.y.z-alpha.n / -beta.n / -rc.n — prereleases from develop/stagingContent type
Image
Digest
sha256:c37edbe6b…
Size
125.9 MB
Last updated
about 2 months ago
docker pull sisqueslabs/gardenia-api