Self-hosting
Arkyc runs anywhere Node, Postgres, and an S3-compatible store are available.
Local infrastructure
The bundled docker-compose.yml provides everything for development:
docker compose up -d| Service | Image | Port(s) | Credentials |
|---|---|---|---|
| PostgreSQL | postgres:16-alpine | 5432 | arkyc / arkyc, db arkyc |
| MinIO | minio/minio | 9000/9001 | arkyc / arkyc-secret |
| Redis | redis:7-alpine | 6379 | — |
MinIO's console is on 9001; create the bucket referenced by AWS_BUCKET and point the s3 disk at http://localhost:9000.
Migrations & seed
pnpm --filter @arkyc/api exec ark migrate # apply all migrations
pnpm --filter @arkyc/api exec ark migrate:rollback # roll back the last batch
pnpm --filter @arkyc/api exec ark seed # permissions + roles + demo dataark seed runs the permission/role sync (idempotent) and the demo-tenant seeder.
Running the services
# API
pnpm --filter @arkyc/api build && pnpm --filter @arkyc/api start # or: ark dev
# Dashboard (static SPA)
pnpm --filter @arkyc/dashboard build # outputs dist/, serve behind any static hostPut the dashboard behind the same origin as the API (or set its VITE_*_API_URL to the API's public URL) and ensure each project's allowed origins include the dashboard/widget host.
Queue workers
For production, use the durable queue and run workers as long-lived processes:
QUEUE_CONNECTION=database # in apps/api/.envpnpm --filter @arkyc/api exec ark queue:work database --queue=ocr
pnpm --filter @arkyc/api exec ark queue:work database --queue=biometric
pnpm --filter @arkyc/api exec ark queue:work database --queue=webhookRun the roles as separate processes (use redis in place of database for the redis connection). --once processes a single job and exits; --stop-when-empty drains and exits (handy for cron/CI). Retries use each job's tries/backoff; exhausted jobs run their failed hook. The database driver needs the jobs table — ark migrate creates it.
Production checklist
- Strong
JWT_SECRETandTWO_FACTOR_ENCRYPTION_KEY; never reuse the examples. DATABASE_URLto a managed Postgres; runark migrateon deploy.FILESYSTEM_DISK=s3(orgcs) with private buckets and short signed-URL TTLs.QUEUE_CONNECTION=database(orredis) with workers supervised.- Real provider endpoints via
*_DRIVER=external(see Provider drivers). - Per-project allowed origins and webhook endpoints configured.
- TLS in front of the API; restrict the dashboard origin.
Hardening (rate limits, retention jobs, encryption-at-rest for webhook secrets, observability) is tracked as a dedicated release phase.
