How to Setup Nginx for a PHP application on Fedora 28/29
After switching from Linux Mint to Fedora 28/29 on my laptop, I had difficulties to run my Grav CMS or other PHP projects on Fedora OS. In the last 2 months, I've learned several things about the different between the Ubuntu-based OS and the RHEL-based OS. They are similar but some small differences can take so much time to run one application from other OS to another OS. My motivation was to clone my projects from my Git repositories (which were created under Linux Mint and Ubuntu), and run them on my laptop with Fedora 29. Unfortunately, it was not so easy and took more time as I thought.
Mostly the Fedora OS is just similar like other Linux distributions. Instead of sudo apt-get install
, we write sudo dnf install
for installing a new software package. So I can install Nginx and PHP-FPM with this command line:
sudo dnf install nginx php-fpm php-common
By default, the installed PHP creates a system user and a group name on Fedora which are declared as apache
, where in Ubuntu we can find it as www-data
. This difference can cause several permission issues if I want to run my Grav project (or other PHP web project) on Fedora 28/29 directly after git clone
.
In my case, the Grav app runs on my server with Ubuntu 18.04. I synchronized the file from a Git repository of my server. After the clone, the folder group name is assigned as www-data
. Since I don't want to have an inconsistency, I decided to use www-data
instead of apache
in my laptop.
In Fedora, the official place for the project directory is in /srv/www/mysite. However since I synchronize the project directory with git clone
to my home folder, I need to ensure that the parent directories which points to the root folder has also a permission access for www-data
. Otherwise I see an error message in /var/log/nginx/error.log. It can contain failed (13: Permission denied), for example:
2018/10/15 19:15:10 [crit] 31049#0: *1 stat() "/var/www/testsite/user/themes/antimatter/css/slidebars.min.css" failed (13: Permission denied), client: 127.0.0.1, server: testsite, request: "GET /user/themes/antimatter/css/slidebars.min.css HTTP/1.1", host: "testsite", referrer: "http://testsite/"
For more details, please read these discussions:
Fedora 28/29 Setting
Let's begin with the operating system first.
-
As described before, I create a new system user called www-data as replacement to apache without home directory:
sudo useradd -Mr www-data
Maybe I can check whether the
www-data
user has been created before. To check its existence we need this command:ls /etc/group | grep www-data
- Clone the Grav project from your Git repository, for example to $HOME/mysite.
-
Disable SELinux for NGINX:
sudo semanage permissive -a httpd_t
Or optionally you can allow
httpd
to access and write the user home directory (SELinux):sudo chcon -R -t httpd_sys_rw_content_t $HOME/mysite
SE Linux Permission type Description httpd_sys_content_t Read-only directories and files used by Apache httpd_sys_rw_content_t Readable and writable directories and files used by Apache. Assign this to directories where files can be created or modified by your application, or assign it to files directory to allow your application to modify them.
Nginx Setting
These steps are my summary to install and configure Nginx:
- Install Nginx:
dnf install nginx
. - Change the user of the Nginx process to www-data by opening the default config file in /etc/nginx/nginx.conf. Uncomment the first line user nginx and replace with user
www-data
. Check if include sites-enabled/; or include /etc/nginx/sites-enabled/; exists in /etc/nginx/nginx.conf. You can copy the nginx.conf from https://learn.getgrav.org/webservers-hosting/servers/nginx/. -
Create a nginx config file for your site under /etc/nginx/sites-available/mysite.conf, You can copy the configuration file from your downloaded Grav directory under webserver-configs/nginx.conf. Then, do these steps:
- adapt the
root
folder, - adapt the
server_name
, - add accesslog and error_log folders to /var/log/nginx/mysite/_ (don't forget the semicolon at the end),
- create the new directory
sudo mkdir /var/log/nginx/mysite
, - modify the
fastcgi_pass
path tounix:/run/php-fpm/php7.2-fpm.sock
, since on Fedora the PHP folder installation is slightly different compared to the Ubuntu (check the PHP section below).
Please see the details in the grav-site config section in https://learn.getgrav.org/webservers-hosting/servers/nginx/.
- adapt the
-
Create a symbolic link to the /etc/nginx/sites-enabled/, e.g.:
ln -s /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/mysite.conf
-
activate the Nginx server:
sudo systemctl enable nginx.service sudo systemctl start nginx.service
-
Check if the Nginx worker process runs with
www-data
as the user:ps aux | grep nginx
for example it returns:
www-data 5973 0.0 0.0 39208 4752 ? S 11:44 0:00 nginx: worker process
-
Set the group of _/var/lib/nginx/ to
www-data
sudo chgrp www-data -R /var/lib/nginx
-
Ensure that the directories to your root folder has a permission access for
www-data
:ls -l $HOME/testsite
PHP-FPM Setting
These steps help me to configure the PHP-FPM using the socket communication:
-
Install
php-fpm
andphp-common
:sudo dnf install php-fpm php-common
-
Install the required php modules:
dnf install php-opcache php-json php-cli php-dom php-gd php-mbstring php-xml
-
Edit the file /etc/php-fpm.d/www.conf, or create a new config file like /etc/php-fpm.d/grav.conf. Suppose I use the default www.conf file, then these setting are important:
user = www-data group = www-data ; Note that in Ubuntu 18.04 the socket is under /run/php/php7.2-fpm.sock listen = /run/php-fpm/php7.2-fpm.sock listen.owner = www-data listen.group = www-data
Note that
listen.acl_users
has to stay commented. Otherwise the /run/php-fpm/php7.2-fpm.sock will be assigned as root for the owner and the group. -
Edit the default config in /etc/php.ini:
file_uploads = On allow_url_fopen = On memory_limit = 256M upload_max_filesize = 100M max_execution_time = 360 cgi.fix_pathinfo = 0
-
Enable and start the php-fpm pool daemon:
sudo systemctl enable php-fpm.service sudo systemctl start php-fpm.service
-
Check the user of the running php-fpm pool is
www-data
:ps aux | grep php-fpm
These output shows the two PHP pool (
grav
andwww
) with different usernames:www-data 6835 0.0 0.0 411644 10476 ? S 12:01 0:00 php-fpm: pool grav apache 6840 0.0 0.0 411644 10484 ? S 12:01 0:00 php-fpm: pool www
-
Due to the custom username
www-data
instead ofapache
, we need the change the group folder of /var/lib/php/session, /var/lib/php/opcache, and /var/lib/php/wsdlcache.sudo chgrp www-data -R /var/lib/php/session /var/lib/php/opcache /var/lib/php/wsdlcache
Execute this command to check the group owner:
ls -l /var/lib/php
.
Grav Setting
This section describes the Grav CMS as a specific PHP application. Errors, that come from the Grav CMS, can be seen in the /logs/grav.log file. The first step before analysing the error is to clear the cache using bin/grav clear-cache
or sudo bin/grav clear-cache
if you encounter the permission denied error.
Troubleshooting
This section describes all issues that I've encountered.
502 Bad Gateway
the error.log shows:
2018/12/23 12:22:03 [crit] 7780#0: *1 stat() "$HOME/mysite" failed (13: Permission denied), client: 127.0.0.1, server: localhost.mysite, request: "GET / HTTP/1.1", host: "localhost.mysite"
2018/12/23 12:22:03 [crit] 7780#0: *1 connect() to unix:/run/php-fpm/php7.2-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: localhost.mysite, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php-fpm/php7.2-fpm.sock:", host: "localhost.mysite"
Cause
The group owner of socket file is not the same as the Nginx and PHP user:
ls -l /run/php-fpm/
total 4
srw-rw----. 1 root root 0 23. Dez 12:21 php7.2-fpm.sock
Which means that the listen.owner
and listen.group
in /etc/php-fpm.d/grav.conf are not set correctly or are still commented.
Solution
Change these lines in /etc/php-fpm.d/grav.conf:
listen.owner = www-data
listen.group = www-data
and restart the php-fpm application:
sudo systemctl restart php-fpm.service
/logs/grav.log
Error Logs in grav.Critical: Failed to start session: session_start(): Failed to read session data: filse ( path: /var/lib/php/session)
Cause:
The PHP pool daemon with the user www-data cannot write on the folder /var/lib/php/session
because on Fedora the standard group name is apache
.
Solution:
sudo chgrp -R www-data /var/lib/php/opcache /var/lib/php/session /var/lib/php/wsdlcache
CSS and JS files are interpreted as MIME type
Error:
CSS and JS files are interpreted as MIME type text/html
or
2018/10/15 19:15:10 [crit] 31049#0: *1 stat() "/var/www/testsite/user/themes/antimatter/css/slidebars.min.css" failed (13: Permission denied), client: 127.0.0.1, server: testsite, request: "GET /user/themes/antimatter/css/slidebars.min.css HTTP/1.1", host: "testsite", referrer: "http://testsite/"
Solution: https://github.com/getgrav/grav/issues/2224
Permission error in logs/grav.log
2018/12/23 15:59:03 [error] 14318#0: *10 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught UnexpectedValueException: The stream or file "$HOME/mysite/logs/grav.log" could not be opened: failed to open stream: Permission denied in $HOME/mysite/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107
Stack trace:#0 $HOME/mysite/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array)
Cause
The grav.log file cannot be written due to the permission issue.
Solution
sudo chmod 664 logs/grav.log