diff --git a/DOCKER_QUICK_START.md b/DOCKER_QUICK_START.md index 66a49eb..9ee1383 100644 --- a/DOCKER_QUICK_START.md +++ b/DOCKER_QUICK_START.md @@ -38,6 +38,8 @@ This starts: - ✅ Redis - ✅ React Frontend (auto-built and running) +**Important**: The frontend is configured to reach the API at `http://host.docker.internal:8000` (special Docker networking that reaches your host machine from inside the container). + ### Step 2: Start API (New Terminal) ```bash @@ -164,20 +166,42 @@ docker compose up --build frontend ### Frontend can't connect to API ```bash -# Make sure API is running +# Make sure API is running on host at port 8000 curl http://localhost:8000/health # Should return: {"status": "healthy", ...} + +# If API is running but frontend still fails: +# The frontend uses host.docker.internal:8000 to reach the host +# This is a Docker Desktop feature that maps to localhost on the host + +# Verify it's working with: +docker exec $(docker ps -q -f name=payguard-frontend) \ + wget --spider -q http://host.docker.internal:8000 +# Should work without error ``` ### Port 3000 already in use ```bash # Find and kill process -kill -9 $(lsof -t -i :3000) +lsof -t -i :3000 # Or use different port in docker-compose.yml # Change: "3000:3000" to "3001:3000" ``` +### "host.docker.internal" not recognized (Linux only) +On Linux, `host.docker.internal` may not work. Instead: +```bash +# Option 1: Pass host IP to container +docker compose up --build +# Then edit docker-compose.yml frontend environment: +# VITE_API_URL=http://172.17.0.1:8000 (default Docker gateway) + +# Option 2: Use network_mode: host (shares host network) +# Add to frontend service: network_mode: "host" +# Then remove ports, depends_on conditions +``` + ## Full System Architecture ``` diff --git a/docker-compose.yml b/docker-compose.yml index aac212a..885d526 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -67,7 +67,11 @@ services: retries: 5 environment: - NODE_ENV=production + - VITE_API_URL=http://host.docker.internal:8000 restart: unless-stopped + # NOTE: Frontend connects to API running on host machine via host.docker.internal + # This allows docker compose up to start infrastructure + frontend, + # while API and Consumer run locally on the same machine volumes: redis_data: diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000..c3213e2 --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1,10 @@ +# Frontend environment configuration + +# API Base URL - overrides the default in App.tsx +# Default behavior: +# - Development (npm run dev): http://localhost:8000 +# - Production (Docker): http://host.docker.internal:8000 +# VITE_API_URL=http://localhost:8000 + +# Node environment (set by docker-compose.yml) +NODE_ENV=production diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 3534e3d..5a10102 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -28,7 +28,10 @@ interface Result { timestamp: string; } -const API_BASE_URL = 'http://localhost:8000'; +// Use host.docker.internal when running in Docker, localhost when running locally +const API_BASE_URL = process.env.NODE_ENV === 'production' + ? 'http://host.docker.internal:8000' + : 'http://localhost:8000'; const App: React.FC = () => { const [auth, setAuth] = useState({