In this article, you will learn how to setup webserver for serving Drupal websites running with Nginx, PHP-FPM 7.4, MySQL and phpMyAdmin on Ubuntu 20.04
For the following tutorial, I used very much the information from my previous guide with Ubuntu 18.04, but I decided to rewrite it for Ubuntu 20.04 version as it is shipped with php7.4 version and will work for Drupal 7, Drupal 8 and most probably for Drupal 9
Prerequisites
- Ubuntu 20.04
- Root privileges.
You can get a cheap VPS starting just $5/mo from Linode. That's what I did - bought a new nanode from Linode
Deploying server with Linode
Literally in a couple of seconds, the new server was up and running - that's what I love sticking with Linode for years
Follow basic security guide, see: Securing Your Server
I will use Putty for Windows to access SSH
Secure your server
Create the user, replacing example_user with your desired username. You’ll then be asked to assign the user a password:
adduser example_user
Add the user to the sudo group so you’ll have administrative privileges:
adduser example_user sudo
Disallow root logins over SSH. This requires all SSH connections to be by non-root users. Once a limited user account is connected, administrative privileges are accessible either by using sudo or changing to a root shell using su -.
sudo nano /etc/ssh/sshd_config
Under # Authetification section change to
# Authentication: ... PermitRootLogin no
Update the Ubuntu system
sudo apt-get update
Install Nginx and PHP-FPM
Install Nginx with the following apt command:
sudo apt-get install nginx -y
Next, install php7.4-fpm with php-gd extension that is required by Drupal core:
sudo apt-get install php7.4-fpm php7.4-cli php7.4-gd php7.4-mysql php7.4-xml -y
Configure Nginx and PHP-FPM
In this step, we will configure Nginx to use php-fpm to serve HTTP requests for PHP pages. Go to the php-fpm directory "/etc/php/7.4/fpm" and edit the "php.ini" file:
sudo nano /etc/php/7.4/fpm/php.ini
Un-comment the cgi.fix_pathinfo line and change the value to "0"
When using nano command you can use CTRL+W to locate that line. Once changed press CTRL+O to save changes and CTRL+X to exit from nano editor
Now we should modify the default Nginx virtual host configuration. Edit the "default" file and enable the php-fpm directive.
sudo nano /etc/nginx/sites-available/default
Un-comment location ~ \.php$ section, so it look like this
location ~ \.php$ { include snippets/fastcgi-php.conf; # With php7.4-cgi alone: #fastcgi_pass 127.0.0.1:9000; # With php7.4-fpm: fastcgi_pass unix:/run/php/php7.4-fpm.sock; }
CTRL+O and CTRL+X
Then test the Nginx configuration with the command "nginx -t" to ensure that it is valid:
nginx -t
If there is no error, restart nginx and the php-fpm service:
systemctl restart nginx systemctl restart php7.4-fpm
PHP Info file (Optional)
Next, test that php-fpm is working properly with Nginx by creating new PHP info file in the web directory "/var/www/html"
cd /var/www/html/ echo "<?php phpinfo(); ?>" > info.php
Visit the info.php file at the server IP in a web browser.
Configure the VirtualHost for Drupal
We will install Drupal 8 in the directory "/srv/www/0dtespxtrading.com". Please replace my domain name in your installation with the domain name of the website that you want to use this Drupal installation for. So let's create the directory:
sudo mkdir -p /srv/www/0dtespxtrading.com/{public_html,logs} sudo usermod -a -G www-data admin sudo chown -R www-data:www-data /srv/www sudo chmod -R 775 /srv/www sudo nano /etc/nginx/sites-available/0dtespxtrading.com
Paste the Nginx configuration for Drupal 8:
server { server_name 0dtespxtrading.com; root /srv/www/0dtespxtrading.com/public_html; ## <-- Your only path $ access_log /srv/www/0dtespxtrading.com/logs/access.log; error_log /srv/www/0dtespxtrading.com/logs/error.log; listen 80; listen [::]:80; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } # Very rarely should these ever be accessed outside of your lan location ~* \.(txt|log)$ { allow 192.168.0.0/16; deny all; } location ~ \..*/.*\.php$ { return 403; } location ~ ^/sites/.*/private/ { return 403; } # Block access to "hidden" files and directories whose names begin with a # period. This includes directories used by version control systems such # as Subversion or Git to store control files. location ~ (^|/)\. { return 403; } location / { # try_files $uri @rewrite; # For Drupal <= 6 try_files $uri /index.php?$query_string; # For Drupal >= 7 } location @rewrite { rewrite ^/(.*)$ /index.php?q=$1; } # In Drupal 8, we must also match new paths where the '.php' appears in the middle, # such as update.php/selection. The rule we use is strict, and only allows this pattern # with the update.php front controller. This allows legacy path aliases in the form of # blog/index.php/legacy-path to continue to route to Drupal nodes. If you do not have # any paths like that, then you might prefer to use a laxer rule, such as: # location ~ \.php(/|$) { # The laxer rule will continue to work if Drupal uses this new URL pattern with front # controllers other than update.php in a future release. location ~ '\.php$|^/update.php' { fastcgi_split_path_info ^(.+?\.php)(|/.*)$; #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini include fastcgi_params; include snippets/fastcgi-php.conf; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_intercept_errors on; fastcgi_pass unix:/run/php/php7.4-fpm.sock; } # Fighting with Styles? This little gem is amazing. # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6 location ~ ^/sites/.*/files/styles/ { # For Drpal >= 7 try_files $uri @rewrite; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; } }
CTRL+O and CTRL + X
The Drupal virtual host file has been created, now we have to activate it by creating a symlink to the file in the "sites-enabled" directory:
ln -s /etc/nginx/sites-available/0dtespxtrading.com /etc/nginx/sites-enabled/
Test the Nginx configuration and if there are no errors restart Nginx:
nginx -t systemctl restart nginx
Install MySQL
sudo apt-get install mysql-server sudo mysql_secure_installation
Install phpMyAdmin
sudo apt-get install phpmyadmin
Hit ESC when the installation prompts you for auto-configuration because there is no option for Nginx.
Make an easily accessible symlink
sudo ln -s /usr/share/phpmyadmin/ /srv/www/0dtespxtrading.com/public_html/phpmyadmin
Install and Configure Drupal
Enter the directory that we created earlier and download Drupal with wget. I'm using the latest Drupal 8.8.6. release as of May 20, 2020, make sure you are downloading latest version by visiting Drupal 8 download page and writing down the last numbers (version)
cd /srv/www/0dtespxtrading.com sudo wget https://ftp.drupal.org/files/projects/drupal-8.8.6.tar.gz sudo tar -xvzf drupal-8.8.6.tar.gz sudo cp drupal-8.8.6/* public_html/ -R sudo chown www-data:www-data public_html -R
Now visit your Drupal site in the web Browser, you should see the following screen
Drupal 8 welcome screen
Now, it's just time to connect the database and set up your Drupal 8 website