Cloud & DevOps
14 min
2025-10-06
In modern fullstack development, GitHub Actions is one of the most powerful ways to automate everything from testing to deployment, directly inside your repository. In this post, I'll walk you through how I set up a seamless CI/CD pipeline for a Next.js (frontend) and Django (backend) application, fully automated to deploy on Azure App Service.
Instead of relying on third-party CI/CD tools, GitHub Actions lets you:
For small teams and startups, this means zero manual deployment steps, every commit becomes production-ready.
Here's the structure of the project I automated:
root/
├── frontend/ (Next.js 15)
│ ├── package.json
│ └── next.config.mjs
├── backend/ (Django)
│ ├── manage.py
│ └── requirements.txt
├── Dockerfile
└── .github/workflows/deploy.yml
Both the frontend and backend are containerized using a Dockerfile, and Azure handles the final build and deployment automatically.
The workflow YAML file (.github/workflows/deploy.yml) defines the build, test, and deploy pipeline. Here's how I structured it:
name: CI/CD - Next.js + Django
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
# FRONTEND (Next.js)
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install frontend dependencies
working-directory: ./frontend
run: npm ci
- name: Build frontend
working-directory: ./frontend
run: npm run build
# BACKEND (Django)
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install backend dependencies
working-directory: ./backend
run: pip install -r requirements.txt
- name: Run backend tests
working-directory: ./backend
run: python manage.py test
# DEPLOYMENT (Azure)
- name: Log in to Azure
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Build and push image to Azure Container Registry
uses: azure/docker-login@v2
with:
login-server: ${{ secrets.AZURE_CONTAINER_REGISTRY }}
username: ${{ secrets.AZURE_USERNAME }}
password: ${{ secrets.AZURE_PASSWORD }}
- name: Deploy to Azure Web App
uses: azure/webapps-deploy@v3
with:
app-name: my-fullstack-app
publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
images: ${{ secrets.AZURE_CONTAINER_REGISTRY }}/my-fullstack-app:latest
This workflow handles everything automatically, from installation to testing and final deployment on Azure.
Security is crucial. Instead of exposing credentials, I used GitHub's encrypted secrets under:
Settings → Secrets and Variables → Actions
These include:
AZURE_PUBLISH_PROFILE, Azure App Service publish credentialsAZURE_CREDENTIALS, JSON credentials for Azure loginAZURE_CONTAINER_REGISTRY, AZURE_USERNAME, AZURE_PASSWORD, Docker registry detailsBefore every deployment, the workflow ensures code integrity:
I configured additional workflows for preview environments:
feature/* branches → Deploy to staging appmain branch → Deploy to productionThis helps test new features live before merging them.
actions/cache to cache npm and pip dependencies for faster builds.concurrency in workflows to cancel older in-progress deployments when new commits arrive.env: blocks for better maintainability.Setting up GitHub Actions for a Next.js + Django stack may seem complex initially, but once configured, it's a game-changer. Every push to main automatically builds, tests, and deploys your entire app to Azure, no manual steps, no forgotten migrations, no downtime.
This is the same automation setup I use in my production projects. It gives clients peace of mind, keeps releases predictable, and saves hours every week in manual DevOps work.
Once you adopt this workflow, you'll wonder how you ever shipped without it.
Tags :
GitHubActions
CI/CD
Nextjs
Django
Azure
DevOps
Automation
Fullstack