DevOps Basics — Quick Summary
Quick revision: every topic, key terms, and mnemonics for DevOps Basics.
This is a quick revision doc covering all 18 topics in the DevOps Basics collection. These are the interview essentials — open the linked notes if you want depth.
Networking Fundamentals
How DNS Works
What it is. DNS is the internet’s phone book — translates google.com into an IP like 142.250.190.14.
Key terms.
- Recursive resolver — ISP/Cloudflare/Google DNS doing the lookup
- Root → TLD → Authoritative NS — the resolver walks down this chain
- A — IPv4 mapping; AAAA — IPv6
- CNAME — alias to another domain
- MX — mail server (with priority)
- TXT — verification, SPF, DKIM
- NS — authoritative nameservers
- TTL — cache duration in seconds; DNS propagation — time for changes to spread
Commands.
dig pman47.cc +short
dig pman47.cc MX
dig @8.8.8.8 pman47.cc
nslookup -type=MX pman47.cc
Remember. Lower TTL the day before a migration. After changes, verify with dig. CNAMEs can’t sit at root domain.
Networking Basics for Devs
What it is. IP addresses identify machines, ports identify services on a machine, TCP/UDP move the data.
Key terms.
- IPv4 — 4 numbers, 0-255, ~4.3B total
- IPv6 — 8 hex groups, practically infinite
- Private ranges — 10.x, 172.16-31.x, 192.168.x
- NAT — router gives one public IP, hands private IPs internally
- Ports — 0-65535. 22 SSH, 80 HTTP, 443 HTTPS, 5432 Postgres, 6379 Redis, 27017 Mongo
- TCP — reliable, ordered, 3-way handshake; UDP — fire and forget, fast
- 127.0.0.1 — loopback (only this machine)
- 0.0.0.0 — all interfaces (needed in Docker)
- localhost — typically resolves to 127.0.0.1
URL flow. DNS lookup → TCP handshake → TLS handshake → HTTP request → response → render.
Remember. Docker container can’t be reached from host? Bind to 0.0.0.0, not 127.0.0.1. lsof -i :3000 finds who owns a port.
SSL, TLS & HTTPS
What it is. TLS encrypts traffic between browser and server. HTTPS = HTTP + TLS.
Key terms.
- SSL — old, dead. TLS — current (1.2/1.3)
- Handshake — Client Hello → Server Hello + cert → key exchange → encrypted
- TLS 1.3 — 1 RTT (vs 2 in TLS 1.2), even 0-RTT for repeats
- Certificate — proves “I am who I claim to be”
- CA — Certificate Authority (signs certs)
- Let’s Encrypt — free automated CA
- Certbot / Caddy / mkcert — tools to auto-issue
- Self-signed cert — for local dev (browser will warn)
- Mixed content — HTTPS page loading HTTP resource = blocked
- Encryption in transit (TLS) ≠ at rest (disk encryption)
Code.
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
-sha256 -days 365 -nodes -subj "/CN=localhost"
Remember. “SSL cert” usually means TLS cert. Caddy auto-issues + auto-renews. Padlock = TLS cert signed by trusted CA.
SSH Basics
What it is. Encrypted remote shell access — every server admin uses it daily.
Key terms.
- Password auth — bad (brute-force, repeated typing)
- Key-based auth — public key on server, private key on our machine
- Ed25519 — modern, fast, short keys
~/.ssh/config— host shortcutsssh-copy-id— install public key on serverProxyJump— go through bastion host- Local port forwarding —
ssh -L local:host:remote(access remote DB as if local) - Permissions —
~/.ssh700, private key 600
Commands.
ssh-keygen -t ed25519 -C "me@example.com"
ssh-copy-id user@server
ssh -L 5432:localhost:5432 -N user@server # tunnel only
ssh -vvv user@server # debug
chmod 600 ~/.ssh/id_ed25519
Remember. “Permission denied (publickey)” = wrong key, wrong file perms, or key not in authorized_keys. Use ~/.ssh/config so we never type long commands.
HTTP & Web Protocols
HTTP Methods, Status Codes & Headers
What it is. Request-response language of the web.
Key terms.
- Method — GET (read, safe), POST (create, not idempotent), PUT (replace, idempotent), PATCH (partial update), DELETE (idempotent)
- Safe — no server changes (GET, HEAD)
- Idempotent — same call N times = same result
- Status families — 1xx info, 2xx success, 3xx redirect, 4xx client, 5xx server
- Common headers — Content-Type, Accept, Authorization, Cookie, Set-Cookie, Cache-Control
Status codes cheat sheet.
| Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created (POST success) |
| 204 | No Content (DELETE success) |
| 301 | Moved Permanently |
| 302 | Found (temporary) |
| 304 | Not Modified |
| 400 | Bad Request |
| 401 | Unauthorized (not logged in) |
| 403 | Forbidden (logged in, not allowed) |
| 404 | Not Found |
| 409 | Conflict (duplicate) |
| 422 | Unprocessable (validation) |
| 429 | Too Many Requests |
| 500 | Internal Error |
| 502 | Bad Gateway |
| 503 | Service Unavailable |
Remember. POST is the only common method that’s neither safe nor idempotent. 401 = “who are you,” 403 = “I know, you can’t.” curl -v shows full request+response.
CORS
What it is. Browser security: page A’s JS can only call page A’s origin unless the server opts in.
Key terms.
- Origin = protocol + domain + port (all three must match)
- Same-Origin Policy — browser-enforced, blocks cross-origin reads
- CORS — server-side opt-in via response headers
- Simple request — GET/HEAD/POST + standard headers, no preflight
- Preflight — OPTIONS request first (“can I POST JSON?”)
Access-Control-Allow-Origin— specific origin or*Access-Control-Allow-Methods/Headers/Credentials/Max-Age
The credentials gotcha. With credentials: include, server can NOT use Allow-Origin: *. Must specify exact origin.
Dev fix. Vite/CRA proxy: /api/* → http://localhost:8080, browser thinks same-origin.
Remember. CORS is browser-only — curl doesn’t enforce it. JSON Content-Type triggers preflight. Custom headers (Authorization) trigger preflight.
REST API Design Basics
What it is. Conventions making APIs predictable: URLs are nouns, methods are verbs.
Key terms.
- Resources —
/users(collection),/users/42(single) - CRUD ↔ HTTP — GET/POST/PUT/PATCH/DELETE
- Path params — identify a specific resource (
/users/42) - Query params — filter/sort/paginate (
?status=active&sort=-createdAt) - Body — data payload for create/update
- Pagination — offset-based (simple, slow at scale) vs cursor-based (stable)
- Versioning —
/v1/users(URL, common) or Accept header - Sort syntax —
sort=-fieldfor descending
Remember. No verbs in URLs (/createUser is bad). Keep nesting ≤ 2 levels deep. Use 422 for validation errors, 409 for conflicts.
Proxy & Reverse Proxy
What it is. A middleman server. Forward proxy hides clients; reverse proxy hides servers.
Key terms.
- Forward proxy — VPN, corporate filter, Tor
- Reverse proxy — Nginx, HAProxy, Caddy, CDN
- SSL termination — proxy does TLS, backend gets plain HTTP
- Common reasons — load balancing, caching, security, compression, hide internal IPs
X-Forwarded-For— passes real client IP through proxy- CDN — globally distributed reverse proxy
Code.
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Remember. Forward = client’s mask. Reverse = servers’ mask. Almost every prod app sits behind a reverse proxy.
Servers & Infrastructure
Linux Commands Every Dev Should Know
What it is. The minimum CLI we need to function on any server.
Key terms.
- Navigation —
pwd,ls -la,cd,cd - - Read —
cat,less,head,tail -f(follow logs) - Manipulate —
cp,mv,mkdir -p,rm -rf(be careful!) - Permissions —
chmod 755/644/600,chown user:group - Process —
ps aux,top/htop,kill,lsof -i :PORT - Search —
grep -rni,find . -name - Pipes —
cmd | grep | wc -l - Env —
export VAR=val,echo $PATH,source ~/.bashrc - Network —
curl,ss -tlnp,ping,nslookup
Remember. chmod 755 for scripts, 644 for configs, 600 for keys. tail -f log is a daily friend. man <cmd> is the universal helper.
Web Servers — Nginx & Apache
What it is. Listens on a port, receives HTTP, sends responses (static or proxied).
Key terms.
- Apache — process-per-request, .htaccess flexible, older
- Nginx — event-driven async, handles 10k+ connections per worker
- Config blocks —
http→server→location try_files $uri $uri/ /index.html— SPA fallback (critical!)proxy_pass— forward to backend- SSL termination —
listen 443 ssl+ cert paths nginx -t— test config (always before reload!)systemctl reload nginx— zero-downtime reload
Remember. Nginx for high concurrency / static / reverse proxy. Apache where .htaccess matters. Test config before reload — bad config takes down the site.
Load Balancing Basics
What it is. Spread traffic across multiple servers for capacity + resilience.
Key terms.
- Algorithms — Round Robin, Least Connections, IP Hash, Weighted RR
- L4 — IP+port, fast, blind to HTTP
- L7 — URL/headers/cookies aware, smarter
- Health checks — pull dead servers from pool
- Sticky sessions — same user → same server (avoid; use Redis)
- Horizontal scaling — more servers (preferred)
- Vertical scaling — bigger server (single point of failure)
Code.
upstream api_servers {
least_conn;
server 10.0.0.1:3000 weight=3;
server 10.0.0.2:3000;
server 10.0.0.3:3000 backup;
}
Remember. Make apps stateless (Redis sessions) so any server handles any request — no sticky needed. Health checks are non-optional in prod.
Caching — Browser, CDN & Server
What it is. Store data closer to where it’s needed. Single biggest perf win.
Key terms.
- Layers — browser (~0ms) → CDN (~20ms) → Redis (~1ms) → DB (~10-100ms)
- Cache-Control —
max-age,public/private,no-cache(revalidate),no-store(never),immutable - ETag — content fingerprint; if matches, server returns 304 with no body
- CDN — globally distributed reverse proxy (Cloudflare, CloudFront, Fastly)
- Cache busting — versioned filename
style.abc123.css - Purge API — drop CDN cache on demand
- Redis — in-memory KV store on server (~1ms reads)
- Cache stampede — many simultaneous misses hammer DB; fix with locks or pre-warming
Code.
# static asset, cache 1 year
Cache-Control: public, max-age=31536000, immutable
# user-specific data
Cache-Control: private, no-cache
# secrets
Cache-Control: no-store
Remember. Three rules: TTL must match staleness tolerance. Never public for personalized data. Cache-bust via filename hash, not URL query.
Docker & Containers
Docker Basics
What it is. Package app + everything it needs into a container. “Works on my machine” → works everywhere.
Key terms.
- Image — read-only blueprint
- Container — running instance of image (image:class :: container:object)
- Docker Hub — npm for images
- Port mapping —
-p HOST:CONTAINER - Volume — persistent storage; bind mount (host path) vs named volume (Docker-managed)
- Alpine images — 5-10x smaller (use them by default)
Commands.
docker run -d --name app -p 3000:3000 node:20-alpine
docker ps -a
docker logs -f app
docker exec -it app sh
docker stop app && docker rm app
docker run -d -v pgdata:/var/lib/postgresql/data postgres:15
Remember. Containers are ephemeral — without volumes, data dies. Named volumes for prod (Docker manages path), bind mounts for dev (live code).
Writing a Dockerfile
What it is. Recipe for building an image, layer by layer.
Key terms.
- FROM — base image
- WORKDIR —
cdfor build - COPY — files from host into image
- RUN — execute during build
- CMD — default command at start
- EXPOSE — port documentation (no actual opening)
- ENV — runtime env vars (don’t bake secrets!)
- ARG — build-time only
- Layer caching — change one layer = rebuild everything below it
- Multi-stage build — build in one stage, copy to slim runtime stage
- .dockerignore — keep junk (node_modules, .git, .env) out of build context
Code.
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/server.js"]
Remember. Copy package.json BEFORE source — keeps npm install cached when only code changes. Combine related RUNs with && to reduce layers.
Docker Compose
What it is. Define multi-container apps in one YAML, start with one command.
Key terms.
- services — each container
- build vs image — build from Dockerfile or pull image
- depends_on — startup order (only starts container, not service inside!)
- healthcheck + condition: service_healthy — proper readiness wait
- env_file — load
.env - named volumes — at top level, referenced in services
- DNS by service name —
db:5432,redis:6379(not localhost)
Code.
services:
api:
build: .
ports: ["3000:3000"]
env_file: [.env]
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASS}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
retries: 5
volumes:
pgdata:
Commands. docker compose up -d, down [-v], logs -f [svc], exec, ps, up -d --build.
Remember. Service name = hostname inside the network. depends_on alone doesn’t wait for service ready — use healthchecks.
CI/CD & Operations
Environment Variables & Configuration
What it is. Config outside code, different per environment. Same code runs everywhere.
Key terms.
process.env.X(Node),os.environ.get(Python)- dotenv — loads
.envinto env vars .env.example— committed;.env— gitignored- 12-factor app — config in env, not code
- Docker —
-e VAR=val,--env-file,environment:/env_file:in compose - CI secrets — GitHub Secrets, GitLab Variables; encrypted, masked in logs
ARGvsENVin Dockerfile — ARG is build-time only
Code.
require("dotenv").config();
const port = process.env.PORT || 3000;
Remember. Never put secrets in Dockerfile ENV — they get baked in. If we leak a secret in git, ROTATE it (don’t just delete commit). .env always in .gitignore.
CI/CD
What it is. Auto build/test/deploy on every push.
Key terms.
- CI — push triggers automatic lint+test+build
- Continuous Delivery — always deployable, human triggers
- Continuous Deployment — auto deploy on green
- Workflow / Job / Step / Action / Runner (GitHub Actions vocab)
needs:— sequential job dependencyif: github.ref == 'refs/heads/main'— branch gating- secrets —
${{ secrets.NAME }} - Cache —
cache: 'npm'keyed onpackage-lock.json
Code.
on:
push: { branches: [main] }
pull_request:
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: npm }
- run: npm ci
- run: npm run lint
- run: npm test
deploy:
needs: ci
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh
Remember. Main branch is always deployable. PR runs CI; merge runs CD. Cache deps to keep builds fast.
Logging & Monitoring Basics
What it is. Know what’s happening before users tell us.
Key terms.
- Logging — what happened (events, errors, decisions)
- Log levels — debug, info, warn, error, fatal
- Structured logs — JSON, searchable, filterable
- Centralized logging — ELK, CloudWatch, Datadog, Loki+Grafana
- Monitoring — what’s happening NOW (metrics, real-time)
- Key metrics — response time (p50/p95/p99), error rate, uptime, CPU/mem, RPS
- Health check —
/health(liveness) vs/ready(deps healthy too) - Alerting — wakes us up when monitoring detects problems
- Rate limiting — token bucket / sliding window; respond 429 +
Retry-After
Code.
app.get("/ready", async (req, res) => {
try {
await db.query("SELECT 1");
await redis.ping();
res.status(200).json({ status: "ok", uptime: process.uptime() });
} catch (err) {
res.status(503).json({ status: "degraded", error: err.message });
}
});
Remember. Logs answer “what happened?”, metrics answer “is it healthy now?”, alerts answer “wake me up.” Always JSON logs in prod, set level to info. p99 latency matters more than average.