Here’s a real-world CI/CD pipeline setup for a React frontend + Node.js backend + deployment using GitHub Actions**. This is very close to what startups actually use.
🚀 Full CI/CD Pipeline (React + Node + GitHub Actions)
🧱 Architecture
Frontend (React) → Backend (Node/Express) → Deployment (Vercel / Render / AWS)
↑ ↑
CI tests CI tests
↓ ↓
GitHub Actions runs everything automatically
📁 Example Project Structure
```plaintext id="7p0k1m"
my-app/
├── client/ # React app
├── server/ # Node.js API
├── .github/
│ └── workflows/
│ └── ci-cd.yml
├── package.json
---
# ⚙️ CI Pipeline (Testing both React + Node)
This workflow runs on every push and pull request.
```yaml id="ci1234"
name: Full CI Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install frontend dependencies
working-directory: client
run: npm install
- name: Run frontend tests
working-directory: client
run: npm test
test-backend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install backend dependencies
working-directory: server
run: npm install
- name: Run backend tests
working-directory: server
run: npm test
🚀 CD Pipeline (Deployment)
Now we deploy when everything passes.
Example: Deploy backend + frontend
```yaml id="cd5678"
name: Deploy Pipeline
on:
push:
branches: [ main ]
jobs:
deploy-backend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install backend
working-directory: server
run: npm install
- name: Build backend
working-directory: server
run: npm run build
- name: Deploy backend to Render
run: |
curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK }}
deploy-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install frontend
working-directory: client
run: npm install
- name: Build React app
working-directory: client
run: npm run build
- name: Deploy to Vercel
run: |
npx vercel --prod --token=${{ secrets.VERCEL_TOKEN }}
---
# 🔐 GitHub Secrets (IMPORTANT)
You must store sensitive keys in:
👉 GitHub Repo → Settings → Secrets and Variables
Example secrets:
```plaintext id="sec123"
VERCEL_TOKEN=your-vercel-token
RENDER_DEPLOY_HOOK=https://api.render.com/deploy/xxx
🧪 What happens when you push code?
Example flow:
```plaintext id="flow123"
- You push code to GitHub
- GitHub Actions starts CI
- Runs:
- React tests
- Node API tests
- If ALL pass:
- Builds frontend
- Builds backend
- CD triggers:
- Deploy backend (Render/AWS)
- Deploy frontend (Vercel) ```
🧠 What real companies add on top
🔥 1. Linting
```yaml id="lint1"
run: npm run lint
---
### 🔥 Code formatting check
```yaml id="fmt1"
run: npm run format:check
🔥 Caching (faster builds)
```yaml id="cache1"
uses: actions/cache@v4
---
### 🔥 Database migrations (backend)
```yaml id="db1"
run: npm run migrate
🔥 Parallel jobs
Frontend + backend run at the same time (already shown above)
🚀 Real-world deployment options
Frontend
- Vercel (most common)
- Netlify
- AWS S3 + CloudFront
Backend
- Render
- Railway
- AWS EC2 / ECS
- DigitalOcean
⚠️ Common mistakes in CI/CD
❌ No environment variables
→ app works locally but fails in CI
❌ Missing build step
→ deployment breaks
❌ Not separating frontend/backend
→ messy pipeline
❌ No test stage
→ broken code gets deployed
🧭 Production-grade CI/CD flow
```plaintext id="prod1"
Push → CI Tests → Build → Approval (optional) → Deploy → Monitor
---
# 💡 Final Summary
A real CI/CD pipeline:
* Tests frontend + backend automatically
* Builds apps only if tests pass
* Deploys without manual work
* Prevents broken code from reaching users
Top comments (0)