Supercharge Your Python Workflow with docker compose watch

Learn how to use docker compose watch in a Python project to automatically restart on code changes and rebuild on requirements updates. Boost your DevOps workflow with this modern Docker setup

When you're developing a Python application with Docker, iteration speed matters. You want fast feedback loops, minimal downtime between changes, and clean, reproducible environments. That’s where docker compose watch comes in—a new feature that automatically restarts or rebuilds services in response to file changes.

In this post, we’ll set up docker compose watch to:

  • Restart your Python service when your source code changes.
  • Rebuild the container if your requirements.txt changes (since that usually means dependencies have changed).
  • Include a pro tip about ensuring your containers stay up-to-date after a git pull.

Let’s get started.


Step 1: Basic Docker Setup for Python

Assume you have a Python project with this structure:

my-app/
├── app/
│   └── main.py
├── requirements.txt
├── Dockerfile
└── docker-compose.yml

Dockerfile

# Use an official Python image
FROM python:3.11-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

# Set work directory
WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy project
COPY app app/

# Expose the port FastAPI will run on
EXPOSE 8000

# Run the FastAPI app with Uvicorn
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Step 2: Define Services in docker-compose.yaml

services:
  app:
    build: .
    volumes:
      - .:/app
    ports:
      - 8000:8000
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000

docker-compose.yaml

This mounts your source code inside the container so you can pick up changes during development.


Step 3: Use docker compose watch for Auto-Restarts and Rebuilds

You can now use a docker-compose.watch.yml file to define what files to watch and how to react.

docker-compose.watch.yaml

services:
  app:
    build: .
    develop:
      watch:
        - path: app/
          action: sync+restart
          target: /app/app
        - path: requirements.txt
          action: rebuild
    ports:
      - 8000:8000
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000

docker-compose.watch.yaml

With this config:

  • Changes in app/ (your Python code) will trigger a container restart.
  • Changes to requirements.txt will trigger a full rebuild of the container.

Step 4: Start Watching

Launch your app and start the watch process:

docker compose -f docker-compose.watch.yaml up --watch

Now, any time you update your code or your dependencies, Docker will handle the rest.


Pro Tip: Rebuild After a git pull

Sometimes you or your teammates pull in changes that modify Dockerfile, requirements.txt, or anything else affecting the build context.

Tip: After running git pull, run this:

docker compose build

This ensures your local environment reflects the latest configuration and dependencies before continuing development.


Final Thoughts

Using docker compose watch brings the best of both worlds—fast feedback for code changes and smart rebuilds when necessary. It bridges the gap between local development and the fidelity of containerized environments.

If you're building Python apps with Docker, give docker compose watch a try. It just might become your new favourite workflow tool.

I've published the code to my github repo here.