CloudLearn web portal — auth, licensing, payments, dashboard, docs
1.0K
The Vyomi web portal — runs the marketing site, sign-in / OAuth, pricing & checkout (Razorpay + Stripe), license issuance & dashboard, and bundled API docs for the Vyomi appliance.
| Tag | What it is | When to use |
|---|---|---|
latest | Most recent stable release (pointer) | Quick docker run; don't use in production |
<X.Y.Z> | Pinned, immutable stable release | Production — always pin a version |
<X.Y.Z>-rc1, <X.Y.Z>-beta.2, … | Pre-release (RC, beta) | Staging / pre-release validation |
edge / sha-<abc1234> | Manual sanity builds (workflow_dispatch only) | Staging / debugging a specific commit |
Pre-release rule: any tag with a SemVer pre-release suffix (
v1.2.0-rc1,v1.2.0-beta.3) publishes the version tag only — it never moves:latest. Users pinned to:latestwon't silently land on an RC.Release-driven CI: images are only built when a
v*.*.*git tag is pushed. Daily commits tomaindo NOT produce new images — pin to a version when you deploy.
All tags are multi-arch: linux/amd64 + linux/arm64.
docker run -d --name cloudlearn-portal \
-p 8001:8000 \
-e DATABASE_URL='postgresql+psycopg://user:[email protected]:5432/cloudlearn' \
-e SESSION_SECRET="$(openssl rand -hex 32)" \
-e ADMIN_TOKEN="$(openssl rand -hex 32)" \
-e LICENSE_ISSUER='https://portal.your-domain.io' \
-v portal-keys:/app/keys \
vyomi/portal:latest
open http://localhost:8001
services:
cloudlearn-portal:
image: vyomi/portal:latest
ports: ["8001:8000"]
environment:
DATABASE_URL: postgresql+psycopg://user:[email protected]:5432/cloudlearn
SESSION_SECRET: ${SESSION_SECRET}
ADMIN_TOKEN: ${ADMIN_TOKEN}
LICENSE_ISSUER: https://portal.your-domain.io
PAYMENT_PROVIDER: razorpay
RAZORPAY_KEY_ID: ${RAZORPAY_KEY_ID}
RAZORPAY_KEY_SECRET: ${RAZORPAY_KEY_SECRET}
volumes:
- portal-keys:/app/keys
restart: unless-stopped
volumes:
portal-keys:
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | yes | Managed Postgres URL — Neon / Render / Supabase / RDS. postgresql:// and postgres:// aliases are auto-rewritten to use the psycopg v3 driver. |
SESSION_SECRET | yes | Cookie signing key. Generate: openssl rand -hex 32 |
ADMIN_TOKEN | yes | Bearer token for /api/license/issue admin endpoint. |
LICENSE_ISSUER | yes | Public URL of THIS portal — used as the JWT iss claim and in /.well-known/jwks.json. |
| Variable | Description |
|---|---|
PAYMENT_PROVIDER | razorpay (INR), stripe (USD), or demo (no-money local dev) |
RAZORPAY_KEY_ID / RAZORPAY_KEY_SECRET / RAZORPAY_WEBHOOK_SECRET | Razorpay credentials |
STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET | Stripe credentials |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | Google OAuth |
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | GitHub OAuth |
LINKEDIN_CLIENT_ID / LINKEDIN_CLIENT_SECRET | LinkedIn OAuth |
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASSWORD / SMTP_FROM | Outbound email (Resend / Postmark / SES). Unset = log-to-stdout dev mode. |
PORTAL_ADMIN_EMAILS | Comma-separated emails auto-promoted to admin on startup. |
CLOUDLEARN_APPLIANCE_URL | Public URL the user's appliance is reachable from for the /docs chooser cards. |
Full env reference in .env.example.
| Mount | Why |
|---|---|
/app/keys | JWT signing keys (generated on first boot). Must persist — losing this invalidates every issued license. |
/app/data | Optional, only used when DATABASE_URL=sqlite:///... (dev fallback). |
curl http://localhost:8001/healthz
# → {"status":"ok"}
The image declares a HEALTHCHECK so orchestrators (Docker Swarm, ECS,
Kubernetes via liveness probes) can observe readiness directly.
main (→ :edge)
and every v*.*.* tag (→ :<version> + :latest).cloudlearn/simulator —
the local cloud simulator appliance that the portal issues licenses for.Content type
Image
Digest
sha256:409944ddb…
Size
92.8 MB
Last updated
about 1 month ago
docker pull vyomi/portal