Production-like preview environments for every PR. This repo deploys a React frontend, Node.js API, and Python worker into per-PR Kubernetes namespaces using Argo CD + GitHub Actions.
Core idea: PR opens → build/push images tagged by PR head SHA → Argo CD deploys pr-<number> namespace → review in a production-like cluster → merge to main.
services/api/Node.js + Express APIservices/frontend/React + Vite UI + Express server (/health.json)services/worker/Python worker that polls the APIdeploy/helm/services/Source Helm charts for each servicedeploy/helm/app/Umbrella chart used by Argo CD (vendored subcharts incharts/)deploy/argocd/Argo CD ApplicationSet for PR previewsinfra/terraform/AWS VPC + EKS + RDSsync-helm-charts.shSync service charts into the umbrella chart vendored underdeploy/helm/app/charts/
- PR opened/updated → GitHub Actions builds and pushes images with tag
PR_HEAD_SHA. - Argo CD ApplicationSet watches PRs and deploys
deploy/helm/appintopr-<number>namespace. - Frontend service is
LoadBalancerin preview. Get the external IP with:
kubectl -n pr-<number> get svc frontendCreate Docker Hub repos:
preyash29/prod-preview-apipreyash29/prod-preview-frontendpreyash29/prod-preview-worker
Add GitHub Actions secrets in your repo:
DOCKERHUB_USERNAMEDOCKERHUB_TOKEN
Copy env templates if you run services locally:
cp services/api/.env.example services/api/.env
cp services/frontend/.env.example services/frontend/.env
cp services/worker/.env.example services/worker/.envInstall Argo CD in your cluster (namespace argocd assumed).
Create a GitHub token (read access to the repo) and store it in a secret for ApplicationSet:
kubectl -n argocd create secret generic github-token \
--from-literal=token=YOUR_GITHUB_TOKENApply the ApplicationSet:
kubectl apply -f deploy/argocd/applicationset-preview.yamlIf your Argo CD namespace is not argocd, update:
deploy/argocd/applicationset-preview.yaml
The umbrella chart uses vendored subcharts. If you modify charts under deploy/helm/services/, run:
./sync-helm-charts.shCommit the updated files under deploy/helm/app/charts/ along with your source chart changes. Argo CD checks out the repo at the PR head_sha and renders deploy/helm/app, so preview deploys will fail if the vendored charts are not committed.
- Terraform creates your AWS network, database, and EKS cluster. (
infra/terraform/) - Docker builds images for each service and pushes to Docker Hub.
- Argo CD deploys per-PR environments using the umbrella chart in
deploy/helm/app.
flowchart LR
subgraph "GitHub"
PR["Pull Request (PR)"]
CI["GitHub Actions\nBuild + Push Images"]
end
subgraph "Registry"
DH["Docker Hub\nImages tagged with PR SHA"]
end
subgraph "GitOps"
AS["Argo CD ApplicationSet\nPR Generator"]
ARGO["Argo CD Controller"]
end
subgraph "Kubernetes (EKS)"
NS["Namespace: pr-<number>"]
FE["Frontend Service\nLoadBalancer"]
API["API Service\nClusterIP"]
WK["Worker Service\nClusterIP"]
end
PR --> CI --> DH
PR --> AS --> ARGO
ARGO --> NS
DH --> ARGO
NS --> FE
NS --> API
NS --> WK
FE --> API
WK --> API
sequenceDiagram
participant Dev as Developer
participant GH as GitHub PR
participant CI as GitHub Actions
participant DH as Docker Hub
participant AS as Argo CD ApplicationSet
participant ARGO as Argo CD
participant K8s as Kubernetes (EKS)
Dev->>GH: Open/Update PR
GH->>CI: Trigger build workflow
CI->>DH: Build & push images (tag = PR SHA)
GH->>AS: PR discovered (PR generator)
AS->>ARGO: Create/Update Application
ARGO->>K8s: Sync Helm chart to namespace pr-<number>
K8s-->>Dev: Preview URL (LoadBalancer IP)
Dev->>GH: Merge PR
GH->>AS: PR closed
AS->>ARGO: Remove Application
ARGO->>K8s: Delete namespace pr-<number>
