DEV Community

Muhammad Umair Virk
Muhammad Umair Virk

Posted on Originally published at Medium

Why Serverless Engineers Already Understand Containers

The outage that teaches you deployment

A service passes every test locally. It fails in staging because the API calls localhost:5432 for Postgres — but Postgres is in another container, reachable only as db:5432.

This is not a Docker problem. It is a boundary problem: your code assumed an environment it does not own.

Engineers who have shipped on AWS Lambda already avoid a class of these mistakes. They never SSH into a function to hot-fix. They inject config at deploy time. They treat each invocation as disposable. Containers reward the same discipline with different vocabulary.

This article maps what transfers, what breaks, and what I require before any Python backend goes to production in a container.


What serverless already taught you

Immutable deployments

Lambda versions are replaced, not patched. Container images work the same way: build a new image, roll out, roll back by tag. If your incident runbook includes "edit files inside the running box," you have a design problem.

Configuration at runtime

Secrets belong in Secrets Manager or injected env vars — not in source control, not in the image layer cache. Docker does not change the rule; it changes where you mount the values.

Single responsibility per unit

One Lambda, one job. One container, one main process. Compose and Kubernetes add orchestration; they do not remove the rule.

Cold start awareness

Slim packages on Lambda map to slim base images (python:3.12-slim, multi-stage builds). Startup time affects autoscaling and health-check windows the same way cold starts affect user-facing latency.

If you understand why a Lambda deployment package should stay small, you understand why a 2 GB container image is a liability.


Where the mental model breaks

1. Network identity

Inside Compose or Kubernetes, localhost is the container itself. Services discover each other by DNS name (api, db, redis). This is the most common first-production failure I see in teams moving from bare metal or single-host deploys.

2. Port publishing

EXPOSE in a Dockerfile documents intent. It does not bind a host port. You still need explicit port mapping or an ingress controller. Confusing the two produces "the container is healthy but nothing reaches it from outside."

3. Image vs. container vs. process

The image is immutable. The container is a running instance. You can scale ten replicas from one image. Debugging "which instance handled this request?" requires logs with instance identity — hostname, pod name, task id.

4. Health checks are part of the contract

A process that listens but cannot serve traffic should fail the health check. Load balancers and orchestrators depend on this. HEALTHCHECK in Docker and /health endpoints in your app are not optional polish.


A production-shaped Dockerfile (Python / FastAPI)

FROM python:3.12-slim

WORKDIR /app

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

RUN useradd --create-home appuser
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app ./app

USER appuser
EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health')"

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Enter fullscreen mode Exit fullscreen mode

Non-root user, slim base, explicit health check, no secrets in layers. This is the minimum bar I review for in PRs.


Serverless vs. containers — a decision lens

Constraint Lean serverless Lean containers
Traffic shape Spiky, unpredictable Steady or long-running workers
Unit of work Short, event-driven Persistent connections, WebSockets, background workers
Ops surface Minimize Team can own runtime and patching
Dependency weight Small handler bundles Custom system libs, ML models, legacy binaries

Most mature platforms use both. The engineer who can reason about trade-offs — not just "we use Kubernetes" — is the one I want reviewing architecture.


What I look for in a backend engineer's deploy story

Can they explain why the last outage happened at the infrastructure boundary, not in a line of Python? Can they roll back without data loss? Do they know where config lives and who can read it?

Containers are not a separate career. They are the next layer of the same responsibility: ship code that survives real environments.


Further reading


Muhammad Umair Virk is a Backend Engineer based in the UAE — Python, AWS, microservices, and payment systems. Open to backend and platform roles.

Top comments (0)