Hey everyone đź‘‹
I want to share something that’s made a huge difference in how I ship code for my app: Blue-Green deployment.
If you’ve ever pushed a release and then spent the next hour nervously watching logs (or worse—fixing production bugs on the fly), you’ll probably appreciate this approach.
So, What is Blue-Green Deployment?
In simple terms, you maintain two identical environments: one “blue” and one “green.”
At any given time:
- One environment is live and handling real user traffic
- The other is idle, ready for a new release
When it’s time to deploy:
- You push the new version to the inactive environment
- You test it thoroughly
- Once everything looks good, you switch traffic over
The old environment stays around as a fallback
Think of it like having a fully prepared backup version of your app just one switch away.
Why This Approach is So Useful
Older deployment styles usually meant updating production directly. That worked… until it didn’t.
Blue-Green deployment helps solve a lot of that stress:
- Fewer risks during deployment
- Instant rollback if something breaks
- No downtime for users
- More confidence to ship frequently
For my app, this is especially important. People use it throughout the day for inspiration, and even a short outage can be noticeable.
A Quick Look at my App
Just to set the context, here’s what I have been working with:
Frontend:
- React (Vite)
- Tailwind CSS
- React Router
Backend:
- Node.js + Express
- PostgreSQL
- JWT authentication
Infrastructure:
- AWS EC2 (backend)
- S3 + CloudFront (frontend)
Users can browse the app, sign up, and save their favorites. Pretty straightforward—but I want it to be reliable.
How I Actually Implement Blue-Green
I automated most of this using GitHub Actions.
1. CI/CD Starts Automatically
Whenever I push changes to the main branch, the pipeline kicks in (but only if backend files have changed).
Before anything gets deployed, I run some checks:
- Secret scanning (Gitleaks)
- Dependency + security analysis (Semgrep)
- Container scanning (Trivy)
If anything looks risky, the pipeline stops right there.
2. Building the Docker Image
I containerize the backend using Docker so everything behaves consistently across environments.
Then I:
- Build the image
- Scan it
- Push it to Amazon ECR
I also use Docker Buildx to speed things up with caching.
3. The Blue-Green Switch on EC2
This is the core of the system.
My deployment script basically decides:
- If blue is live → deploy green
- If green is live → deploy blue
Then it:
- Pulls the latest Docker image
- Stops the old container on the target side
- Starts the new one on a different port
- Runs a health check
- Switches Nginx traffic to the new version if everything is fine
- Cleans up the old container
From start to finish, it usually takes just a few minutes, and users don’t notice anything.
4. After Deployment Checks
Once the switch is done, I run OWASP ZAP against the live system to simulate real-world attacks and catch security issues.
I also sent a Slack update so the team knows what happened.
Frontend Deployment (Simpler by Design)
My frontend doesn’t need Blue-Green.
Since it’s static:
- I built the React app
- Upload it to S3
- Invalidate CloudFront cache
Rolling back is just redeploying a previous build, so there’s no need for dual environments here.
What’s Improved
Since moving to Blue-Green, a few things stand out:
- Deployments feel way less stressful
- I ship more often instead of batching changes
- I had zero deployment-related downtime for a while
- Rollbacks are basically instant when needed
A Few Challenges I Ran Into
It’s not all effortless, though.
Database migrations need extra care—you can’t assume both versions behave the same way.
Environmental parity matters a lot. If the idle environment isn’t identical, surprises show up at the worst time.
Resource usage is higher since you’re running two environments.
And Nginx switching required some tuning to get right, especially to ensure a seamless cutover.
A Few Things I’d Like to Improve Next
As the project grows, there are still a few things I’d like to improve in this setup:
- Replace Nginx switching with an AWS Application Load Balancer (ALB) for cleaner and more scalable traffic routing
- Add canary deployments to slowly shift traffic instead of switching everything at once
- Automate rollback if health checks fail after deployment
- Add better monitoring and alerts using tools like Prometheus and Grafana
- Use Terraform to manage infrastructure more consistently
- Create preview environments for pull requests to test features before merging
Even though the current setup works, there’s always room to make deployments safer and more automated.
Final Thoughts
Blue-Green deployment changed how I think about shipping code.
Instead of “hope this works,” it’s more like “I can test this safely before anyone sees it.”
It’s not the only deployment strategy out there, but for us, it’s been a solid balance of safety and speed.
If you’ve tried something different—rolling deployments, canary releases, or something custom—it’d be interesting to hear how it’s worked for you.
Github link: https://github.com/Shawmeer/Blue-Green-AWS
Check more blogs at: https://khanalsamir.com

Top comments (0)