Take-Home Technical Assignment
DevOps Engineer
A 4-day practical challenge to assess your ability to build and operate production-grade
infrastructure.
Issued: [15 June, 2026] Deadline: [19 June, 2026]
👋 Welcome
Hey — thanks for making it here. We give this assignment to a small number of candidates and
we read every submission carefully.
This is not a tutorial-following exercise. We want to see real decisions, clean systems, and the
ability to reason about what you've built. Both tasks mirror work you'd actually do here on day
one.
Read the entire doc before you start,
📋 At a Glance
Infrastructure A Linux VPS is provided with a custom user account (details
below)
Deliverables GitHub repo(s), live endpoints, a short Loom walkthrough, and a
README per repo
Task 1 Deploy a [Link] API with full CI/CD pipeline
Task 2 Containerized deployment with Nginx reverse proxy,
zero-downtime CI/CD, and monitoring
🔐 VPS Access Credentials — Keep These Private
Do not share these credentials.
Do not commit credentials, SSH keys, passwords, or .env files to GitHub.
Server IP:
[Link]
Candidate: Kshitij
Username: kshitij
Password: For the password you will get a separate mail right after this
SSH Login:
ssh kshitij@[Link]
Candidate: Asif
Username: asif
Password: For the password you will get a separate mail right after this
SSH Login:
ssh asif@[Link]
Candidate: Shivangi
Username: shivangi
Password: For the password you will get a separate mail right after this
SSH Login:
ssh shivangi@[Link]
TASK 01
Deploy a [Link] API to VPS with CI/CD
DevOps · Linux · GitHub Actions · PM2
What You're Building
Take the provided [Link]/Express codebase (.zip attached), push it to your own GitHub
repository, and deploy it to the VPS. Every push to the main branch should automatically deploy
the latest code to the server with no manual intervention.
Step 1 — Set Up Your GitHub Repo
• Unzip the provided codebase and push it to a new public GitHub repository
• Name it something sensible, e.g. api-deployment-challenge
• Your repo must have a clear README covering setup, env vars, and architecture
Step 2 — Configure the VPS
• SSH into the VPS using the credentials above
• Install [Link]
• Install PM2
• Clone your repo
💡 Why PM2?
PM2 is the industry standard for running Node apps in production on Linux. It keeps your app
alive if it crashes, restarts on server reboot, and gives you live logs. You're expected to know it or
learn it quickly.
Step 3 — Set Up GitHub Actions CI/CD
When you push to main, the pipeline should:
• SSH into the VPS using appleboy/ssh-action
• Pull latest code
• Install dependencies and restart
TASK 02
Production-Grade Containerized Deployment
Docker · Nginx · Zero-Downtime CI/CD · Monitoring · Security Hardening
What You're Building
Take the provided [Link]/Express codebase (.zip attached), push it to your own GitHub
repository, and deploy it to the VPS. Every push to the main branch should automatically deploy
the latest code to the server with no manual intervention.
There are no step-by-step instructions here. You're expected to research, make
architectural decisions, and document your reasoning.
Requirements
1. Dockerize the Application
• Write a production-grade Dockerfile with a multi-stage build
◦ Stage 1: install dependencies and build
◦ Stage 2: lean runtime image — only what the app needs to run
• The final image should be as small as possible — no dev dependencies, no build tools
• Add a HEALTHCHECK instruction to the Dockerfile
• Use a .dockerignore file — node_modules and .env must never be in the image
2. Nginx as Reverse Proxy
• Install and configure Nginx on the VPS to sit in front of your Docker container
• Nginx should listen on port 80 and proxy traffic to your container
• Add these headers to your Nginx config:
◦ X-Real-IP
◦ X-Forwarded-For
◦ X-Forwarded-Proto
• Configure a basic rate limit in Nginx — no more than 30 requests per minute per IP
3. Zero-Downtime CI/CD Pipeline
Build a GitHub Actions pipeline that deploys your Docker container with zero downtime. The
pipeline should:
• Run on every push to main
• Build the Docker image on the VPS (not GitHub's runners — SSH in and build there)
• Implement a blue-green or rolling strategy so the old container keeps serving traffic until
the new one is healthy
◦ Start the new container, verify the health check passes, then stop the old one
◦ If the health check fails, the old container must keep running — no broken deploys
• The pipeline must fail and alert if the health check does not pass within 30 seconds
• All secrets (SSH key, any env vars) must be stored as GitHub Secrets
What zero-downtime means here
If someone hits your API endpoint at the exact moment a deploy is running, they should get a
valid response — not a connection refused or 502. You decide how to implement this. Document
your approach in the README.
4. Monitoring & Alerting
You should know when your service is down before we tell you.
• Set up UptimeRobot (free tier) to monitor your HTTP endpoint every 5 minutes
• Configure it to alert via email on downtime
• In your Loom, show us the UptimeRobot dashboard — we want to see uptime history
• Set up basic log rotation for your container logs so they don't fill the disk:
◦ Use Docker's json-file log driver with max-size and max-file limits in your run command
or compose file
5. Security Hardening
Basic server hygiene. These are non-negotiable for a production deployment.
• Disable password-based SSH login — key-only authentication
• Disable root login via SSH
• The app process inside the container must not run as root — use a non-root user in your
Dockerfile
• Environment variables must be passed to the container at runtime — never baked into
the image. Use a --env-file flag or Docker secrets
• No sensitive data (API keys, passwords, .env files) committed to the repository at any
point — we will check git history
6. docker-compose (Bonus)
Bonus
If you set up a [Link] that defines your app container and any supporting services
(e.g. a Redis cache, a separate worker), and update your CI/CD to use docker compose up -d
instead of bare docker run, that's a meaningful bonus.
This is optional. A clean single-container setup done well is better than a messy multi-container
one.
📎 Resources
• Docker multi-stage builds — official docs
• Nginx reverse proxy with [Link] — DigitalOcean
• GitHub Actions: zero-downtime Docker deploy pattern
• UptimeRobot — free uptime monitoring
📬 What to Submit
• Public GitHub repo(s) — Task 1 and Task 2 can be separate repos or a monorepo
• Live endpoints — Task 1 and Task 2 both accessible via the VPS public IP
• A Loom walkthrough (5–8 minutes) covering:
◦ Your folder and file structure
◦ CI/CD pipeline running live — push a commit during the recording
◦ The zero-downtime strategy you implemented and why
◦ UptimeRobot dashboard
• A README in each repo — architecture decisions, how to run locally, env vars needed,
and anything you'd do differently with more time
🏆 How We Evaluate
No surprises — here's exactly what we're looking at.
Task 1 — [Link] Deployment & CI/CD
What We're Looking At Weight
App is running and accessible on the VPS High
CI/CD pipeline triggers on main push and deploys correctly High
PM2 configured — app restarts on server reboot Medium
GitHub Secrets used — no credentials hardcoded anywhere Medium
Clean workflow YAML and repo structure Medium
Task 2 — Production Deployment
What We're Looking At Weight
Multi-stage Dockerfile — lean image, HEALTHCHECK High
present
Nginx correctly configured as reverse proxy with headers High
and rate limiting
Zero-downtime deploy strategy implemented and High
documented
SSH hardened — key-only auth, root login disabled High
App runs as non-root user inside the container Medium
UptimeRobot monitoring set up and shown in Loom Medium
Log rotation configured on container logs Medium
README explains architectural decisions, not just setup Medium
steps
No secrets in git history (we will check) Medium
docker-compose with multiple services Bonus
📐 Ground Rules
• Use any online resources and documentation — this is not a closed exam
• Do not share or commit VPS credentials under any circumstances
• AI tools are fine for reference and debugging — but you must be able to explain every
line of config you submit
• The work must be yours — we will ask you to walk through your decisions in a follow-up
call
• We will push a test commit to verify your CI/CD pipeline end-to-end
• We will check git history for any accidentally committed secrets