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:
- Python running locally on the developer's machine
- PostgreSQL database in a separate Docker container
- 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:
-
Clone the repository:
git clone https://github.com/your-username/NotionAiAssistant.git cd NotionAiAssistant
-
Start the development environment:
docker-compose -f docker-compose.dev.yml up
-
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
Aspect | Before | After |
---|---|---|
Time to start | 5-10 minutes | 1-2 minutes |
Initial setup | Complex, multiple steps | Single command |
Feedback after changes | 30-60 seconds | 1-2 seconds |
Consistency among devs | Variable | 100% consistent |
Contribution barrier | High | Low |
Lessons and Best Practices
Our experience taught us some valuable practices:
- Prioritize developer experience from the start of the project
- Optimize feedback time - the faster, the better
- Simplify onboarding for new contributors
- Document clearly the development workflow
- 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."