DEV Community

alok-38
alok-38

Posted on

Build Your Own DevOps Lab: CI/CD, Environment Separation, and Nginx

Building a Fully Automated DevOps Lab on AWS with Nginx

In this post, I'll walk you through setting up a complete DevOps lab on AWS using EC2, Nginx, and GitHub Actions for CI/CD. This is perfect for anyone wanting hands-on experience with environment separation, automated deployments, and production-grade configurations.


Project Overview

We are hosting a static site on an EC2 instance with Nginx. The key features include:

  • Automated CI/CD using GitHub Actions and AWS SSM
  • Separate production and staging environments
  • Security best practices for a public-facing site

Environments:

  • Production: /usr/share/nginx/html/DevOps/current
  • Staging: /usr/share/nginx/html/DevOps-staging

Environment Setup

EC2 Setup:

  • OS: Amazon Linux 2
  • Nginx installed from the package manager
  • Runs as non-root user nginx
  • Directories:
/usr/share/nginx/html/DevOps/current   # production
/usr/share/nginx/html/DevOps-staging  # staging
Enter fullscreen mode Exit fullscreen mode
  • Set proper permissions:
sudo chown -R ec2-user:ec2-user /usr/share/nginx/html/DevOps*
Enter fullscreen mode Exit fullscreen mode

Git & Branching

We follow a simple branching strategy:

  • Main branch: production-ready code
  • Feature branches: work on new features

Example:

git checkout -b feature/add-header
Enter fullscreen mode Exit fullscreen mode

Merge to main after testing in staging. Production deploys are triggered only on tags:

on:
  push:
    tags:
      - "v*.*"
Enter fullscreen mode Exit fullscreen mode

CI/CD Pipeline

GitHub Actions workflow automates deployment:

  1. Checkout code
  2. Configure AWS credentials
  3. Deploy via AWS SSM:
aws ssm send-command \
  --targets "Key=InstanceIds,Values=<EC2-ID>" \
  --document-name "AWS-RunShellScript" \
  --parameters '{"commands":["cd /usr/share/nginx/html/DevOps/current","git pull origin main","sudo systemctl reload nginx"]}'
Enter fullscreen mode Exit fullscreen mode

Production deploys happen only on tags; staging can be deployed manually or via a branch workflow.


Nginx Configuration

Main Server Block:

  • Serves /DevOps/current
  • Listens on HTTP 80 (HTTPS optional)
  • Security:

    • Disable directory listing
    • Limit HTTP methods to GET/HEAD
    • Block hidden files
    • Add security headers
    • Cache static assets (/styles/)
  • Monitoring endpoint /nginx_status restricted to localhost

Staging Server Block:

  • Serves /DevOps-staging
  • Optional port 8080 or subdomain staging.example.com

Environment Separation

Environment Directory Branch/Deployment
Production /DevOps/current main branch + tag deployment
Staging /DevOps-staging feature branches, manual testing

Monitoring & Logs

  • Nginx logs: /var/log/nginx/access.log & /error.log
  • Stub status: /nginx_status restricted to localhost
  • Optional: integrate Prometheus/Grafana or AWS CloudWatch

Security Quick Wins

Nginx:

  • Enable HTTPS and security headers
  • Limit HTTP methods
  • Block hidden files
  • Cache static assets

OS:

  • Run Nginx as non-root user
  • Limit SSH access via security groups
  • Keep the system updated

CI/CD:

  • Secrets stored securely in GitHub Actions
  • Only tag-based deployments

Monitoring:

  • Restrict /nginx_status to localhost
  • Monitor logs regularly

Commands Reference

Check Nginx config:

sudo nginx -T
sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

Reload Nginx:

sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Git workflow:

git add -A
git commit -m "message"
git push origin main
git tag v1.0.1
git push origin v1.0.1
Enter fullscreen mode Exit fullscreen mode

Deployment: fully automated via GitHub Actions & AWS SSM


Next Steps / Recommendations

  • Add HTTPS with Let’s Encrypt
  • Automate staging deployments via branch workflows
  • Integrate monitoring dashboards (Prometheus/Grafana)
  • Implement rollbacks using symlinked releases (current)

This setup gives you a production-ready DevOps lab, complete with CI/CD, environment separation, monitoring, and basic security. You can now experiment, extend, and even turn this into a learning playground for more advanced DevOps practices.

Top comments (0)