Docker for Development

The Evolution of Our Development Environment

When we started developing NotionAiAssistant, we quickly realized that a consistent and easy-to-set-up development environment would be essential for the project's success, especially as an open-source initiative aiming to attract contributors.

graph LR
    subgraph "Before: Fragmented Development"
        PL["Local<br>Python"] --> P1["Environment<br>Inconsistencies"]
        PL --> P2["Different<br>Versions"]
        P3["Complex<br>Setup"]
    end
    
    subgraph "After: Unified Docker"
        DC["Docker<br>Compose"] --> B1["Hot<br>Reload"]
        DC --> B2["Synced<br>Volumes"]
        DC --> B3["Consistent<br>Environment"]
    end
    
    I["Developer"] --> A
    I --> D
    
    A -.-> |Evolution| D
    
    classDef before fill:#ffcccc,stroke:#333,stroke-width:2px
    classDef after fill:#ccffcc,stroke:#333,stroke-width:2px
    classDef dev fill:#bbf,stroke:#333,stroke-width:2px
    
    class A,PL,P1,P2,P3 before
    class D,DC,B1,B2,B3 after
    class I dev

The Initial Challenge: Local Python Development

Initially, our development workflow was fragmented:

  1. Python running locally on the developer's machine
  2. PostgreSQL database in a separate Docker container
  3. Streamlit frontend in another local process

This model presented several problems:

  • Environment inconsistencies: "It works on my machine" was a recurring issue
  • Complex setup: New contributors had to follow detailed instructions
  • Different dependency versions: Caused hard-to-track bugs
  • High technical knowledge requirement: Barrier for less experienced contributors

The Solution: Hot Reload in Docker for Development

Our major evolution was implementing a Docker development environment with integrated hot reload:

# Excerpt from our Dockerfile.dev
FROM python:3.10-slim as dev

WORKDIR /app

# Install dependencies with uv for faster speed
COPY requirements-dev.txt .
RUN pip install --no-cache-dir uv
RUN uv pip install --no-cache-dir -r requirements-dev.txt

# Hot reload configuration
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Entry point that starts the app with hot reload
ENTRYPOINT ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080", "--reload"]

Combined with volume mapping in docker-compose:

# Excerpt from docker-compose.dev.yml
services:
  app:
    build:
      context: .
      target: dev
    volumes:
      - ./app:/app/app
      - ./config:/app/config
    # ...

Transformative Benefits

This approach brought extraordinary benefits:

1. Amplified Productivity

  • Automatic hot reload: Code changes are instantly reflected in the browser
  • Immediate feedback: Developers see results without restarting containers
  • Continuous workflow: Fewer interruptions, more productivity

2. Simplified Experience for Contributors

  • Single command to start: docker-compose -f docker-compose.dev.yml up
  • No complex local setup: Everything works inside the container
  • Consistent environment: All developers have exactly the same setup

3. Accessibility for Different Experience Levels

  • Python developers: Can contribute without deep Docker knowledge
  • Beginner developers: Significantly reduced entry barrier
  • Non-technical contributors: Can easily test and provide feedback

How It Works in Practice

The workflow became incredibly simple:

  1. Clone the repository:

    git clone https://github.com/your-username/NotionAiAssistant.git
    cd NotionAiAssistant
    
  2. Start the development environment:

    docker-compose -f docker-compose.dev.yml up
    
  3. Start developing:

    • Edit files in your favorite IDE
    • Changes are detected automatically
    • The app reloads in seconds
    • See changes in the browser in real-time

Before and After Comparison

AspectBeforeAfter
Time to start5-10 minutes1-2 minutes
Initial setupComplex, multiple stepsSingle command
Feedback after changes30-60 seconds1-2 seconds
Consistency among devsVariable100% consistent
Contribution barrierHighLow

Lessons and Best Practices

Our experience taught us some valuable practices:

  1. Prioritize developer experience from the start of the project
  2. Optimize feedback time - the faster, the better
  3. Simplify onboarding for new contributors
  4. Document clearly the development workflow
  5. Test your environment with developers of different experience levels

Impact on the Project

Implementing hot reload in Docker fundamentally transformed our project:

  • Increased contributions: More people could participate easily
  • Faster development cycles: Features implemented in less time
  • Better code quality: More iterations and experimentation
  • More engaged community: Reduced barrier to participation

This approach became one of the pillars of our project's philosophy: advanced technology that feels simple for the end user.


"The best tool isn't the one with the most features, but the one that removes obstacles from your path."