DevOps for Developers
CI/CD, IaC, GitOps, observability, and the DevOps culture and toolchain.
Overview
DevOps is a culture and set of practices that unites software development (Dev) and IT operations (Ops) to deliver software faster and more reliably. The core idea: instead of developers writing code and then 'throwing it over the wall' to operations to deploy, both teams collaborate throughout the entire lifecycle — from writing code to monitoring it in production. Key DevOps practices: Continuous Integration (CI), Continuous Delivery (CD), Infrastructure as Code (IaC), automated testing, and observability.
CI/CD (Continuous Integration / Continuous Delivery) is the backbone of DevOps. Continuous Integration: every time code is pushed to GitHub, an automated pipeline runs tests, linting, and a build — catching bugs within minutes. Continuous Delivery: every successful build is automatically deployed to staging, and with approval, to production. This replaces manual, error-prone deployments. Popular CI/CD tools: GitHub Actions (free for open source), Jenkins (self-hosted), GitLab CI, and CircleCI. A typical pipeline: code push → test → build Docker image → push to registry → deploy to Kubernetes.
Microservices architecture structures an application as a collection of small, independently deployable services — each with a single responsibility, its own database, and its own deployment cycle. Communication between microservices: REST APIs (synchronous, simple) or message brokers like Redis Pub/Sub or RabbitMQ (asynchronous, decoupled). Challenges: service discovery, distributed tracing, network latency, and eventual consistency. Observability is essential for production: Logs (what happened — structured JSON), Metrics (how the system performs — Prometheus/Grafana), and Traces (distributed request flow across services — Jaeger/OpenTelemetry).
Code Example
# .github/workflows/deploy.yml
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# ── Job 1: Test ───────────────────────────────
test:
name: Test & Lint
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 -- --coverage --ci
- name: Upload coverage
uses: codecov/codecov-action@v3
# ── Job 2: Build & Push Docker Image ─────────
build:
name: Build Docker Image
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # only on main branch
steps:
- uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# ── Job 3: Deploy to Kubernetes ───────────────
deploy:
name: Deploy to Production
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up kubectl
uses: azure/setup-kubectl@v3
- name: Configure kubeconfig
run: echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > ~/.kube/config
- name: Update deployment image
run: |
kubectl set image deployment/devonix-api \
api=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \
-n production
kubectl rollout status deployment/devonix-api -n productionTest Your Knowledge
Ready to test what you've learned? Take the quiz with 10 questions and see your score.