Skip to content

Modernize Web Server Configuration article (remove obsolete Apache examples, add Caddy) #17597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 9, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
modernize the web server configuration chapter
  • Loading branch information
xabbuh authored and wouterj committed Aug 2, 2023
commit 035af33a75685f21e785818ff3c447de71c6417d
355 changes: 82 additions & 273 deletions setup/web_server_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@ The preferred way to develop your Symfony application is to use
:doc:`Symfony Local Web Server </setup/symfony_server>`.

However, when running the application in the production environment, you'll need
to use a fully-featured web server. This article describes several ways to use
Symfony with Apache or Nginx.
to use a fully-featured web server. This article describes how to use Symfony
with Apache or Nginx.

When using Apache, you can configure PHP as an
:ref:`Apache module <web-server-apache-mod-php>` or with FastCGI using
:ref:`PHP FPM <web-server-apache-fpm>`. FastCGI also is the preferred way
to use PHP :ref:`with Nginx <web-server-nginx>`.
.. sidebar:: The public directory

.. sidebar:: The ``public/`` directory

The ``public/`` directory is the home of all of your application's public and
The public directory is the home of all of your application's public and
static files, including images, stylesheets and JavaScript files. It is
also where the front controller (``index.php``) lives.

Expand All @@ -27,7 +22,83 @@ to use PHP :ref:`with Nginx <web-server-nginx>`.
another location (e.g. ``public_html/``) make sure you
:ref:`override the location of the public/ directory <override-web-dir>`.

.. _web-server-nginx:
Apache with PHP-FPM
-------------------

To make use of PHP-FPM with Apache, you first have to ensure that you have
the FastCGI process manager ``php-fpm`` binary and Apache's FastCGI module
installed (for example, on a Debian based system you have to install the
``libapache2-mod-fastcgi`` and ``php7.4-fpm`` packages).

PHP-FPM uses so-called *pools* to handle incoming FastCGI requests. You can
configure an arbitrary number of pools in the FPM configuration. In a pool
you configure either a TCP socket (IP and port) or a Unix domain socket to
listen on. Each pool can also be run under a different UID and GID:

.. code-block:: ini

; 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 socket
listen = 127.0.0.1:9000

Using mod_proxy_fcgi with Apache 2.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are running Apache 2.4, you can use ``mod_proxy_fcgi`` to pass incoming
requests to PHP-FPM. Configure PHP-FPM to listen on a TCP or Unix socket, enable
``mod_proxy`` and ``mod_proxy_fcgi`` in your Apache configuration, and use the
``SetHandler`` directive to pass requests for PHP files to PHP FPM:

.. code-block:: apache

<VirtualHost *:80>
ServerName domain.tld
ServerAlias www.domain.tld

# Uncomment the following line to force Apache to pass the Authorization
# header to PHP: required for "basic_auth" under PHP-FPM and FastCGI
#
# SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1

# For Apache 2.4.9 or higher
# Using SetHandler avoids issues with using ProxyPassMatch in combination
# with mod_rewrite or mod_autoindex
<FilesMatch \.php$>
SetHandler proxy:fcgi://127.0.0.1:9000
# for Unix sockets, Apache 2.4.10 or higher
# SetHandler proxy:unix:/path/to/fpm.sock|fcgi://dummy
</FilesMatch>

# If you use Apache version below 2.4.9 you must consider update or use this instead
# ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/public/$1

# If you run your Symfony application on a subpath of your document root, the
# regular expression must be changed accordingly:
# ProxyPassMatch ^/path-to-app/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/public/$1

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

# uncomment the following lines if you install assets as symlinks
# or run into problems when compiling LESS/Sass/CoffeeScript assets
# <Directory /var/www/project>
# Options FollowSymlinks
# </Directory>

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

Nginx
-----
Expand All @@ -53,7 +124,7 @@ The **minimum configuration** to get your application running under Nginx is:
# }

location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;

Expand Down Expand Up @@ -115,268 +186,6 @@ The **minimum configuration** to get your application running under Nginx is:

For advanced Nginx configuration options, read the official `Nginx documentation`_.

.. _web-server-apache-mod-php:

Adding Rewrite Rules for Apache
-------------------------------

The easiest way is to install the ``apache`` :ref:`Symfony pack <symfony-packs>`
by executing the following command:

.. code-block:: terminal

$ composer require symfony/apache-pack

This pack installs a ``.htaccess`` file in the ``public/`` directory that contains
the rewrite rules needed to serve the Symfony application.

In production servers, you should move the ``.htaccess`` rules into the main
Apache configuration file to improve performance. To do so, copy the
``.htaccess`` contents inside the ``<Directory>`` configuration associated to
the Symfony application ``public/`` directory (and replace ``AllowOverride All``
by ``AllowOverride None``):

.. code-block:: apache

<VirtualHost *:80>
# ...
DocumentRoot /var/www/project/public

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

# Copy .htaccess contents here
</Directory>
</VirtualHost>

Apache with mod_php/PHP-CGI
---------------------------

The **minimum configuration** to get your application running under Apache is:

