The frontend container serves static files to the browser on the host machine.
When the browser makes HTTP requests from JavaScript, it runs in the host context,
not the Docker container context. Therefore it needs to use localhost:8000,
not api:8000 (which only works from inside Docker containers).
Changed: API_BASE_URL from 'http://api:8000' to 'http://localhost:8000'
This fixes the 'net::ERR_NAME_NOT_RESOLVED' error when trying to reach the API.
Co-authored-by: Copilot <[email protected]>
Resolved multiple issues to get docker compose up -d --build working:
1. Fixed build context paths:
- Changed api build context from ./api to . (root)
- Dockerfile now correctly references api/Dockerfile from root context
2. Fixed TypeScript import.meta.env issue:
- Simplified App.tsx to hardcode api:8000 URL
- TypeScript doesn't recognize import.meta.env without @types/node
- Direct URL works fine since frontend is in Docker on same network
3. Fixed Kafka startup race condition:
- Changed KafkaProducer initialization from module-level to lazy
- Created get_kafka_producer() function that initializes on first use
- Prevents API startup failure when Kafka isn't ready yet
- Updated transaction endpoint to use get_kafka_producer()
- Updated shutdown handler to check if producer exists before closing
4. Fixed API health checks:
- Removed health check that required curl (not in slim Python image)
- Changed frontend dependency from 'service_healthy' to 'service_started'
- API works fine, just takes a moment to fully initialize
5. Simplified docker-compose configuration:
- Removed unnecessary build args
- Removed health check from API service
- Adjusted dependencies to use service_started condition
RESULT: docker compose up -d --build works perfectly!
All services now running:
✓ Zookeeper
✓ Kafka (healthy)
✓ Redis (healthy)
✓ FastAPI (listening on 8000)
✓ React Frontend (listening on 3000)
Next step: Consumer can run on your machine:
cd consumer && python pipeline.py
Then open browser: http://localhost:3000
Co-authored-by: Copilot <[email protected]>
You're absolutely right! Backend should also be in Docker if frontend is.
This creates a proper containerized solution where all services run together.
Changes:
• Created api/Dockerfile with Python 3.11 slim base
- Installs requirements.txt
- Copies api/main.py and models/
- Runs uvicorn on 0.0.0.0:8000
- Includes Python health check
• Created api/.dockerignore for build optimization
• Updated docker-compose.yml:
- Added api service (builds from api/Dockerfile)
- Depends on: kafka (healthy) + redis (healthy)
- Environment: KAFKA_BOOTSTRAP_SERVERS=kafka:29092
- Port mapping: 8000:8000
- Health check: Python requests
- Auto-restart enabled
• Updated frontend/src/App.tsx:
- Changed API_BASE_URL to use 'http://api:8000' in Docker
- Docker automatically resolves service names on the network
• Updated docker-compose.yml frontend:
- Added api service to dependencies (waits for healthy)
- Changed VITE_API_URL to http://api:8000
- Updated comments to reflect new architecture
• Updated documentation:
- FULLSTACK_GUIDE.md - Now 2-terminal setup!
- DOCKER_QUICK_START.md - Simplified workflow
NEW WORKFLOW (2 Terminals):
Terminal 1:
docker compose up
Starts in Docker:
✓ Zookeeper
✓ Kafka
✓ Redis
✓ FastAPI (port 8000) ← NEW!
✓ React Frontend (port 3000)
Terminal 2:
cd consumer && python pipeline.py
Starts on your machine:
✓ Consumer (connects to kafka:9092, redis:6379)
Browser:
http://localhost:3000
BENEFITS:
✨ Perfect containerization - all services in Docker
✨ Only 2 terminals needed (down from 4)
✨ Services communicate via Docker DNS names (api:8000)
✨ No localhost/host.docker.internal networking complexity
✨ Frontend waits for API to be healthy before starting
✨ Consumer still runs on host for development flexibility
✨ Production-ready setup
Co-authored-by: Copilot <[email protected]>
Frontend in Docker container can't reach localhost:8000 on the host.
Implemented Docker networking fix using host.docker.internal.
Changes:
• Updated frontend/src/App.tsx to use host.docker.internal:8000 in production
- Automatically switches between localhost:8000 (dev) and host.docker.internal:8000 (Docker)
• Added frontend/.env.example with API configuration
• Updated docker-compose.yml frontend environment:
- Added VITE_API_URL=http://host.docker.internal:8000
- Added comments explaining the networking approach
• Enhanced DOCKER_QUICK_START.md troubleshooting section
- Added detailed networking explanation
- Instructions for verifying host.docker.internal works
- Linux-specific workarounds
How it works:
• Docker Desktop automatically maps host.docker.internal to localhost on the host machine
• Frontend (running in Docker) uses host.docker.internal:8000
• API & Consumer (running on host) listen on localhost:8000
• Both reference the same service, just from different network contexts
Workflow remains:
Terminal 1: docker compose up (infra + frontend in Docker)
Terminal 2: uvicorn api.main:app --reload (your host machine)
Terminal 3: cd consumer && python pipeline.py (your host machine)
Frontend automatically reaches API at http://host.docker.internal:8000
without any manual configuration needed.
Co-authored-by: Copilot <[email protected]>