Skip to content
tezvyn:

Walk me through a basic Dockerfile for a FastAPI app

Source: fastapi.tiangolo.comEasyHow cards are made

Walk me through a basic Dockerfile for a FastAPI app
Summary

Docker layering and build cache for Python containers.

Key points

Slim base, install deps before app code to cache layers, expose port, exec-form CMD for Uvicorn.

Watch out for

Shell-form CMD or code-before-requirements, killing cache.

What's really being asked

The interviewer wants to see that you understand Docker image layering, cache invalidation, and the difference between build-time and run-time steps. They also care whether you know why exec-form CMD matters for PID 1 signal handling in containers, and whether you can articulate security and performance trade-offs like using a slim base image.

The full answer

First, choosing a minimal base image such as python:3.11-slim to reduce attack surface and final image size. Second, copying only the requirements file before the application code so that pip install runs in a cached layer and does not rebuild on every source change. Third, copying the FastAPI source code after dependencies are installed. Fourth, exposing the port the app listens on, typically 8000. Fifth, using exec-form CMD with a JSON array such as CMD followed by uvicorn, main:app, --host, 0.0.0.0, --port, 8000 so Uvicorn runs as PID 1 and receives SIGTERM directly from Docker. Optionally mentioning a non-root user is a strong senior signal.

The mistakes people make

A red flag is using shell-form CMD like CMD uvicorn main:app --host 0.0.0.0 --port 8000 because Docker spawns a shell process as PID 1 and signals may not reach Uvicorn cleanly, preventing graceful shutdown. Another mistake is copying the entire project before installing requirements, which means any code edit invalidates the dependency layer and forces a full pip reinstall. Using the full python image without justification is also weak because it bloats the image unnecessarily. Forgetting to expose the port or misunderstanding that EXPOSE is documentation unless paired with runtime port mapping is another common slip.

What usually comes next

The interviewer may ask how you would handle production concerns such as running multiple Uvicorn workers inside the container versus running one process per container and scaling horizontally. They might ask how to use a non-root USER directive or multi-stage builds to further shrink the image. You could also be asked about health checks, dockerignore files, or how to pass configuration via environment variables rather than hardcoding flags in the Dockerfile.

A concrete example

A solid Dockerfile looks like this in concept. FROM python:3.11-slim. WORKDIR /code. COPY ./requirements.txt /code/requirements.txt. RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt. COPY ./app /code/app. EXPOSE 80. CMD in exec form using uvicorn, app.main:app, --host, 0.0.0.0, --port, 80. This ordering keeps the heavy pip install layer cached while lightweight source changes only rebuild the final layers. The exec-form CMD ensures Uvicorn is the direct child of the container init and can shut down gracefully when Docker sends a stop signal.

Interview question

A developer notices that every small code change in their FastAPI app causes Docker to rerun pip install during builds. Which Dockerfile change fixes this?

  • a.Copy the entire project before running pip install to ensure all local packages are detected
  • b.Copy requirements.txt and install dependencies before copying the application source codeCorrect
  • c.Switch from shell-form CMD to exec-form CMD
  • d.Use python:3.11-slim instead of the full python image
Why?

Copying requirements.txt first allows Docker to cache the pip install layer so that later source code changes do not invalidate it. Option A describes the exact anti-pattern causing the cache bust, and while using a slim image is good practice, it reduces image size rather than improving build cache hits.

Just read this? Test yourself on what you have been reading.

Read the original → fastapi.tiangolo.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on docker — each one lists the topics its interview covers.

See open roles