.. code-block:: apache

<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>

# uncomment the following lines if you install assets as symlinks
# or run into problems when compiling LESS/Sass/CoffeeScript assets
# <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/``.

Use the following **optimized configuration** to disable ``.htaccess`` support
and increase web server performance:

.. code-block:: apache

<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>

# uncomment the following lines if you install assets as symlinks
# or run into problems when compiling LESS/Sass/CoffeeScript assets
# <Directory /var/www/project>
# Options FollowSymlinks
# </Directory>

# optionally disable the fallback resource for the asset directories
# which will allow Apache to return a 404 error when files are
# not found instead of passing the request to 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

# optionally set the value of the environment variables used in the application
#SetEnv APP_ENV prod
#SetEnv APP_SECRET <app-secret-id>
#SetEnv DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name"
</VirtualHost>

.. caution::

Use ``FallbackResource`` on Apache 2.4.25 or higher, due to a bug which was
fixed on that release causing the root ``/`` to hang.

.. tip::

If you are using **php-cgi**, Apache does not pass HTTP basic username and
password to PHP by default. To work around this limitation, you should use
the following configuration snippet:

.. code-block:: apache

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

Using mod_php/PHP-CGI with Apache 2.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In Apache 2.4, ``Order Allow,Deny`` has been replaced by ``Require all granted``.
Hence, you need to modify your ``Directory`` permission settings as follows:

.. code-block:: apache

<Directory /var/www/project/public>
Require all granted
# ...
</Directory>

For advanced Apache configuration options, read the official `Apache documentation`_.

.. _web-server-apache-fpm:

Apache with PHP-FPM
-------------------

To make use of PHP-FPM with Apache, you first have to ensure that you have
the FastCGI process manager ``php-fpm`` binary and Apache's FastCGI module
installed (for example, on a Debian based system you have to install the
``libapache2-mod-fastcgi`` and ``php<version>-fpm`` packages).

PHP-FPM uses so-called *pools* to handle incoming FastCGI requests. You can
configure an arbitrary number of pools in the FPM configuration. In a pool
you configure either a TCP socket (IP and port) or a Unix domain socket to
listen on. Each pool can also be run under a different UID and GID:

.. code-block:: ini

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

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

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

Using mod_proxy_fcgi with Apache 2.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are running Apache 2.4, you can use ``mod_proxy_fcgi`` to pass incoming
requests to PHP-FPM. Configure PHP-FPM to listen on a TCP or Unix socket, enable
``mod_proxy`` and ``mod_proxy_fcgi`` in your Apache configuration, and use the
``SetHandler`` directive to pass requests for PHP files to PHP FPM:

.. code-block:: apache

<VirtualHost *:80>
ServerName domain.tld
ServerAlias www.domain.tld

# Uncomment the following line to force Apache to pass the Authorization
# header to PHP: required for "basic_auth" under PHP-FPM and FastCGI
#
# SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1

# For Apache 2.4.9 or higher
# Using SetHandler avoids issues with using ProxyPassMatch in combination
# with mod_rewrite or mod_autoindex
<FilesMatch \.php$>
SetHandler proxy:fcgi://127.0.0.1:9000
# for Unix sockets, Apache 2.4.10 or higher
# SetHandler proxy:unix:/path/to/fpm.sock|fcgi://dummy
</FilesMatch>

# If you use Apache version below 2.4.9 you must consider update or use this instead
# ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/public/$1

# If you run your Symfony application on a subpath of your document root, the
# regular expression must be changed accordingly:
# ProxyPassMatch ^/path-to-app/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/project/public/$1

DocumentRoot /var/www/project/public
<Directory /var/www/project/public>
# enable the .htaccess rewrites
AllowOverride All
Require all granted
</Directory>

# uncomment the following lines if you install assets as symlinks
# or run into problems when compiling LESS/Sass/CoffeeScript assets
# <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 with Apache 2.2
~~~~~~~~~~~~~~~~~~~~~~~

On Apache 2.2 or lower, you cannot use ``mod_proxy_fcgi``. You have to use
the `FastCgiExternalServer`_ directive instead. Therefore, your Apache configuration
should look something like this:

.. code-block:: apache

<VirtualHost *:80>
ServerName domain.tld
ServerAlias www.domain.tld

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

DocumentRoot /var/www/project/public
<Directory /var/www/project/public>
# enable the .htaccess rewrites
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>

# uncomment the following lines if you install assets as symlinks
# or run into problems when compiling LESS/Sass/CoffeeScript assets
# <Directory /var/www/project>
# Options FollowSymlinks
# </Directory>

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

If you prefer to use a Unix socket, you have to use the ``-socket`` option
instead:

.. code-block:: apache

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

.. _`Apache documentation`: https://httpd.apache.org/docs/
.. _`FastCgiExternalServer`: https://docs.oracle.com/cd/B31017_01/web.1013/q20204/mod_fastcgi.html#FastCgiExternalServer
.. _`Nginx documentation`: https://www.nginx.com/resources/wiki/start/topics/recipes/symfony/
Expand Down