DEPLOYMENT
JaduSpine on AWS (ECS/Fargate + ALB + Cloudflare DNS) — Playbook¶
This repo’s playground expects:
- WebSocket path:
/connection/websocket - HTTP API path:
/api - JWT (HS256) for client connections using
JADU_SPINE_JWT_SECRET(seeAUTH_README.md)
Target outcome:
- A single JaduSpine realtime server (Centrifugo under the hood) on ECS/Fargate behind an ALB (HTTPS).
- DNS handled by Cloudflare.
- Admin enabled (password + secret).
- HTTP API public (protected by API key).
0) Inputs you must decide¶
- AWS region (must match your ACM certificate region)
- JaduSpine domain (example):
jaduspine.example.com - Allowed origin(s) for browsers (example):
https://app.example.com - Where to deploy:
- an existing VPC + subnets (recommended), or
- create a new VPC (not included in this repo yet)
This repo includes a Terraform root module at infra/terraform/ which assumes you already have a VPC + subnets.
Prerequisites (local machine)¶
- Terraform installed: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
- AWS CLI installed and configured (Terraform uses your local AWS credentials)
Basic AWS CLI setup:
# 1) Install AWS CLI (macOS via Homebrew)
brew install awscli
# 2) Configure credentials (creates/updates ~/.aws/config and ~/.aws/credentials)
aws configure
# Optional: if you use profiles
aws configure --profile <profile-name>
# 3) Verify you’re authenticated to the expected AWS account
aws sts get-caller-identity
If you’re using a named profile, run Terraform with:
export AWS_PROFILE=<profile-name>
1) Create secrets in AWS (Secrets Manager recommended)¶
Create 4 secret values (values are up to you). These names are the runtime env var names your backend/Centrifugo will use:
JADU_SPINE_JWT_SECRETCENTRIFUGO_API_KEYCENTRIFUGO_ADMIN_PASSWORDCENTRIFUGO_ADMIN_SECRET
Important:
- In AWS Secrets Manager, the secret resource name/path can be anything. What matters is the secret value stored inside it.
- Terraform only needs the secret ARNs and will inject those values into the right container env vars.
Naming suggestion for the AWS secret resource name (optional):
/jaduspine/<env>/JADU_SPINE_JWT_SECRET/jaduspine/<env>/CENTRIFUGO_API_KEY/jaduspine/<env>/CENTRIFUGO_ADMIN_PASSWORD/jaduspine/<env>/CENTRIFUGO_ADMIN_SECRET
Paste the secret ARNs into infra/terraform/terraform.tfvars:
secret_arn_jadu_spine_jwt_secret→ secret ARN that containsJADU_SPINE_JWT_SECRETsecret_arn_centrifugo_api_key→ secret ARN that contains the API key value (used asCENTRIFUGO_API_KEYin your backend and injected asCENTRIFUGO_HTTP_API_KEYinto Centrifugo)secret_arn_centrifugo_admin_password→ secret ARN that containsCENTRIFUGO_ADMIN_PASSWORDsecret_arn_centrifugo_admin_secret→ secret ARN that containsCENTRIFUGO_ADMIN_SECRET
For our current setup (plain-text secrets), these are the values to paste:
secret_arn_jadu_spine_jwt_secret = "arn:aws:secretsmanager:us-east-1:408921634255:secret:jaduspine/prod/jwt_secret-FBP1UO"
secret_arn_centrifugo_api_key = "arn:aws:secretsmanager:us-east-1:408921634255:secret:jaduspine/prod/centrifugo_api_key-AjaXt1"
secret_arn_centrifugo_admin_password = "arn:aws:secretsmanager:us-east-1:408921634255:secret:jaduspine/prod/centrifugo_admin_password-vrzc6p"
secret_arn_centrifugo_admin_secret = "arn:aws:secretsmanager:us-east-1:408921634255:secret:jaduspine/prod/centrifugo_admin_secret-mZa8GX"
2) Create an ACM certificate (TLS) and validate it in Cloudflare¶
In AWS Certificate Manager (ACM), request a public certificate for:
jaduspine.example.com
Choose DNS validation. ACM will give you one (or more) DNS records like:
- Name:
_xxxx.jaduspine.example.com - Type:
CNAME - Value:
_yyyy.acm-validations.aws
In Cloudflare:
- Add the CNAME record(s) exactly as ACM shows.
- Set them to DNS only (grey cloud) for validation.
Wait until ACM shows the cert as Issued.
3) Configure Terraform variables¶
Copy the example file:
infra/terraform/terraform.tfvars.example→infra/terraform/terraform.tfvars
Fill in:
- your VPC + subnet IDs
- your
certificate_arn - your secret ARNs
- your allowed origins
4) Deploy (Terraform)¶
From repo root:
cd infra/terraform
terraform init
terraform plan -out tfplan
terraform apply tfplan
Terraform will output (at minimum) your ALB DNS name.
5) Point Cloudflare DNS at the ALB¶
In Cloudflare DNS:
- Create
CNAMErecord: - Name:
jaduspine - Target:
<alb-dns-name-from-terraform-output>
For fewer moving parts during initial setup:
- set it to DNS only (grey cloud)
After things work end-to-end, you can decide whether to proxy it via Cloudflare (orange cloud). If you do, use Full (strict) TLS mode and keep the ALB HTTPS listener.
6) Configure your apps¶
Frontend¶
Set:
NEXT_PUBLIC_CENTRIFUGO_URL=wss://jaduspine.example.com/connection/websocket
Backend¶
Set:
CENTRIFUGO_API_URL=https://jaduspine.example.com/apiCENTRIFUGO_API_KEY=<same as secret>JADU_SPINE_JWT_SECRET=<same as secret>
7) Verify¶
- Open
https://jaduspine.example.comand confirm you reach the server. - Confirm WebSocket connects from your app using:
wss://jaduspine.example.com/connection/websocket- Confirm backend publishing works via HTTP API:
https://jaduspine.example.com/apiwithCENTRIFUGO_API_KEY.
Notes (v1 constraints)¶
- Keep
desired_count = 1. Without Redis, multi-task scaling will cause some publishes to miss clients connected to other tasks. - Admin is enabled via password + secret (see
infra/jaduspine.config.prod.jsonfor the intended shape).