Конфигурация веб-сервера

Дата обновления перевода 2024-07-29

Конфигурация веб-сервера

Предпочитаемым способом разработки вашего приложения Symfony является использование локального веб-сервера Symfony.

Однако, при запуске приложения в окружении производства, вам понадобится использовать веб-сервер с полным функционалом. Эта статья описывает несколько способов использования Symfony с Apache или Nginx.

Публичный каталог является домом для всех публичных и статических файлов вашего приложения, включая изображения, таблицы стилей и файлы JavaScript. В нем также в нем расположен фронт-контроллер (index.php).

Каталог public служит корнем документа при конфигурировании вашего веб-сервера. В приведенных ниже примерах корнем документа будет каталог public/. корнем документа. Этот каталог имеет адрес /var/www/project/public/.

Если ваш хостинг-провайдер требует изменить каталог public/ на другое место (например, public_html/), убедитесь, что вы переопределили расположение каталога public/ .

Конфигурирование PHP-FPM

Во всех приведенных ниже примерах конфигурации используется менеджер процессов PHP FastCGI (PHP-FPM). Убедитесь, что у вас установлен PHP-FPM (например, в системе на базе Debian необходимо установить пакет php-fpm).

PHP-FPM использует так называемые пулы для обработки входящих FastCGI-запросов. Вы можете сконфигурировать произвольное количество пулов в конфигурации FPM. В пуле вы конфигурируете либо TCP сокет (IP и порт), либо сокет домена Unix для прослушивания. Каждый пул может быть запущен под разными UID и GID:

1
2
3
4
5
6
7
8
9
10
11
12
; /etc/php/7.4/fpm/pool.d/www.conf

; a pool called www
[www]
user = www-data
group = www-data

; use a unix domain socket
listen = /var/run/php/php7.4-fpm.sock

; or listen on a TCP connection
; listen = 127.0.0.1:9000

Apache

Если вы используете Apache 2.4+, вы можете использовать mod_proxy_fcgi для передачи входящих запросов в PHP-FPM. Установите мод Apache2 FastCGI

(libapache2-mod-fastcgi на Debian), включите mod_proxy и mod_proxy_fcgi в конфигурации Apache, и используйте директиву SetHandler для передачи запросов к PHP-файлам в PHP FPM:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# /etc/apache2/conf.d/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com

    # Раскомментируйте следующую строку, чтобы заставить Apache передавать заголовок
    # авторизации в PHP: требуется для "basic_auth" в PHP-FPM и FastCGI
    #
    # SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1

    <FilesMatch \.php$>
        # при использовании PHP-FPM как сокета unix
        SetHandler proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://dummy

        # когда PHP-FPM сконфигурирован для использования TCP
        # SetHandler proxy:fcgi://127.0.0.1:9000
    </FilesMatch>

    DocumentRoot /var/www/project/public
    <Directory /var/www/project/public>
        AllowOverride None
        Require all granted
        FallbackResource /index.php
    </Directory>

    # раскомментируйте следующие строки, если вы устанавливаете ресурсы как символьные ссылки
    # или столкнулись с проблемами при компиляции ресурсов LESS/Sass/CoffeeScript
    # <Directory /var/www/project>
    #     Options FollowSymlinks
    # </Directory>

    ErrorLog /var/log/apache2/project_error.log
    CustomLog /var/log/apache2/project_access.log combined
</VirtualHost>

Nginx

Для того чтобы ваше приложение работало под управлением Nginx, требуется минимальная конфигурация:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# /etc/nginx/conf.d/example.com.conf
server {
    server_name example.com www.example.com;
    root /var/www/project/public;

    location / {
        # попытайтесь обслужить файл напрямую, резерв - index.php
        try_files $uri /index.php$is_args$args;
    }

    # опционально отключите возврат к PHP-скрипту для каталогов ресурсов; 
    # nginx будет возвращать ошибку 404, если файлы не найдены, вместо того, чтобы передавать
    # запрос в Symfony (улучшает производительность, но страница 404 Symfony не отображается)
    # location /bundles {
    #     try_files $uri =404;
    # }

    location ~ ^/index\.php(/|$) {
        # при использовании PHP-FPM как сокета unix
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;

        # когда PHP-FPM сконфигурирован для использования TCP
        # fastcgi_pass 127.0.0.1:9000;

        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        # опционально установите значение переменных окружения, используемых в приложении 
        # fastcgi_param APP_ENV prod;
        # fastcgi_param APP_SECRET <app-secret-id>;
        # fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name";

        # Когда вы используете символьные ссылки, чтобы связать корень документа с 
        # текущей версией вашего приложения, вы должны передать реальный
        # путь к приложению вместо пути к символьной ссылке в PHP
        # FPM.
        # В противном случае PHP OPcache может неправильно определить изменения в
        # ваших PHP-файлах (см. https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # для получения дополнительной информации).
        # Оговорка: Если PHP-FPM размещен на другой машине, чем nginx,
        # $realpath_root может разрешиться не так, как вы ожидаете! В этом случае попробуйте использовать
        # $document_root вместо этого.
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # Предотвращает URI, включающие фронт-контроллер. Это будет 404:
        # http://example.com/index.php/some-path
        # Удалите внутреннюю директиву, чтобы разрешить URI, подобные этому
        internal;
    }

    # вернуть 404 для всех остальных php-файлов, не соответствующих фронт-контроллеру
    # это предотвращает доступ к другим php-файлам, которые вы не хотите, чтобы были доступны
    location ~ \.php$ {
        return 404;
    }

    error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;
}

Tip

Если вы используете NGINX Unit, ознакомьтесь с официальной статьей о том Как запускать приложения Symfony с помощью NGINX Unit.

Tip

При этом выполняется только index.php в публичном каталоге. Все остальные файлы, заканчивающиеся на «.php», будут запрещены.

Если у вас есть другие PHP-файлы в публичном каталоге, которые должны быть выполнены, не забудьте добавить их в блок location выше.

Caution

После развертывания в производстве убедитесь, что вы не можете получить доступ к скрипту index.php (т. е. http://example.com/index.php).

О продвинутых опциях конфигурации Nginx читайте в официальной документации Nginx.

Caddy

При использовании Caddy на сервере вы можете использовать такую конфигурацию:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# /etc/caddy/Caddyfile
example.com, www.example.com {
    root * /var/www/project/public

    # обслуживайте файлы напрямую, если они могут быть найдены (например, CSS или JS файлы в public/)
    encode zstd gzip
    file_server

    # в противном случае используйте PHP-FPM (замените "unix//var/..." на "127.0.0.1:9000" при использовании TCP)
    php_fastcgi unix//var/run/php/php7.4-fpm.sock {
        # опционально установите значение переменных окружения, используемых в приложении
        # env APP_ENV "prod"
        # env APP_SECRET "<app-secret-id>"
        # env DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name"

        # Сконфигурировать FastCGI на разрешение всех символьных ссылок в корневом пути.
        # Это гарантирует, что OpCache будет использовать имена целевых файлов,
        # а не символьные ссылки, для кеширования опкодов и php-файлов см.
        # https://caddy.community/t/root-symlink-folder-updates-and-caddy-reload-not-working/10557
        resolve_root_symlink
    }

    # вернуть 404 для всех остальных php-файлов, не соответствующих фронт-контроллеру
    # это предотвращает доступ к другим php-файлам, которые вы не хотите, чтобы были доступны
    @phpFile {
        path *.php*
    }
    error @phpFile "Not found" 404
}

Смотрите официальную документацию Caddy для получения дополнительных примеров, таких как использование Caddy в инфраструктуре контейнеров.