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

Дата обновления перевода 2021-06-09

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

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

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

При использовании Apache, вы можете сконфигурировать PHP как Apache-модуль или с FastCGI, используя PHP FPM. FastCGI также является предпочитаемым способом использования PHP с Nginx.

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

Веб-каталог служит в качестве корня документа при конфигурации вашего веб-сервера. В примерах ниже, каталог web/ будет корнем документа. Этот каталог - /var/www/project/web/.

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

Добавление правил перезаписи

Самый простой способ установить пакет Symfony apache - выполнив следующую команду:

1
$ composer require symfony/apache-pack

Этот пакет устанавливает файл .htaccess в каталоге public/, который содержит правила перезаписи, необходимые для обслуживания приложения Symfony.

На серверах производства, вы должны переместить правила .htaccess в главный файл конфигурации Apache, чтобы улучшить производительность. Чтобы сделать это, скопируйте содержание .htaccess в конфигурацию <Directory>, аосоциированную с каталогом приложения Symfony public/ (и замените AllowOverride All на AllowOverride None):

1
2
3
4
5
6
7
8
9
10
<VirtualHost *:80>
    # ...
    DocumentRoot /var/www/project/public

    <Directory /var/www/project/public>
        AllowOverride None

        # Скопируйте содержание .htaccess сюда
    </Directory>
</VirtualHost>

Apache с mod_php/PHP-CGI

Минимальной конфигурацией необходимой для запуска вашего приложения под Apache является:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<VirtualHost *:80>
    ServerName domain.tld
    ServerAlias www.domain.tld

    DocumentRoot /var/www/project/public
    <Directory /var/www/project/public>
        AllowOverride All
        Order Allow,Deny
        Allow from All
    </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>

Tip

If your system supports the APACHE_LOG_DIR variable, you may want to use ${APACHE_LOG_DIR}/ instead of hardcoding /var/log/apache2/.

Используйте следующую оптимизированную конфигурацию, чтобы отключить поддержку .htaccess и увеличить производительность веб-сервера:

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
<VirtualHost *:80>
    ServerName domain.tld
    ServerAlias www.domain.tld

    DocumentRoot /var/www/project/public
    DirectoryIndex /index.php

    <Directory /var/www/project/public>
        AllowOverride None
        Order Allow,Deny
        Allow from All

        FallbackResource /index.php
    </Directory>

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

    # по желанию отключите RewriteEngine для каталогов ресурсов,
    # что позволит apache просто отвечать ошибкой 404, когда файлы
    # не найдены, вместо того, чтобы передавать запрос в symfony
    <Directory /var/www/project/public/bundles>
        DirectoryIndex disabled
        FallbackResource disabled
    </Directory>
    ErrorLog /var/log/apache2/project_error.log
    CustomLog /var/log/apache2/project_access.log combined

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

Caution

Используйте FallbackResource в Apache 2.4.25 или выше, в связи с проблемой, вызывающая подвисание корня /, которая была исправлена в этом релизе.

Tip

Если вы используете php-cgi, Apache не передаёт базовые HTTP имя пользователя и пароль в PHP по умолчанию. Чтобы обойти это ограничение, вам стоит использовать следующий отрезок конфигурации:

1
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Использование mod_php/PHP-CGI с Apache 2.4

В Apache 2.4, Order Allow,Deny был заменён Require all granted. Поэтому вам нужно будет изменить ваши настройки доступа Directory следующим образом:

1
2
3
4
<Directory /var/www/project/web>
    Require all granted
    # ...
</Directory>

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

Apache с PHP-FPM

Чтобы воспользоваться PHP5-FPM в Apache, вам для начала надо убедиться в том, что у вас установлены менеджер бинарный процессов FastCGI php-fpm и модуль Apache FastCGI (например, в системе, основанной на Debian, вам понадобится установить пакеты libapache2-mod-fastcgi и php7.4-fpm).

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

1
2
3
4
5
6
7
8
9
10
; пул под названием www
[www]
user = www-data
group = www-data

; использовать сокет unix-домена
listen = /var/run/php/php7.4-fpm.sock

; или прослушивать сокет TCP
listen = 127.0.0.1:9000

Использование mod_proxy_fcgi с Apache 2.4

Если вы запускаете Apache 2.4, вы с лёгкостью можете использовать mod_proxy_fcgi, чтобы передать входящие запросы PHP-FPM. Сконфигурируйте PHP-FPM для прослушивания канала TCP или Unix-домена, включите 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
35
36
37
38
39
40
41
<VirtualHost *:80>
    ServerName domain.tld
    ServerAlias www.domain.tld

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

    # Для версии Apache 2.4.9 или новее
    # Использование SetHandler помогает избежаь проблем при исползовании ProxyPassMatch в комбинации
    # с mod_rewrite или mod_autoindex
    <FilesMatch \.php$>
        SetHandler proxy:fcgi://127.0.0.1:9000
        # Для Unix-каналов, Apache 2.4.10 или новее,
        # SetHandler proxy:unix:/path/to/fpm.sock|fcgi://dummy
    </FilesMatch>

    # Если вы используете более раннюю версию Apache, чем 2.4.9, вы должны рассмотреть вариант
    # обновления или используйте вместо этого
    # ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/web/$1

    # Если вы запускаете ваше приложение Symfony на субпути вашего документа корня,
    # регулярное выражение должно быть изменено соответственно:
    # ProxyPassMatch ^/path-to-app/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/web/$1

    DocumentRoot /var/www/project/web
    <Directory /var/www/project/web>
        # enable the .htaccess rewrites
        AllowOverride All
        Require all granted
    </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>

PHP-FPM с Apache 2.2

В версии Apache 2.2, или старее, вы не можете использовать mod_proxy_fcgi. Вам нужно использовать вместо этого указание FastCgiExternalServer. Поэтому, ваша конфигурация Apache должна выглядеть как-то так:

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
<VirtualHost *:80>
    ServerName domain.tld
    ServerAlias www.domain.tld

    AddHandler php5-fcgi .php
    Action php5-fcgi /php5-fcgi
    Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
    FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization

    DocumentRoot /var/www/project/web
    <Directory /var/www/project/web>
        # включите перезапись .htaccess
        AllowOverride All
        Order Allow,Deny
        Allow from all
    </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>

Если вы предпочитаете использовать Unix-сокет, то вместо этого вам стоит использовать опцию -socket:

1
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization

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
server {
    server_name domain.tld www.domain.tld;
    root /var/www/project/public;

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
    }

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

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        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 реальный путь
        # приложения вместо пути символьной ссылки.
        # Иначе, OPcache PHP может неверно определить изменения в ваших PHP-файлах
        # (см. https://github.com/zendtech/ZendOptimizerPlus/issues/126, чтобы узнать
        # больше информации).
        # Caveat: Когда 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://domain.tld/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.

Note

В зависимости от вашей конфигурации PHP-FPM config, fastcgi_pass также может быть fastcgi_pass 127.0.0.1:9000.

Tip

Это выполняет только app.php, app_dev.php и config.php в веб-каталоге. Все другие файлы, заканчивающиеся на ".php", получат отказ.

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

Caution

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

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