---
title: "How to Configure Development Containers with Docker"
slug: "configuring-development-containers-docker-guide"
published: "2025-08-18"
updated: "2025-12-26"
validated: "2025-10-20"
categories:
  - "Docker"
tags:
  - "dev containers"
  - "vscode"
  - "docker"
  - "docker compose"
  - "react"
  - "vite"
  - "fastapi"
  - "hot reload"
  - "development environment"
llm-intent: "reference"
audience-level: "intermediate"
framework-versions:
  - "docker"
  - "vscode dev containers"
  - "docker compose"
  - "node.js"
  - "vite"
status: "stable"
llm-purpose: "Guide to configuring VSCode Dev Containers with Docker Compose for React and FastAPI, including hot reload, debugging, and performance tips."
llm-prereqs:
  - "Access to Docker"
  - "Access to VSCode Dev Containers"
  - "Access to Docker Compose"
  - "Access to Node.js"
  - "Access to Vite"
llm-outputs:
  - "Updated docker-compose configuration files for the new environment"
---

**Summary Triples**
- (How to Configure Development Containers with Docker, focuses-on, Guide to configuring VSCode Dev Containers with Docker Compose for React and FastAPI, including hot reload, debugging, and performance tips.)
- (How to Configure Development Containers with Docker, category, general)

### {GOAL}
Guide to configuring VSCode Dev Containers with Docker Compose for React and FastAPI, including hot reload, debugging, and performance tips.

### {PREREQS}
- Access to Docker
- Access to VSCode Dev Containers
- Access to Docker Compose
- Access to Node.js
- Access to Vite

### {STEPS}
1. Install prerequisites
2. Create frontend Dockerfile.dev
3. Add frontend devcontainer.json
4. Create backend Dockerfile.dev
5. Add backend devcontainer.json
6. Add compose.dev.yml
7. Start and connect from VSCode

<!-- llm:goal="Guide to configuring VSCode Dev Containers with Docker Compose for React and FastAPI, including hot reload, debugging, and performance tips." -->
<!-- llm:prereq="Access to Docker" -->
<!-- llm:prereq="Access to VSCode Dev Containers" -->
<!-- llm:prereq="Access to Docker Compose" -->
<!-- llm:prereq="Access to Node.js" -->
<!-- llm:prereq="Access to Vite" -->
<!-- llm:output="Updated docker-compose configuration files for the new environment" -->

# How to Configure Development Containers with Docker
> Guide to configuring VSCode Dev Containers with Docker Compose for React and FastAPI, including hot reload, debugging, and performance tips.
Matija Žiberna · 2025-08-18

This was an enourmous source of frustration to set up so I had to document the process.

I was working on a full-stack project when I ran into the classic "it works on my machine" problem. 

I couldn't get the development environment set up correctly, and I were spending hours troubleshooting dependency conflicts instead of actually building features.

This guide shows you exactly how to configure development containers that eliminate environment issues and get your entire team productive within minutes instead of days.

I'll demonstrate these concepts using React and FastAPI as examples, but the configuration principles apply to any technology stack - the power lies in mastering the development container setup itself.

## What Development Containers Actually Solve

Development containers represent a fundamental shift from traditional development setups. Instead of installing languages, frameworks, and tools directly on your local machine, you develop inside Docker containers that encapsulate everything your project needs. The key insight is that these containers feel exactly like local development while providing perfect consistency across your entire team.

The breakthrough moment came when I realized development containers aren't just about consistency - they're about eliminating the entire category of environment-related problems. No more "works on my machine," no more spending half a day setting up a new developer's environment, and no more conflicts between different projects requiring different versions of the same tools.

## Why I Use React + FastAPI to Demonstrate

I'm using a React frontend with Vite and a Python FastAPI backend to demonstrate development container configuration. This isn't about these specific technologies - it's about showing how to configure development containers for any multi-service application.

**Why this combination works perfectly as a demonstration:**
- **Cross-language complexity**: JavaScript/Node.js and Python represent the exact kind of environment management nightmare that development containers solve
- **Real configuration challenges**: Different package managers, runtime versions, and development tools - perfect for showcasing comprehensive `.devcontainer` setup
- **Universal patterns**: The configuration techniques you'll learn apply to Vue + Django, Angular + .NET, or any other technology combination

