I'm running two services (backend and api) on the same port inside Docker. However, whenever I send requests, NGINX routes all requests to the backend service, and I cannot access the api service properly.
I suspect it's a problem with my NGINX configuration.
Here are my files:
docker-compose.yml
version: '3.8' services: backend: build: context: . dockerfile: ./backend/Dockerfile.dev volumes: - ./backend:/var/www/html/backend environment: - APP_ENV=development networks: - bysooq-network expose: - 9000 env_file: - .env api: build: context: . dockerfile: ./api/Dockerfile.dev volumes: - ./api:/var/www/html/api environment: - APP_ENV=development networks: - bysooq-network expose: - 9000 env_file: - .env postgres: image: postgres:13 restart: always volumes: - ~/bysooq-data/postgres:/var/lib/postgresql/data environment: POSTGRES_DB: xxx POSTGRES_USER: xx POSTGRES_PASSWORD: xxx networks: - bysooq-network redis: image: redis:latest ports: - "6380:6379" restart: always networks: - bysooq-network nginx: image: nginx:latest volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf - ./api:/var/www/html/api - ./backend:/var/www/html/backend ports: - 80:80 depends_on: - backend - api networks: - bysooq-network networks: bysooq-network: driver: bridge nginx default.conf
nginx
server { listen 80; server_name localhost; client_max_body_size 100M; index index.php; # API Service - Must come first with strict matching location ~ ^/api(/.*)?$ { root /var/www/html/api/web; try_files $1 $1/ /index.php$is_args$args; location ~ \.php$ { fastcgi_pass api:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_param REQUEST_URI $1$is_args$args; } } # Backend Service location / { root /var/www/html/backend/web; try_files $uri $uri/ /index.php$is_args$args; location ~ \.php$ { fastcgi_pass backend:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } } What I expect:
Requests to /api/* should go to the api service.
Other requests should go to the backend service.
What happens:
All requests (even /api/...) are handled by the backend.
Question: How can I correctly configure NGINX to route /api/* requests to the API service and other requests to the backend service?
Thanks in advance!
location /api/?location ~ \.php$ { ... }block would overtake both backend and API requests being rewritten toindex.php. And yes, there is no need for such a complex setup — the configuration can be flattened if the/api/location is defined with the^~modifier, as I’ve shown in my answer.