Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CD - Production (AWS + Azure)

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

# -------------------------
# Deploy to AWS
# -------------------------
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-south-1

- name: Terraform Apply - AWS
run: |
cd infra/aws
terraform init
terraform apply -auto-approve

# -------------------------
# Deploy to Azure
# -------------------------
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Terraform Apply - Azure
run: |
cd infra/azure
terraform init
terraform apply -auto-approve
114 changes: 114 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: CI - Develop (AWS + Azure)

on:
push:
branches:
- develop

# ✅ REQUIRED PERMISSIONS
permissions:
contents: read

jobs:
build-test-push:
runs-on: ubuntu-latest

env:
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
AZURE_ACR_NAME: ${{ secrets.AZURE_ACR_NAME }}

steps:
# -------------------------
# Checkout
# -------------------------
- name: Checkout code
uses: actions/checkout@v4

# -------------------------
# Backend setup
# -------------------------
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install backend dependencies
run: |
cd backend
pip install -r requirements.txt

# -------------------------
# Frontend setup
# -------------------------
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install frontend dependencies
run: |
cd frontend
npm install

# -------------------------
# Docker Build
# -------------------------
- name: Build backend image
run: docker build -t backend:${{ github.sha }} ./backend

- name: Build frontend image
run: docker build -t frontend:${{ github.sha }} ./frontend

# =================================================
# AWS ECR
# =================================================
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to AWS ECR
run: |
aws ecr get-login-password --region $AWS_REGION \
| docker login --username AWS --password-stdin \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com

- name: Ensure ECR repositories exist
run: |
for repo in backend frontend; do
aws ecr describe-repositories --repository-names $repo \
|| aws ecr create-repository --repository-name $repo
done

- name: Push images to AWS ECR
run: |
for repo in backend frontend; do
docker tag $repo:${{ github.sha }} \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$repo:${{ github.sha }}
docker push \
$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$repo:${{ github.sha }}
done

# =================================================
# Azure ACR (FIXED)
# =================================================
- name: Azure Login
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Login to Azure ACR
run: |
az acr login --name $AZURE_ACR_NAME

- name: Push images to Azure ACR
run: |
for repo in backend frontend; do
docker tag $repo:${{ github.sha }} \
$AZURE_ACR_NAME.azurecr.io/$repo:${{ github.sha }}
docker push \
$AZURE_ACR_NAME.azurecr.io/$repo:${{ github.sha }}
done
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Backend
backend/venv/
backend/app/__pycache__/
backend/*.pyc

# Frontend
frontend/node_modules/
frontend/.next/

# OS / editor junk
.DS_Store
*.log
44 changes: 44 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# =========================
# Stage 1: Build stage
# =========================
FROM python:3.11-slim AS builder

# Set working directory
WORKDIR /app

# Install build dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY app app

# =========================
# Stage 2: Runtime stage
# =========================
FROM python:3.11-slim

# Create non-root user (security best practice)
RUN useradd -m appuser

# Set working directory
WORKDIR /app

# Copy only required files from builder stage
COPY --from=builder /usr/local/lib/python3.11 /usr/local/lib/python3.11
COPY --from=builder /usr/local/bin /usr/local/bin
COPY app app

# Switch to non-root user
USER appuser

# Environment-based configuration
ENV HOST=0.0.0.0
ENV PORT=8000

# Expose application port
EXPOSE 8000

# Start FastAPI using Uvicorn
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
47 changes: 47 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# =========================
# Stage 1: Build stage
# =========================
FROM node:18-alpine AS builder

# Set working directory
WORKDIR /app

# Copy package files first (better caching)
COPY package.json package-lock.json ./
RUN npm ci

# Copy application source
COPY . .

# Build Next.js app
RUN npm run build

# =========================
# Stage 2: Production stage
# =========================
FROM node:18-alpine

# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Set working directory
WORKDIR /app

# Copy only required build output
COPY --from=builder /app/package.json ./
COPY --from=builder /app/package-lock.json ./
COPY --from=builder /app/.next ./.next
# COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules

# Switch to non-root user
USER appuser

# Environment variable for backend URL
ENV NEXT_PUBLIC_API_URL=http://localhost:8000

# Expose Next.js port
EXPOSE 3000

# Start Next.js in production mode
CMD ["npm", "start"]