**The real focus is mastering `.devcontainer` configuration.** Once you understand how to structure these files properly, you can configure development containers for any technology stack. The React and FastAPI code is just the canvas - the development container configuration is the masterpiece.

**What makes development containers powerful:**
- Your entire development environment runs in Docker while maintaining local development performance
- Every team member works in identical environments regardless of their operating system
- New developers become productive immediately without complex setup procedures
- Full VSCode functionality works seamlessly inside containers with IntelliSense, debugging, and extensions
- Hot reloading and auto-refresh work exactly as expected in traditional development

## Prerequisites and Setup

Before diving into the implementation, you'll need three essential tools. The setup process is straightforward, but getting these components working together correctly is crucial for the entire workflow.

**Required installations:**

1. **Docker Desktop** - Download and install from [docker.com](https://www.docker.com/products/docker-desktop)
2. **VSCode** - Get the latest version from [code.visualstudio.com](https://code.visualstudio.com/)
3. **Dev Containers Extension** - Install this directly in VSCode by searching for "Dev Containers" in the extensions marketplace

The Dev Containers extension is what makes the magic happen. Once installed, VSCode can connect to and work inside Docker containers as if they were local development environments.

## Project Structure: The `.devcontainer` Configuration is Everything

The development container structure I've settled on supports both independent service development and coordinated multi-service workflows. The most critical part of this entire setup is getting the `.devcontainer` configurations right - these files are what transform ordinary Docker containers into fully-featured development environments that rival local development.

```
project-root/
├── .devcontainer/
│   ├── frontend/
│   │   └── devcontainer.json     # Frontend container config
│   └── backend/
│       └── devcontainer.json     # Backend container config
├── frontend/
│   ├── Dockerfile.dev            # Frontend dev environment
│   ├── package.json
│   └── src/
├── backend/
│   ├── Dockerfile.dev            # Backend dev environment
│   ├── requirements.txt
│   └── main.py
└── compose.dev.yml               # Development orchestration
```

**The `.devcontainer` directory is the heart of this entire system.** These VSCode-specific configurations define exactly how each service behaves when opened in a development container - which extensions get installed, what settings are applied, which ports are forwarded, and how the development environment is initialized. Master these configurations, and you've mastered development containers.

Each service gets its own `devcontainer.json` file with carefully chosen extensions, settings, and development tools. The development Dockerfiles support these configurations by providing the base environment, but the `.devcontainer` files are what create the actual development experience.

## Frontend Development Container Setup

Setting up the frontend development container focuses on creating an optimal React development environment with comprehensive tooling and hot reloading. The goal is to match or exceed the experience of local development while providing perfect consistency across the team.

### Frontend Development Dockerfile

Create `frontend/Dockerfile.dev`:

```dockerfile
# Development environment with Node.js
FROM node:20-slim

# Set working directory
WORKDIR /app

# Install git for VSCode and development tools
RUN apt-get update && apt-get install -y \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm install --legacy-peer-deps

# Copy source code
COPY . .

# Expose Vite dev server port
EXPOSE 5173

# Start Vite dev server with host binding for Docker
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "5173"]
```

This Dockerfile creates a development environment that includes system tools like Git (essential for VSCode functionality) and configures Vite with host binding so the development server is accessible from outside the container. The `--host 0.0.0.0` configuration is crucial - without it, you won't be able to access your development server from your host machine.

### Frontend Dev Container Configuration

Create `.devcontainer/frontend/devcontainer.json`:

```json
{
    "name": "Frontend Dev Container",
    "dockerComposeFile": ["../../compose.dev.yml"],
    "service": "frontend",
    "shutdownAction": "none",
    "workspaceFolder": "/workspace/frontend",
    
    "customizations": {
        "vscode": {
            "extensions": [
                // Essential React/TypeScript extensions
                "dbaeumer.vscode-eslint",
                "esbenp.prettier-vscode",
                "bradlc.vscode-tailwindcss",
                "dsznajder.es7-react-js-snippets",
                
                // Development productivity
                "formulahendry.auto-rename-tag",
                "christian-kohler.npm-intellisense",
                "christian-kohler.path-intellisense",
                
                // Git and Docker support
                "eamodio.gitlens",
                "ms-azuretools.vscode-docker",
                
                // Code quality
                "ms-vscode.vscode-typescript-next"
            ],
            "settings": {
                // Editor configuration
                "editor.formatOnSave": true,
                "editor.defaultFormatter": "esbenp.prettier-vscode",
                "editor.codeActionsOnSave": {
                    "source.fixAll.eslint": true,
                    "source.organizeImports": true
                },
                
                // JavaScript/TypeScript settings
                "javascript.updateImportsOnFileMove.enabled": "always",
                "typescript.updateImportsOnFileMove.enabled": "always",
                
                // Terminal configuration
                "terminal.integrated.defaultProfile.linux": "bash",
                
                // File associations
                "files.associations": {
                    "*.css": "tailwindcss"
                }
            }
        }
    },
    
    // Development setup
    "postCreateCommand": "npm install && npm run dev",
    "forwardPorts": [5173],
    "portsAttributes": {
        "5173": {
            "label": "Vite Dev Server",
            "onAutoForward": "notify"
        }
    },
    
    // Use node user for security
    "remoteUser": "node",
    
    // Development features
    "features": {
        "ghcr.io/devcontainers/features/git:1": {},
        "ghcr.io/devcontainers/features/github-cli:1": {}
    }
}
```

This configuration transforms a basic Docker container into a fully-featured development environment. The extension list includes everything you need for productive React development, while the settings ensure code formatting and linting happen automatically. The `postCreateCommand` runs when the container is created, automatically installing dependencies and starting the development server.

## Backend Development Container Setup

The backend setup creates a comprehensive Python development environment optimized for FastAPI development with debugging capabilities, testing infrastructure, and code quality tools integrated directly into the container.

### Backend Development Dockerfile

Create `backend/Dockerfile.dev`:

```dockerfile
# Development environment with Python
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Install system dependencies for development
RUN apt-get update && apt-get install -y \
    sqlite3 \
    git \
    curl \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Copy requirements
COPY requirements.txt .

# Install Python dependencies with development tools
RUN pip install --no-cache-dir -r requirements.txt \
    && pip install --no-cache-dir \
    pytest \
    pytest-asyncio \
    black \
    flake8 \
    mypy \
    isort

# Create data directory
RUN mkdir -p /app/data && chmod 777 /app/data

# Copy application code
COPY . .

# Expose port 8000 for FastAPI
EXPOSE 8000

# Set environment variables
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONPATH=/app

# Run with Uvicorn in development mode with auto-reload
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload", "--log-level", "debug"]
```

This Dockerfile includes all the development tools you need for professional Python development: pytest for testing, Black for formatting, Flake8 for linting, and MyPy for type checking. The environment variables optimize Python for development with unbuffered output and no bytecode generation. The `--reload` flag in the CMD ensures the server automatically restarts when you change code.

### Backend Dev Container Configuration

Create `.devcontainer/backend/devcontainer.json`:

```json
{
    "name": "Backend Dev Container",
    "dockerComposeFile": ["../../compose.dev.yml"],
    "service": "backend",
    "shutdownAction": "none",
    "workspaceFolder": "/workspace/backend",
    
    "customizations": {
        "vscode": {
            "extensions": [
                // Python development essentials
                "ms-python.python",
                "ms-python.vscode-pylance",
                "ms-python.black-formatter",
                "ms-python.isort",
                "ms-python.flake8",
                "ms-python.mypy-type-checker",
                
                // Documentation and productivity
                "njpwerner.autodocstring",
                "kevinrose.vsc-python-indent",
                
                // FastAPI specific
                "tamasfe.even-better-toml",
                
                // Development tools
                "eamodio.gitlens",
                "ms-azuretools.vscode-docker",
                
                // Code quality
                "charliermarsh.ruff",
                "ms-python.pytest"
            ],
            "settings": {
                // Python interpreter
                "python.defaultInterpreterPath": "/usr/local/bin/python",
                
                // Linting configuration
                "python.linting.enabled": true,
                "python.linting.pylintEnabled": false,
                "python.linting.flake8Enabled": true,
                "python.linting.mypyEnabled": true,
                
                // Formatting configuration
                "editor.formatOnSave": true,
                "[python]": {
                    "editor.defaultFormatter": "ms-python.black-formatter",
                    "editor.codeActionsOnSave": {
                        "source.organizeImports": true
                    }
                },
                
                // Testing configuration
                "python.testing.pytestEnabled": true,
                "python.testing.unittestEnabled": false,
                "python.testing.pytestArgs": ["tests"],
                
                // IntelliSense settings
                "python.analysis.typeCheckingMode": "basic",
                "python.analysis.autoImportCompletions": true
            }
        }
    },
    
    // Development setup
    "postCreateCommand": "pip install -r requirements.txt && python -c 'import sqlite3; sqlite3.connect(\"/app/data/app.db\").close(); print(\"Database initialized\")'",
    "forwardPorts": [8000],
    "portsAttributes": {
        "8000": {
            "label": "FastAPI Server",
            "onAutoForward": "notify"
        }
    },
    
    // Run as root for development flexibility
    "remoteUser": "root",
    
    // Development features
    "features": {
        "ghcr.io/devcontainers/features/git:1": {},
        "ghcr.io/devcontainers/features/github-cli:1": {}
    }
}
```

This configuration creates a sophisticated Python development environment with comprehensive tooling integration. The Python extension stack provides IntelliSense, debugging, and code navigation, while the formatting and linting tools maintain code quality automatically. The testing configuration enables running pytest directly from VSCode's interface.

## Development Orchestration with Docker Compose

The development compose configuration orchestrates both containers into a cohesive development environment that supports rapid iteration, hot reloading, and seamless service communication.

### Development Compose Configuration

Create `compose.dev.yml`:

```yaml
services:
  # Frontend development service
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    ports:
      - "5173:5173"  # Vite dev server
      - "24678:24678"  # Vite HMR port
    networks:
      - app-network
    volumes:
      # Mount source code for hot reloading
      - .:/workspace:cached
      # Use named volume for node_modules to avoid conflicts
      - frontend-node-modules:/workspace/frontend/node_modules
      # Cache for faster rebuilds
      - frontend-cache:/workspace/frontend/.vite
    environment:
      # Point to backend dev server
      - VITE_API_URL=http://localhost:8000
      - NODE_ENV=development
    stdin_open: true
    tty: true

  # Backend development service
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.dev
    ports:
      - "8000:8000"  # FastAPI dev server
      - "5678:5678"  # Python debugger port
    networks:
      - app-network
    volumes:
      # Mount source code for hot reloading
      - .:/workspace:cached
      # Persist backend data
      - backend-data:/app/data
      # Python cache for faster imports
      - backend-cache:/root/.cache/pip
    environment:
      - DATABASE_URL=sqlite:///app/data/app.db
      - ENVIRONMENT=development
      - DEBUG=true
      - PYTHONPATH=/workspace/backend
    stdin_open: true
    tty: true

# Named volumes for performance and persistence
volumes:
  frontend-node-modules:
    driver: local
  frontend-cache:
    driver: local
  backend-data:
    driver: local
  backend-cache:
    driver: local

# Network for service communication
networks:
  app-network:
    driver: bridge
```

This compose file balances performance, functionality, and developer experience. The volume mounting strategy uses `:cached` for better performance on macOS, while named volumes for dependencies prevent conflicts and improve build performance. The network configuration enables service-to-service communication using container names.

## The Development Workflow

Once everything is set up, the development workflow becomes incredibly smooth. Here's how I work with development containers on a daily basis.

### Starting Your Development Environment

```bash
# Start all services
docker compose -f compose.dev.yml up -d

# Or start with logs visible for troubleshooting
docker compose -f compose.dev.yml up
```

### Connecting VSCode to Containers

The fastest way to connect is through VSCode's command palette:

1. Open VSCode in your project root
2. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac)
3. Type "Dev Containers: Reopen in Container"
4. Select either "Frontend Dev Container" or "Backend Dev Container"

VSCode automatically handles container building, starting, and connection. All configured extensions install automatically, and you get a fully configured development environment instantly.

### Multi-Service Development

For full-stack development, I typically work with both containers simultaneously:

1. **Open two VSCode windows**
2. **Connect one to the frontend container** - Access files at `/workspace/frontend`
3. **Connect the other to the backend container** - Access files at `/workspace/backend`

This setup gives you:
- Frontend hot reload at `http://localhost:5173`
- Backend auto-reload at `http://localhost:8000`  
- Seamless API communication between services
- Independent debugging for each service

### Daily Development Commands

**Frontend development:**
```bash
# Install new packages
docker compose -f compose.dev.yml exec frontend npm install axios

# Run tests
docker compose -f compose.dev.yml exec frontend npm run test

# Access container shell
docker compose -f compose.dev.yml exec frontend bash
```

**Backend development:**
```bash
# Install new packages
docker compose -f compose.dev.yml exec backend pip install sqlalchemy

# Run tests
docker compose -f compose.dev.yml exec backend pytest

# Access container shell
docker compose -f compose.dev.yml exec backend bash
```

## Debugging and Development Features

### Frontend Debugging

The frontend development experience matches local development exactly:
- **React DevTools** work seamlessly with containerized development
- **Hot Module Replacement** provides instant feedback without page reloads
- **VSCode debugging** with breakpoints works directly in containerized JavaScript
- **Browser DevTools** show API calls to the containerized backend normally

### Backend Debugging

Backend debugging is equally comprehensive:
- **VSCode Python debugger** attaches to Python running in the container
- **Interactive debugging** with breakpoint support and variable inspection  
- **FastAPI documentation** at `http://localhost:8000/docs` for API testing
- **Real-time logs** using `docker compose logs -f backend`

## Troubleshooting Common Issues

### Container Won't Start

```bash
# Check logs for specific errors
docker compose -f compose.dev.yml logs frontend
docker compose -f compose.dev.yml logs backend

# Rebuild containers from scratch
docker compose -f compose.dev.yml build --no-cache
```

### Hot Reload Not Working

For frontend hot reload issues, add polling to your `vite.config.js`:

```javascript
export default {
  server: {
    host: '0.0.0.0',
    port: 5173,
    watch: {
      usePolling: true  // Required for file watching in containers
    }
  }
}
```

### VSCode Can't Connect

```bash
# Verify containers are running
docker compose -f compose.dev.yml ps

# Restart Dev Containers extension in VSCode
# Ctrl+Shift+P → "Developer: Reload With Extensions Disabled"
# Then re-enable the Dev Containers extension
```

### Performance Issues

Create a `.dockerignore` file to exclude unnecessary files from the build context:

```
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
coverage
.nyc_output
```

## Performance Optimization Tips

**Container performance:**
- Use named volumes for `node_modules` and caches to avoid performance penalties
- Mount only necessary directories for hot reloading
- Use `.dockerignore` to reduce build context size
- Keep containers running during development to avoid startup overhead

**VSCode optimization:**
- Install only necessary extensions to reduce resource usage
- Use workspace-specific settings to avoid configuration conflicts
- Configure file watching properly for container environments

This development container setup has transformed how my team develops full-stack applications. We eliminated environment setup time, reduced onboarding from days to minutes, and completely solved the "works on my machine" problem. The initial setup investment pays for itself immediately through improved team productivity and eliminated debugging time.

Let me know in the comments if you have questions about implementing development containers for your team, and subscribe for more practical development guides.

Thanks, Matija

## LLM Response Snippet
```json
{
  "goal": "Guide to configuring VSCode Dev Containers with Docker Compose for React and FastAPI, including hot reload, debugging, and performance tips.",
  "responses": [
    {
      "question": "What does the article \"How to Configure Development Containers with Docker\" cover?",
      "answer": "Guide to configuring VSCode Dev Containers with Docker Compose for React and FastAPI, including hot reload, debugging, and performance tips."
    }
  ]
}
```