Из-за чего php-fpm на все запросы выдает 404?

Ссылка скопирована
1 ответ

Есть три контейнера:
- nginx,
По вводным: - beckend: php-fpm+laravel
- vue.js+nginx

По вводным: хочу чтобы все запросы на /api/* шли на beckend в laravel, а остальнве на frontend
По вводным: frontend работает, страницы открываются,
По вводным: а вот beckend на все запросы выдает 404

Где я ошибся?

Docker-compose.yml

services: backend: build: context: ./backend dockerfile: Dockerfile args: HTTP_PROXY: http://172.17.0.1:8118 HTTPS_PROXY: http://172.17.0.1:8118 NO_PROXY: localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer http_proxy: http://172.17.0.1:8118 https_proxy: http://172.17.0.1:8118 no_proxy: localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer extra_hosts: - "host.docker.internal:host-gateway" container_name: jdasia-backend env_file: - ./docker/.env.docker volumes: - ./backend:/var/www/html depends_on: - db - redis environment: XDEBUG_MODE: ${XDEBUG_MODE:-develop,debug} XDEBUG_CLIENT_HOST: ${XDEBUG_CLIENT_HOST:-host.docker.internal} XDEBUG_CLIENT_PORT: ${XDEBUG_CLIENT_PORT:-9003} http_proxy: http://172.17.0.1:8118 https_proxy: http://172.17.0.1:8118 no_proxy: localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer HTTP_PROXY: http://172.17.0.1:8118 HTTPS_PROXY: http://172.17.0.1:8118 NO_PROXY: localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer extra_hosts: - "host.docker.internal:host-gateway" nginx: image: nginx:stable-alpine container_name: jdasia-nginx ports: - "80:80" - "443:443" volumes: - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro - ./infra/nginx/certs:/etc/nginx/certs:ro depends_on: - backend - frontend frontend: build: context: ./frontend dockerfile: Dockerfile args: HTTP_PROXY: http://172.17.0.1:8118 HTTPS_PROXY: http://172.17.0.1:8118 NO_PROXY: localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer http_proxy: http://172.17.0.1:8118 https_proxy: http://172.17.0.1:8118 no_proxy: localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer extra_hosts: - "host.docker.internal:host-gateway" container_name: jdasia-frontend volumes: - ./frontend:/app - /app/node_modules - ./infra/nginx/certs:/etc/nginx/certs:ro environment: - NODE_ENV=development - HTTP_PROXY=http://172.17.0.1:8118 - HTTPS_PROXY=http://172.17.0.1:8118 - NO_PROXY=localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer - http_proxy=http://172.17.0.1:8118 - https_proxy=http://172.17.0.1:8118 - no_proxy=localhost,127.0.0.1,::1,host.docker.internal,172.17.0.1,db,redis,backend,mailhog,frontend,web,adminer depends_on: - backend volumes: db_data:

./backend/Dockerfile

FROM php:8.2-fpm-trixie # Proxy support ARG HTTP_PROXY ARG HTTPS_PROXY ARG NO_PROXY # Only set proxy if explicitly provided ENV http_proxy=${HTTP_PROXY:-} \ https_proxy=${HTTPS_PROXY:-} \ no_proxy=${NO_PROXY:-} \ ALL_PROXY=${HTTP_PROXY:-} # tcpdump port 9000 -A | strings # Install system deps (Debian/apt) RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ git curl unzip zip \ tcpdump mc htop \ libpq-dev libicu-dev libzip-dev libonig-dev \ pkg-config autoconf make g++ \ && docker-php-ext-configure intl \ && docker-php-ext-install pdo pdo_pgsql mbstring intl zip opcache \ && if [ -n "$HTTP_PROXY" ]; then pecl config-set http_proxy "$HTTP_PROXY"; fi \ && pecl channel-update pecl.php.net || true \ && (pecl install -o -f redis xdebug \ || (echo "PECL direct install failed, trying tarballs" \ && curl -fsSL --connect-timeout 20 --retry 5 ${HTTPS_PROXY:+--proxy "$HTTPS_PROXY"} https://pecl.php.net/get/redis-6.0.2.tgz -o /tmp/redis.tgz \ && curl -fsSL --connect-timeout 20 --retry 5 ${HTTPS_PROXY:+--proxy "$HTTPS_PROXY"} https://pecl.php.net/get/xdebug-3.3.2.tgz -o /tmp/xdebug.tgz \ && pecl install /tmp/redis.tgz /tmp/xdebug.tgz)) \ && docker-php-ext-enable redis xdebug \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Composer COPY --from=composer:2 /usr/bin/composer /usr/bin/composer # Composer will respect HTTP(S)_PROXY environment; no explicit config needed WORKDIR /var/www/html # Copy composer files first COPY composer.json composer.lock ./ # Install PHP dependencies without running scripts (artisan not copied yet) RUN composer install --no-dev --optimize-autoloader --no-scripts # Copy application files (excluding vendor and node_modules) COPY . . RUN rm -rf node_modules # Opcache recommended settings ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS=1 \ PHP_OPCACHE_MAX_ACCELERATED_FILES=20000 \ PHP_OPCACHE_MEMORY_CONSUMPTION=128 \ PHP_OPCACHE_MAX_WASTED_PERCENTAGE=10 # Xdebug configuration (copied into conf.d) COPY 99-xdebug.ini /usr/local/etc/php/conf.d/99-xdebug.ini CMD ["php-fpm"]

По вводным:./infra/nginx/default.conf

server { listen 80; server_name localhost; root /var/www/html/public; index index.php index.html; # PHP-FPM handler location ~ \.php$ { #include fastcgi_params; include /etc/nginx/fastcgi_params; fastcgi_pass backend:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; } # Frontend (Vue.js SPA) - все остальные запросы location / { proxy_pass http://frontend:80; } # Backend API location /api/ { try_files $uri $uri/ /index.php?$query_string; } client_max_body_size 20m; } # HTTPS server server { listen 443 ssl; http2 on; server_name localhost; ssl_certificate /etc/nginx/certs/dev.crt; ssl_certificate_key /etc/nginx/certs/dev.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; index index.php index.html; # Frontend (Vue.js SPA) - все остальные запросы location / { proxy_pass http://frontend:80; } # Backend API - send directly to PHP without filesystem checks location /api/ { proxy_pass http://backend:9000; } client_max_body_size 20m; }
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Игорь NetOps Ответ

Если php-fpm на все запросы отдаёт 404, почти всегда неверно передаётся SCRIPT_FILENAME или Nginx/контейнер смотрит в другой root, чем PHP-FPM. В Docker это особенно частая проблема: Nginx видит файлы в одном пути, а PHP-контейнер — в другом.

Проверьте Nginx location:

location ~ .php$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass php:9000;
}

location ~ .php$ { try_files $uri =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php:9000; }

Если в Docker у Nginx root /var/www/html/public, то такой же код должен быть доступен PHP-контейнеру по тому же пути. Иначе PHP-FPM получает путь, которого у него нет, и возвращает 404/Primary script unknown.

Проверьте внутри контейнеров:

docker exec -it nginx ls -la /var/www/html/public/index.php
docker exec -it php ls -la /var/www/html/public/index.php

docker exec -it nginx ls -la /var/www/html/public/index.php docker exec -it php ls -la /var/www/html/public/index.php

Если во втором контейнере файла нет — исправьте volumes. Для Laravel root должен указывать на public, а не на корень проекта.

Также смотрите логи:

docker logs nginx
docker logs php
# или php-fpm error log

docker logs nginx docker logs php # или php-fpm error log

Сообщение Primary script unknown почти всегда подтверждает неправильный путь. Ещё проверьте, что в конфиге нет alias вместо root без корректной сборки SCRIPT_FILENAME. При alias переменные пути часто собираются иначе, и PHP-FPM получает несуществующий файл.

Для Laravel дополнительно проверьте try_files $uri $uri/ /index.php?$query_string; в основном location. Если все запросы идут прямо в PHP без правильного front controller, роутинг приложения тоже может выглядеть как сплошные 404.

Итог: синхронизируйте volume paths между Nginx и PHP-FPM, проверьте root, SCRIPT_FILENAME, try_files и наличие public/index.php внутри PHP-контейнера.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно