The Linux Server Administrator’s Modern Survival Guide: Cloud, Docker, Git, CI/CD and Production Infrastructure
Most server administrators start with:
ssh
Then they discover that modern infrastructure is much bigger than SSH.
You need to understand cloud servers, containers, Git, CI/CD, reverse proxies, databases, caching, monitoring, backups, and disaster recovery.
The good news?
You don't need to memorize hundreds of commands.
You need to understand how the pieces fit together.
That is the difference between someone who can execute commands and someone who can operate production infrastructure.
The Modern Server Stack
A production application might look like this:
Users
↓
Cloudflare / CDN
↓
Load Balancer
↓
Nginx
↓
Application
↓
Redis
↓
Database
↓
Object Storage / Backups
GitHub
↓
CI/CD
↓
Deployment
↓
Monitoring
↓
Alerts
Every layer solves a different problem.
Cloud provides infrastructure.
Nginx handles web traffic.
Docker packages applications.
Git manages source code.
CI/CD automates delivery.
Redis accelerates frequently accessed data.
Prometheus/Grafana tells you what is happening.
Backups and disaster recovery make sure one failure doesn't become a catastrophe.
Learn the architecture first.
The commands become easier afterward.
1. Cloud: Stop Thinking in Terms of Servers
AWS, DigitalOcean, and Azure all provide similar fundamental building blocks.
You need to understand:
- Compute
- Storage
- Networking
- DNS
- Identity
- Firewalls
- Load balancing
- Monitoring
- Backups
For example, on AWS:
EC2 → Compute
S3 → Object storage
RDS → Managed database
Route 53 → DNS
ELB → Load balancing
CloudFront → CDN
IAM → Identity and access
VPC → Networking
The important interview question isn't:
"What is EC2?"
It's:
"How would you deploy and protect an application running on EC2?"
A strong answer includes:
EC2
↓
Security Group
↓
Nginx
↓
Application
↓
Database
↓
S3 backups
↓
CloudWatch monitoring
That's infrastructure thinking.
2. Security Groups Are Not Just Another Firewall
A common interview mistake is saying:
"Security Groups are AWS firewalls."
That's technically correct, but incomplete.
A better answer:
A Security Group controls network traffic to and from AWS resources such as EC2 instances through defined inbound and outbound rules.
For example:
aws ec2 authorize-security-group-ingress \
--group-id sg-12345 \
--protocol tcp \
--port 22 \
--cidr 203.0.113.0/24
But don't blindly open SSH to:
0.0.0.0/0
Production security starts with one principle:
Allow only what is required, from only where it is required.
3. Docker: Package the Application, Not the Server
Before containers, deploying an application often meant:
Install OS
Install runtime
Install dependencies
Configure application
Configure services
Fix permissions
Hope nothing conflicts
Docker changes the model.
You package the application and its environment into an image.
Then run that image consistently.
docker pull nginx
docker run -d \
--name my-nginx \
-p 80:80 \
nginx
Now understand the difference:
Image
The packaged blueprint.
Container
A running instance of that image.
Volume
Persistent storage.
Network
Communication between containers.
This distinction appears constantly in interviews.
4. Containers Are Not Virtual Machines
This question is almost guaranteed in DevOps interviews.
VM
Hardware
↓
Hypervisor
↓
Guest OS
↓
Application
Container
Hardware
↓
Host OS / Kernel
↓
Container Runtime
↓
Container
↓
Application
Containers generally start faster and use fewer resources because they share the host kernel.
But that doesn't mean:
"Containers are always better."
The correct engineering answer is:
Use the abstraction that fits the workload, isolation requirements, operational model, and scalability needs.
5. Docker Compose: One Application, Multiple Services
Real applications rarely contain only one process.
You might have:
Nginx
PHP
MySQL
Redis
Docker Compose lets you describe that architecture as code.
services:
nginx:
image: nginx:latest
php:
image: php:8.2-fpm
mysql:
image: mysql:8.0
redis:
image: redis:alpine
Then:
docker compose up -d
One command.
Four services.
Repeatable infrastructure.
That is the real value of containers:
consistency.
6. Git Is Infrastructure Knowledge
Git isn't just for developers.
If you're managing servers, you should understand:
git clone
git status
git pull
git fetch
git add
git commit
git push
git diff
git log
git stash
git revert
But don't just memorize commands.
Understand this:
Working Directory
↓
Staging Area
↓
Commit
↓
Remote Repository
And understand the difference between:
git fetch
and:
git pull
fetch downloads remote changes without modifying your current working tree.
pull generally performs a fetch followed by integration into your current branch.
That distinction matters during production troubleshooting.
7. CI/CD Turns Deployment Into a Pipeline
Without automation:
Developer
↓
SSH server
↓
git pull
↓
install dependencies
↓
restart service
↓
hope
With CI/CD:
Git Push
↓
Build
↓
Test
↓
Package
↓
Deploy
↓
Health Check
↓
Monitoring
A simple GitHub Actions workflow might deploy after a push to main.
But production CI/CD should ideally also include:
- Automated tests
- Security scanning
- Build verification
- Deployment approval where appropriate
- Secrets management
- Health checks
- Rollback strategy
The goal isn't simply:
"Deploy automatically."
The goal is:
Deploy safely and repeatably.
8. Python and Node.js Need a Process Model
An application running manually from a terminal is not production architecture.
For Python:
Nginx
↓
Gunicorn
↓
Flask/Django
For Node.js:
Nginx
↓
Node.js
A process manager such as PM2 can help manage Node.js processes.
For Python applications, systemd plus Gunicorn is a common pattern.
The important principle is:
Your application should survive logout, crashes, and server reboots.
That means:
systemctl enable myapp
and:
Restart=always
are not cosmetic configuration.
They are operational resilience.
9. Redis: Fast Doesn't Mean Permanent
Redis is commonly used for:
- Caching
- Sessions
- Queues
- Counters
- Temporary application state
- Real-time workloads
A basic test:
redis-cli ping
Expected:
PONG
You should also understand dangerous commands.
For example:
redis-cli FLUSHALL
can delete all Redis data.
And:
redis-cli KEYS "*"
can become expensive on large production datasets.
A good administrator doesn't just know commands.
They know which commands not to run casually.
10. Elasticsearch: Search Is Different From a Database
Elasticsearch is designed around searching and analyzing large amounts of data.
Useful operational endpoints include:
curl localhost:9200
curl \
"localhost:9200/_cluster/health?pretty"
curl \
"localhost:9200/_cat/indices?v"
When troubleshooting, don't ask only:
"Is Elasticsearch running?"
Ask:
Is the service running?
Is port 9200 listening?
Is the cluster healthy?
Are nodes connected?
Are indices available?
Is disk space sufficient?
Are requests succeeding?
This is the difference between service checking and system troubleshooting.
11. Monitoring: If You Can't See It, You Can't Operate It
A server can be "up" while the application is effectively down.
For example:
CPU = 40%
RAM = 50%
Disk = 70%
Everything looks healthy.
But:
Database connections = exhausted
The application is down.
This is why production monitoring needs multiple layers.
Prometheus
Collects and stores metrics.
Grafana
Visualizes metrics.
Node Exporter
Exposes Linux system metrics.
Zabbix
Provides broader infrastructure monitoring and alerting.
The key lesson:
Monitoring should measure user-impacting health, not just server health.
12. Cloudflare Is More Than a CDN
Cloudflare can provide:
DNS
CDN
DDoS protection
WAF
TLS
Caching
Traffic filtering
A common architecture:
User
↓
Cloudflare
↓
Load Balancer
↓
Nginx
↓
Application
For production TLS, understand:
Flexible
Browser → HTTPS
Cloudflare → HTTP
Usually not desirable for secure applications.
Full
HTTPS between Cloudflare and origin, including self-signed certificates.
Full Strict
HTTPS end-to-end with a valid trusted origin certificate.
For production:
Full (Strict) is generally the preferred model.
13. Disaster Recovery Is Part of Being a Good Administrator
The worst backup is the one you've never tested.
A strong backup strategy follows the:
3-2-1 Rule
3 copies
2 different storage types
1 offsite copy
For example:
Production DB
↓
Local backup
↓
Cloud object storage
↓
Different region/provider
But backups alone aren't enough.
You need recovery procedures.
Ask:
"If this server disappears right now, how long until the application is running again?"
That question introduces two critical concepts:
RTO — Recovery Time Objective
How quickly must the service be restored?
RPO — Recovery Point Objective
How much data loss is acceptable?
Production infrastructure is not about preventing every failure.
It's about recovering intelligently when failure happens.
14. High Traffic Requires Architecture, Not Just Bigger Servers
When traffic increases, many administrators immediately think:
"Buy a bigger server."
That's vertical scaling.
Sometimes it works.
But eventually you need horizontal scaling.
Load Balancer
/ | \
/ | \
App 1 App 2 App 3
\ | /
\ | /
Database
|
Read Replica
Then add:
CDN
Caching
Redis
Connection pooling
Database replicas
Autoscaling
The goal is not to make one machine infinitely powerful.
The goal is to remove single points of failure and distribute work.
15. The Most Important Skill: Troubleshooting
Commands are easy to memorize.
Troubleshooting is harder.
Suppose a website returns:
502 Bad Gateway
Don't randomly restart everything.
Follow the path:
Client
↓
DNS
↓
Cloudflare
↓
Load Balancer
↓
Nginx
↓
Application
↓
Database
Check each layer.
For example:
dig example.com
curl -I https://example.com
systemctl status nginx
nginx -t
ss -tulpn
curl http://127.0.0.1:3000
journalctl -u myapp -n 100
docker ps
docker logs my-container
You're narrowing the failure domain.
That's what good troubleshooting looks like.
16. The Interview Mental Model
When an interviewer gives you a production problem, don't jump immediately to commands.
Use this framework:
1. Observe
What is the exact symptom?
2. Scope
Is one user affected?
One server?
One service?
The entire application?
3. Check
Look at:
Logs
Processes
Ports
CPU
Memory
Disk
Network
Dependencies
Configuration
4. Isolate
Find the first layer where reality differs from expectation.
5. Fix
Make the smallest safe change.
6. Verify
Confirm the service works.
7. Prevent
Add monitoring, automation, documentation, or configuration changes to prevent recurrence.
This framework works across:
Linux
AWS
Docker
Nginx
MySQL
Redis
Kubernetes
CI/CD
Final Lesson
You don't become a strong Linux or DevOps engineer by memorizing 1,000 commands.
You become one by understanding relationships.
Cloud
↓
Network
↓
Load Balancer
↓
Web Server
↓
Application
↓
Cache
↓
Database
↓
Storage
↓
Monitoring
↓
Backup
↓
Recovery
Then automate the boring parts.
Monitor the important parts.
Secure the dangerous parts.
Document the critical parts.
And test your recovery before production forces you to.
The best administrator isn't the person who knows the most commands.
It's the person who can look at a broken system, reduce the problem to a few possibilities, find the real cause, fix it safely, and make sure it doesn't happen again.
That is the skill worth building.
Part 6: Cloud Platforms, Docker, Git, CI/CD & Preferred Skills
6.1 Cloud Platforms (AWS, DigitalOcean, Azure)
AWS (Amazon Web Services)
# Key AWS services for server admins:
# EC2 - Virtual servers (VPS)
# S3 - Object storage (backups, static files)
# RDS - Managed databases
# Route53 - DNS management
# ELB - Load balancer
# CloudFront - CDN
# IAM - User access management
# VPC - Virtual private network
# AWS CLI setup
sudo apt install awscli
aws configure
# Enter: Access Key ID, Secret Access Key, Region, Output format
# EC2 operations
aws ec2 describe-instances # List all instances
aws ec2 start-instances --instance-ids i-1234567 # Start instance
aws ec2 stop-instances --instance-ids i-1234567 # Stop instance
aws ec2 reboot-instances --instance-ids i-1234567 # Reboot instance
# S3 operations (backups)
aws s3 ls # List buckets
aws s3 ls s3://my-bucket/ # List bucket contents
aws s3 cp backup.tar.gz s3://my-bucket/backups/ # Upload file
aws s3 sync /backups/ s3://my-bucket/backups/ # Sync directory
aws s3 cp s3://my-bucket/backups/backup.tar.gz ./ # Download file
# SSH to EC2
ssh -i ~/.ssh/my-key.pem ubuntu@ec2-ip-address
# Default users: ubuntu (Ubuntu), ec2-user (Amazon Linux), admin (Debian)
# Security Groups (AWS firewall)
# Configure in AWS Console or CLI:
aws ec2 authorize-security-group-ingress \
--group-id sg-12345 \
--protocol tcp \
--port 22 \
--cidr 203.0.113.0/24
DigitalOcean
# Key concepts:
# Droplets - Virtual servers
# Spaces - Object storage (like S3)
# Managed DB - Managed databases
# Load Balancers, Firewalls, Domains
# doctl CLI setup
sudo snap install doctl
doctl auth init # Enter API token
# Droplet operations
doctl compute droplet list # List all droplets
doctl compute droplet create my-server \
--size s-2vcpu-4gb \
--image ubuntu-22-04-x64 \
--region blr1 # Create droplet
# Firewall
doctl compute firewall create \
--name my-firewall \
--inbound-rules "protocol:tcp,ports:22,address:0.0.0.0/0 protocol:tcp,ports:80,address:0.0.0.0/0 protocol:tcp,ports:443,address:0.0.0.0/0"
# Snapshots (backup)
doctl compute droplet-action snapshot DROPLET_ID --snapshot-name "pre-migration-backup"
# DigitalOcean console access
# Through web console when SSH is locked out
Azure
# Key services:
# Virtual Machines - Compute
# Blob Storage - Object storage
# Azure SQL - Managed databases
# Azure DNS - DNS management
# Azure CDN - Content delivery
# Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az login
# VM operations
az vm list --output table
az vm start --name myVM --resource-group myRG
az vm stop --name myVM --resource-group myRG
az vm restart --name myVM --resource-group myRG
VPS vs Cloud vs Dedicated Servers
| Feature | VPS | Cloud (AWS/DO/Azure) | Dedicated |
|---|---|---|---|
| Cost | Low ($5-50/mo) | Pay-as-you-go | High ($100+/mo) |
| Scalability | Limited | Instant scaling | Hardware limited |
| Performance | Shared resources | Variable | Full resources |
| Management | Self-managed | Managed options | Self-managed |
| Use case | Small-medium sites | Scalable apps | High-performance |
Interview Q&A: Cloud
| Question | Answer |
|---|---|
| Difference between VPS and cloud? | VPS is a fixed virtual server. Cloud is scalable infrastructure (can add/remove resources instantly) |
| What is an EC2 instance? | AWS virtual server. You choose CPU, RAM, storage, OS |
| What is S3? | AWS object storage. Unlimited storage for files, backups, static assets |
| What are Security Groups in AWS? | Virtual firewall rules for EC2 instances. Control inbound/outbound traffic |
| How do you access a cloud server? | SSH with key pair. AWS uses .pem files, DigitalOcean uses SSH keys |
| What is auto-scaling? | Automatically adds/removes servers based on traffic/load |
6.2 Cloudflare & CDN
Cloudflare Setup
# Setup steps:
# 1. Create Cloudflare account
# 2. Add your domain
# 3. Change nameservers at domain registrar to Cloudflare NS
# 4. Configure DNS records in Cloudflare dashboard
# Cloudflare provides:
# - CDN (cache static files at edge locations)
# - DDoS protection
# - WAF (Web Application Firewall)
# - Free SSL (Flexible, Full, Full Strict)
# - DNS management
# - Page Rules
# - Caching Rules
Cloudflare SSL Modes
| Mode | Description | When to use |
|---|---|---|
| Off | No SSL | Never |
| Flexible | HTTPS browser→CF, HTTP CF→server | No SSL on origin (not recommended) |
| Full | HTTPS everywhere, self-signed OK | Self-signed cert on origin |
| Full (Strict) | HTTPS everywhere, valid cert required | Recommended with Let's Encrypt |
Cloudflare Configuration Tips
# Page Rules examples:
# Force HTTPS: URL pattern *.example.com/* → Always Use HTTPS
# Cache everything: URL pattern *.example.com/static/* → Cache Level: Cache Everything
# Common Cloudflare DNS settings:
# Type | Name | Value | Proxy Status
# A | @ | YOUR_SERVER_IP | Proxied (orange cloud)
# A | www | YOUR_SERVER_IP | Proxied (orange cloud)
# A | api | YOUR_SERVER_IP | DNS only (grey cloud - for websockets/SSH)
# Getting real visitor IP behind Cloudflare (Nginx)
# Install ngx_http_realip_module, then:
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
# ... (add all Cloudflare IP ranges)
real_ip_header CF-Connecting-IP;
# Apache: Install mod_remoteip
RemoteIPHeader CF-Connecting-IP
Interview Q&A: CDN
| Question | Answer |
|---|---|
| What is a CDN? | Content Delivery Network. Caches content at edge servers globally for faster delivery |
| What does Cloudflare do? | CDN, DDoS protection, WAF, DNS, SSL, performance optimization |
| What is "Full (Strict)" SSL? | Encrypts traffic end-to-end and requires a valid SSL certificate on the origin server |
| How do you see the real client IP behind Cloudflare? | Use CF-Connecting-IP header. Configure real_ip_header in Nginx or mod_remoteip in Apache |
| How to bypass Cloudflare for debugging? | Use DNS-only mode (grey cloud) or add server IP to local hosts file |
| What are Cloudflare Page Rules? | URL-based rules for caching, redirects, SSL mode, and other behavior per URL pattern |
6.3 Docker & Containerization
Docker Basics
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER # Add user to docker group
# Log out and log back in
# Docker commands
docker ps # List running containers
docker ps -a # List all containers (including stopped)
docker images # List images
docker pull nginx # Download image
docker pull php:8.2-fpm # Specific version
# Run containers
docker run -d --name my-nginx -p 80:80 nginx # Run Nginx
docker run -d --name my-mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=secret \
-v mysql_data:/var/lib/mysql mysql:8.0 # Run MySQL with volume
# Container management
docker start container_name
docker stop container_name
docker restart container_name
docker rm container_name # Remove stopped container
docker rm -f container_name # Force remove running container
docker logs container_name # View logs
docker logs -f container_name # Follow logs
docker exec -it container_name bash # Shell into container
docker inspect container_name # Detailed info
# Clean up
docker system prune -a # Remove unused images, containers, networks
docker volume prune # Remove unused volumes
Docker Compose (Multi-Container Apps)
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/var/www/html
depends_on:
- php
restart: always
php:
image: php:8.2-fpm
volumes:
- ./html:/var/www/html
restart: always
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: apppassword
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
restart: always
redis:
image: redis:alpine
ports:
- "6379:6379"
restart: always
volumes:
mysql_data:
# Docker Compose commands
docker compose up -d # Start all services
docker compose down # Stop all services
docker compose restart # Restart all services
docker compose logs # View all logs
docker compose logs -f php # Follow specific service logs
docker compose exec php bash # Shell into specific service
docker compose ps # List services
docker compose pull # Pull latest images
docker compose build # Build images (if using Dockerfile)
Dockerfile (Custom Image)
# Dockerfile
FROM php:8.2-fpm
# Install extensions
RUN docker-php-ext-install pdo pdo_mysql mysqli mbstring
# Install additional tools
RUN apt-get update && apt-get install -y \
curl \
zip \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Copy application
COPY . /var/www/html
WORKDIR /var/www/html
# Set permissions
RUN chown -R www-data:www-data /var/www/html
EXPOSE 9000
CMD ["php-fpm"]
Interview Q&A: Docker
| Question | Answer |
|---|---|
| What is Docker? | Platform for building, shipping, and running apps in containers. Lightweight isolated environments |
| Container vs VM? | Container shares host kernel (lightweight, fast). VM has its own kernel (heavier, more isolation) |
| What is Docker Compose? | Tool for defining multi-container apps in YAML. Start all services with one command |
| What is a volume? | Persistent storage for containers. Data survives container restarts/deletion |
| How to debug a container? |
docker logs, docker exec -it container bash, docker inspect
|
| What is a Dockerfile? | Blueprint for building a custom Docker image. Defines base image, dependencies, files, commands |
6.4 Git & GitHub
Git Basics for Server Admin
# Install Git
sudo apt install git
# Configure Git
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
# Clone repository
git clone https://github.com/company/website.git
git clone git@github.com:company/website.git # SSH (preferred for deployments)
# Basic workflow
git status # Check changes
git pull origin main # Pull latest changes
git add . # Stage all changes
git commit -m "Fix: update config" # Commit
git push origin main # Push changes
# Branches
git branch # List branches
git branch -a # List all (including remote)
git checkout main # Switch to main
git checkout -b feature/new-feature # Create and switch to new branch
git merge feature/new-feature # Merge branch into current
git branch -d feature/new-feature # Delete branch
# View history
git log --oneline -10 # Last 10 commits
git log --oneline --graph # Visual branch history
git diff # View unstaged changes
git diff --cached # View staged changes
# Stash changes
git stash # Save changes temporarily
git stash pop # Restore stashed changes
# Undo changes
git checkout -- file.txt # Discard file changes
git reset --hard HEAD # Discard ALL uncommitted changes
git revert abc1234 # Create new commit that undoes a commit
Deployment Workflows
# Simple Git Pull Deployment (basic)
# On server:
cd /var/www/html
git pull origin main
# Fix permissions, restart services if needed
# Deploy Script (/usr/local/bin/deploy.sh)
#!/bin/bash
set -e
APP_DIR="/var/www/html"
BRANCH="main"
echo "Starting deployment..."
cd $APP_DIR
# Pull latest code
git fetch origin
git reset --hard origin/$BRANCH
# Install dependencies
composer install --no-dev --optimize-autoloader # PHP
# OR
npm install --production # Node.js
# Build assets (if applicable)
npm run build
# Clear caches
php artisan cache:clear # Laravel
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Run migrations
php artisan migrate --force
# Fix permissions
chown -R www-data:www-data $APP_DIR
chmod -R 755 $APP_DIR
# Restart services
sudo systemctl reload php8.2-fpm
sudo systemctl reload nginx
echo "Deployment complete!"
SSH Keys for GitHub (Server Deployment)
# Generate deploy key on server
ssh-keygen -t ed25519 -C "server-deploy-key" -f ~/.ssh/github_deploy
# Add public key to GitHub repo → Settings → Deploy Keys
cat ~/.ssh/github_deploy.pub
# Configure SSH to use this key for GitHub
cat >> ~/.ssh/config << EOF
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github_deploy
EOF
# Test connection
ssh -T git@github.com
6.5 Deploying Python & Node.js Applications
Python (Flask/Django) Deployment
# Install Python
sudo apt install python3 python3-pip python3-venv
# Create virtual environment
cd /var/www/myapp
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Install Gunicorn (WSGI server)
pip install gunicorn
# Test run
gunicorn --bind 0.0.0.0:8000 app:app # Flask
gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application # Django
# Create systemd service
sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My Python Application
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
ExecStart=/var/www/myapp/venv/bin/gunicorn --workers 3 --bind unix:myapp.sock app:app
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
# Nginx config for Python app
server {
listen 80;
server_name myapp.com;
location / {
proxy_pass http://unix:/var/www/myapp/myapp.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
alias /var/www/myapp/static;
}
}
Node.js Deployment
# Install Node.js (using nvm - recommended)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install 20 # Install Node.js 20 LTS
nvm use 20
# OR via apt
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install nodejs
# Deploy app
cd /var/www/nodeapp
npm install --production
npm run build # If build step needed
# Process Manager - PM2 (recommended for production)
sudo npm install -g pm2
pm2 start app.js --name "my-app" # Start app
pm2 start npm --name "my-app" -- start # Start with npm start
pm2 list # List all apps
pm2 logs # View logs
pm2 restart my-app # Restart
pm2 stop my-app # Stop
pm2 delete my-app # Remove
pm2 monit # Real-time monitoring
# PM2 auto-start on reboot
pm2 startup # Generate startup script
pm2 save # Save current process list
# Nginx config for Node.js
server {
listen 80;
server_name nodeapp.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
}
}
6.6 Redis & Elasticsearch
Redis
# Install Redis
sudo apt install redis-server
# Configure
sudo nano /etc/redis/redis.conf
# Key settings:
# bind 127.0.0.1 # Listen on localhost only
# requirepass YourStrongPassword # Set password
# maxmemory 256mb # Max memory usage
# maxmemory-policy allkeys-lru # Eviction policy
sudo systemctl restart redis
sudo systemctl enable redis
# Redis CLI
redis-cli
redis-cli -a YourPassword # With password
# Basic commands
redis-cli ping # Test connection → PONG
redis-cli INFO # Server info
redis-cli INFO memory # Memory usage
redis-cli DBSIZE # Number of keys
redis-cli FLUSHALL # Clear all data (CAREFUL!)
redis-cli MONITOR # Real-time command monitoring
# Key operations
redis-cli SET mykey "Hello"
redis-cli GET mykey
redis-cli DEL mykey
redis-cli KEYS "*" # List all keys (don't use in production)
Elasticsearch
# Install Elasticsearch
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
sudo apt install elasticsearch
# Configure
sudo nano /etc/elasticsearch/elasticsearch.yml
# Key settings:
# cluster.name: my-cluster
# node.name: node-1
# network.host: 127.0.0.1
# http.port: 9200
sudo systemctl start elasticsearch
sudo systemctl enable elasticsearch
# Test
curl -X GET "localhost:9200" # Check cluster health
curl -X GET "localhost:9200/_cluster/health?pretty"
curl -X GET "localhost:9200/_cat/indices?v" # List indices
6.7 CI/CD & Automated Deployment
GitHub Actions (Simple CI/CD)
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/html
git pull origin main
composer install --no-dev
php artisan migrate --force
php artisan cache:clear
sudo systemctl reload php8.2-fpm
Webhook-Based Deployment
# Simple webhook server for auto-deploy on git push
# Install webhook tool
sudo apt install webhook
# /etc/webhook.conf
[
{
"id": "deploy",
"execute-command": "/usr/local/bin/deploy.sh",
"command-working-directory": "/var/www/html",
"pass-arguments-to-command": [],
"trigger-rule": {
"match": {
"type": "value",
"value": "your-webhook-secret",
"parameter": {
"source": "header",
"name": "X-Hub-Signature"
}
}
}
}
]
6.8 Monitoring Tools (Grafana, Prometheus, Zabbix)
Quick Overview
| Tool | Purpose | Key Feature |
|---|---|---|
| Prometheus | Metrics collection & storage | Pull-based, time-series DB |
| Grafana | Visualization & dashboards | Beautiful graphs, alerts |
| Zabbix | Full monitoring platform | All-in-one, agent-based |
| Nagios | Infrastructure monitoring | Alerting, legacy but stable |
| Netdata | Real-time monitoring | Zero config, instant dashboards |
Prometheus + Grafana Stack (Most Popular)
# Install Node Exporter (on each server to monitor)
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xvfz node_exporter-*.tar.gz
sudo mv node_exporter-*/node_exporter /usr/local/bin/
# Create systemd service
sudo nano /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=nobody
ExecStart=/usr/local/bin/node_exporter
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start node_exporter
sudo systemctl enable node_exporter
# Metrics available at http://server:9100/metrics
# Install Grafana
sudo apt install -y apt-transport-https software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install grafana
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
# Access Grafana at http://server:3000 (default: admin/admin)
Quick Monitoring with Netdata (Easiest)
# One-line install
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# Dashboard available at http://server:19999
# Real-time CPU, RAM, disk, network, processes - zero config
6.9 Disaster Recovery
Disaster Recovery Plan
1. DOCUMENT EVERYTHING
- Server IPs, hostnames, OS versions
- All software versions and configurations
- DNS records for all domains
- Database credentials
- SSL certificate details
- Contact info for providers
2. BACKUP STRATEGY (3-2-1 Rule)
- 3 copies of all critical data
- 2 different storage types (local + cloud)
- 1 offsite copy (different region/provider)
3. AUTOMATED BACKUPS
- Daily database backups (retained 30 days)
- Weekly full server backups (retained 3 months)
- Real-time replication for critical databases
4. RECOVERY PROCEDURES
- Document step-by-step recovery for each service
- Test recovery quarterly
- Maintain runbooks for common failure scenarios
5. MONITORING & ALERTS
- Uptime monitoring (UptimeRobot, Pingdom)
- Resource alerts (CPU > 80%, disk > 90%, RAM > 85%)
- SSL expiry alerts (30 days before)
Recovery Commands Quick Reference
# Server won't boot → Use provider's console/recovery mode
# Restore from backup
# 1. Provision new server
# 2. Install same software stack
# 3. Restore files from backup
tar -xzf www_backup.tar.gz -C /var/www/
# 4. Restore databases
gunzip < all_databases.sql.gz | mysql -u root -p
# 5. Restore configurations
tar -xzf configs.tar.gz -C /etc/
# 6. Fix permissions
chown -R www-data:www-data /var/www/
# 7. Restart all services
systemctl restart nginx php8.2-fpm mysql
# 8. Update DNS if IP changed
# 9. Verify SSL certificates
# 10. Test all websites and services
6.10 Handling High-Traffic Infrastructure
# Performance optimization checklist for high traffic:
# 1. Enable caching
# - OPcache for PHP (bytecode caching)
# - Redis/Memcached for application caching
# - Nginx fastcgi_cache or proxy_cache
# - Cloudflare CDN for static assets
# 2. Optimize Nginx for high traffic
worker_processes auto;
worker_connections 4096;
multi_accept on;
use epoll;
# 3. PHP-FPM tuning
pm = static # Or dynamic for variable traffic
pm.max_children = 100 # Based on available RAM
# Formula: max_children = (Total RAM - Other Services RAM) / PHP avg memory
# 4. MySQL optimization
innodb_buffer_pool_size = 4G # 60-70% of RAM for dedicated DB
innodb_log_file_size = 512M
max_connections = 500
query_cache_type = 0 # Disabled in MySQL 8.0
# 5. OS-level tuning
# /etc/sysctl.conf
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
fs.file-max = 65535
# Apply: sysctl -p
# 6. Connection pooling
# Use ProxySQL or PgBouncer for database connection pooling
# 7. Horizontal scaling
# Load balancer (Nginx, HAProxy, AWS ELB) distributing traffic
# Multiple app servers behind load balancer
# Read replicas for database
Interview Q&A: Preferred Skills
| Question | Answer |
|---|---|
| Docker vs VM? | Docker: lightweight, shares kernel, fast startup. VM: full OS, more isolation, heavier |
| What is PM2? | Node.js process manager. Auto-restarts, clustering, log management |
| What is Gunicorn? | Python WSGI HTTP server. Runs Python apps, manages worker processes |
| Git pull vs Git fetch? |
pull = fetch + merge (updates working code). fetch = download changes only (doesn't change files) |
| What is Redis used for? | In-memory cache, session storage, queues, real-time data. Very fast |
| What is CI/CD? | Continuous Integration (auto test) / Continuous Deployment (auto deploy). Automates the release pipeline |
| How to handle sudden traffic spike? | Scale vertically (bigger server), scale horizontally (more servers + load balancer), enable caching, use CDN |
| What is Prometheus? | Open-source monitoring system. Collects metrics via HTTP pull model, stores in time-series DB |
| What is Grafana? | Visualization platform. Creates dashboards from Prometheus/other data sources |
Top comments (0)