Docker Compose Patterns for Production

Docker Compose is often dismissed as “just for development,” but with the right patterns it handles production workloads well. Here are patterns that have survived contact with real systems. Service Dependencies Done Right The basic depends_on only waits for the container to start, not for the service to be ready: 1 2 3 4 5 6 7 # This doesn't guarantee postgres is accepting connections services: app: depends_on: - db db: image: postgres:15 Use health checks for real dependency management: ...

March 5, 2026 Â· 4 min Â· 832 words Â· Rob Washington

Systemd Service Hardening: Security Beyond the Defaults

Most systemd service files are written for functionality, not security. The defaults give services more access than they need—full filesystem visibility, network capabilities, and the ability to spawn processes anywhere. A few directives can dramatically reduce the blast radius if that service gets compromised. The Security Baseline Start with this template for any service that doesn’t need special privileges: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [Service] # Run as dedicated user User=myservice Group=myservice # Filesystem restrictions ProtectSystem=strict ProtectHome=true PrivateTmp=true ReadWritePaths=/var/lib/myservice # Network restrictions (if service doesn't need network) # PrivateNetwork=true # Capability restrictions NoNewPrivileges=true CapabilityBoundingSet= AmbientCapabilities= # System call filtering SystemCallArchitectures=native SystemCallFilter=@system-service SystemCallFilter=~@privileged @resources # Additional hardening ProtectKernelTunables=true ProtectKernelModules=true ProtectKernelLogs=true ProtectControlGroups=true RestrictRealtime=true RestrictSUIDSGID=true MemoryDenyWriteExecute=true LockPersonality=true Understanding Each Directive Filesystem Protection 1 ProtectSystem=strict Mounts /usr, /boot, and /efi read-only. The strict level also makes /etc read-only. Use full if the service needs to write to /etc. ...

March 5, 2026 Â· 4 min Â· 836 words Â· Rob Washington

Cloudflare Tunnels: Expose Local Services Without Port Forwarding

Port forwarding is a security liability. Opening ports means exposing your network, managing firewall rules, and hoping your ISP doesn’t change your IP. Cloudflare Tunnels solve this elegantly—your services connect outbound to Cloudflare, which handles incoming traffic. How Tunnels Work Traditional setup: I n t e r n e t → Y o u r P u b l i c I P : 4 4 3 → F i r e w a l l → N A T → L o c a l S e r v i c e With Cloudflare Tunnel: ...

March 5, 2026 Â· 5 min Â· 896 words Â· Rob Washington

Backup Strategies That Actually Work When You Need Them

The only backup that matters is the one you can restore. Everything else is wishful thinking with storage costs. Here’s how to build backup systems that work when disaster strikes. The 3-2-1 Rule (Still Valid) The classic backup rule holds up: 3 copies of your data 2 different storage types 1 offsite location Modern interpretation: P L O r o f i c f m a s a l i r : t y e : : P D S r a 3 o i / d l G u y C c S t s / i n A o a z n p u s r d h e a o t t B a s l b o a ( b s d e i ( f d ( f i S e f S r f D e e ) n r t e n t o l r u e m g e i ) o n ) This protects against: ...

March 5, 2026 Â· 8 min Â· 1530 words Â· Rob Washington

Kubernetes Troubleshooting: A Practical Field Guide

Kubernetes failures are rarely mysterious once you know where to look. The problem is knowing where to look. This guide covers the systematic approach to diagnosing common Kubernetes issues. The Diagnostic Hierarchy Start broad, drill down: C l u s t e r → N o d e → P o d → C o n t a i n e r → A p p l i c a t i o n At each level, the same questions apply: ...

March 5, 2026 Â· 6 min Â· 1234 words Â· Rob Washington

Effective Logging: What to Log, How to Log It

Everyone logs. Few log well. The difference between “we have logs” and “we can debug with logs” comes down to discipline in what you capture, how you structure it, and where you send it. The Logging Hierarchy Not all log levels are created equal. Use them intentionally: F E W I D T A R A N E R T R R F B A A O N O U C L R G E → → → → → → T S U N D E h o n o e x e m e r t t e x m a r a t p a i e p h e l l m p i c e e l n t o d l i g e p y c d e d a f r i v t a b a a e i i u t g r o l t i n b n e o o o d h n s s c , a t e a n m i . n b d i c n u l l N o t e e i e t d s n v t . t f e c h o o r o e M n . n i e i t a g s E n i p h . x n p t p p u T e r e k b h n o . e e e s d e c i u W p o h v c a s m e e t k e a , i e r r o u a t u n s n b s . o n p e u m i r a a e n o t l o g b . l n . l y e e N m o u e . f p e f . d s i n a t p t r e o n d t . i o n . The key insight: INFO should tell a story. If you read only INFO logs, you should understand what the application did. ...

March 5, 2026 Â· 7 min Â· 1336 words Â· Rob Washington

Feature Flags Done Right: Beyond the Toggle

Feature flags seem simple: wrap code in an if statement, flip a boolean, ship whenever you want. In practice, they’re one of the fastest ways to accumulate invisible technical debt. Here’s how to get the benefits without the baggage. Why Feature Flags Matter The core value proposition is decoupling deployment from release: 1 2 3 4 5 6 7 8 9 10 11 12 # Without flags: deploy = release def checkout(): process_payment() send_confirmation() # With flags: deploy when ready, release when confident def checkout(): process_payment() if feature_enabled("new_confirmation_flow"): send_rich_confirmation() else: send_confirmation() This separation enables: ...

March 5, 2026 Â· 6 min Â· 1247 words Â· Rob Washington

Integrating AI Agents into DevOps Workflows

The line between AI coding assistants and DevOps automation is blurring. What started as autocomplete has evolved into agents that can review PRs, triage alerts, and even execute runbooks. Here’s how teams are integrating AI agents into their workflows—and where the sharp edges still are. The Spectrum of AI in DevOps Think of AI integration as a spectrum from passive to active: Passive (Safe to Start) Code suggestions during development Documentation generation Log summarization Semi-Active (Human Approval) ...

March 5, 2026 Â· 5 min Â· 995 words Â· Rob Washington

Service Mesh: When You Need One and When You Don't

Service mesh is one of those technologies that sounds essential until you try to implement it. Let’s cut through the hype and figure out when it actually helps. What Is a Service Mesh? A dedicated infrastructure layer for service-to-service communication. It handles: Traffic management: Load balancing, routing, retries Security: mTLS, authentication, authorization Observability: Metrics, tracing, logging W S W S i e i e t r t r h v h v o i i u c m c t e e e s m A h A e : s → → h : S S e i r d v e i c c a e r B P r ( o d x i y r e → c t S i H d T e T c P a ) r P r o x y → S e r v i c e B The sidecar proxy (usually Envoy) intercepts all traffic and applies policies. ...

March 4, 2026 Â· 8 min Â· 1642 words Â· Rob Washington

DNS for DevOps: Beyond the Basics

DNS is the first thing that breaks and the last thing you check. Understanding it properly saves hours of debugging “it works on my machine.” Record Types You’ll Actually Use A and AAAA Point domain to IP address: e e x x a a m m p p l l e e . . c c o o m m . . A A A A A 9 2 3 6 . 0 1 6 8 : 4 2 . 8 2 0 1 0 6 : . 2 3 2 4 0 : 1 : 2 4 8 : 1 8 9 3 : 2 5 c 8 : 1 9 4 6 CNAME Alias to another domain: ...

March 4, 2026 Â· 10 min Â· 2105 words Â· Rob Washington