How to Install Drupal 9 with Nginx and Let's Encrypt SSL on Debian 10

Drupal is a well-known open source content management system based on PHP. It is available free of charge and released under the GNU General Public License. Drupal can be used for all sizes of websites, from huge international websites to personal blogs and corporate or government sites.

The core part of drupal is named "Drupal Core", it contains the basic content management system, user management, menu management, layout customization and system administration. Drupal Core can be extended by plugins, until now, the drupal community has been provided more than 31.000 modules for Drupal.

In this tutorial, we will show you how to install Drupal 9 on the Debian Buster 10. We will run Drupal under the LEMP Stack (Linux, Nginx, MySQL/MariaDB, and PHP-FPM), and secure the installation using the SSL Letsencrypt.


For this guide, we will test our Drupal installation on the latest version of Debian Buster 10 with 2GB of RAM, 50GB free disk space, and 2 CPUs. Also, we need the root sudo privileges for installing new packages and editing some system software configuration.

What will we do?

  • Install Nginx Webserver
  • Install and Configure PHP-FPM
  • Install and Configure MariaDB
  • Generate SSL Letsencrypt
  • Setup Nginx Virtualhost for Drupal 9
  • Download Drupal 9 Source Code
  • Drupal 9 Post Installation

Step 1 - Install Nginx Webserver

First, we will install the Nginx web server on our Debian server.

Update available repositories on your system and upgrade all packages to the latest version using the apt command below.

sudo apt update
sudo apt upgrade

Next, install the Nginx web server packages using the following command.

sudo apt install nginx -y

Once all installation is completed, start the Nginx service and add it to the system boot.

systemctl start nginx
systemctl enable nginx

The Nginx service is up and running, check it using the following command.

systemctl status nginx

Below is the result you will get.

Install Nginx

As a result, the Nginx service is up and running on the Debian Buster 10.

Step 2 - Install and Configure PHP-FPM

In this step, we will install and configure PHP-FPM 7.3 on the Debian 10 for our Drupal installation.

Install PHP and PHP-FPM packages 7.3 using the apt command below.

sudo apt install php php-fpm php-gd php-common php-mysql php-apcu php-gmp php-curl php-intl php-mbstring php-xmlrpc php-gd php-xml php-cli php-zip -y

Once all installation is finished, go to the '/etc/php/7.3' directory and edit the configuration 'php.ini' using vim editor.

cd /etc/php/7.3/fpm/
vim php.ini

Uncomment and change details configuration as below.

date.timezone = Asia/Singapore
memory_limit = 256M
upload_max_filesize = 64M
max_execution_time = 600
cgi.fix_pathinfo = 0

Save and close.

Next, restart the PHP-FPM service and add it to the system boot.

systemctl restart php7.3-fpm
systemctl enable php7.3-fpm

The PHP-FPM service is up and running, and by default, it's running under the sock file

start php-fpm service

Check the PHP-FPM service using the following command.

ss -plnt | grep php
systemctl status php7.3-fpm

Below is the result you will get.

check php-fpm service and sock file

As a result, the PHP-FPM installation and configuration for Drupal 9 on Debian Buster 10 have been completed.

Step 3 - Install and Configure MariaDB Server

After installing PHP and PHP-FPM packages, we will install the MariaDB database and create a new database for Drupal 9.

Install MariaDB packages using the apt command below.

sudo apt install mariadb-server mariadb-client

After that, start the MariaDB service and add it to the system boot.

systemctl start mysql
systemctl enable mysql

As a result, the MariaDB database has been installed on the Debian server.

setup MySQL root password

Next, we will set up the password for default MariaDB root user using the 'mysql_secure_installation' command as below.


Type the password for default root and type 'Y' for all options.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Set a root password? [Y/n] Y
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y

And the MariaDB root password has been configured.

Next, we need access to the MySQL shell and create a new database and user for our Drupal installation.

Login to the MySQL shell with the default root user and your password as below.

mysql -u root -p

Create a new database named 'drupaldb' and the user 'drupaluser' with the password '[email protected]' using the MySQL queries below.

create database drupaldb;
create user [email protected] identified by '[email protected]';
grant all privileges on drupaldb.* to [email protected] identified by '[email protected]';
flush privileges;

Type 'exit' or press the 'Ctrl+d' button to exit from the MySQL shell.

Create Database for drupal

As a result, the new database and user for Drupal installation has been created.

Step 4 - Generate SSL Letsencrypt

For this tutorial, we will secure the Drupal 9 installation using the SSL Letsencrypt. So make sure that you've domain name which resolved to your server IP address.

To use the SSL Letsencrypt, we need to generate SSL certificates with the certbot tool.

Install the certbot tool using the apt command below.

sudo apt install certbot -y

After that, stop the Nginx service and generate the SSL Letsencrypt for your Drupal domain name using the following command.

systemctl stop nginx
certbot certonly --rsa-key-size 2048 --standalone --agree-tos --no-eff-email --email [email protected] -d

Make sure to change the email address with your own. Once all is completed, your SSL certificates will be available at the '/etc/letsencrypt/live/' directory.

Step 6 - Set up Nginx Virtualhost for Drupal 9

In this step, we will create a new Nginx virtual host configuration for Drupal.

Go to the etc/nginx/sites-available directory and create new virtual host configuration 'drupal9' using vim editor.

cd /etc/nginx/sites-available/
vim drupal9

Change the domain name and path of the SSL Letsencrypt certificates with your own, the paste into it.

server {
    root /var/www/drupal9; ## <-- Your only path reference.

    listen 80;
    listen [::]:80;
    listen 443 default ssl;

    ssl_certificate      /etc/letsencrypt/live/;
    ssl_certificate_key  /etc/letsencrypt/live/;

    # Redirect HTTP to HTTPS
    if ($scheme = http) {
        return 301 https://$server_name$request_uri;

    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)$ {
        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.3-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;

Save and close.

Next, activate the Nginx virtual host configuration for Drupal.

ln -s /etc/nginx/sites-available/drupal9 /etc/nginx/sites-enabled/

Now test the Nginx configuration and make sure there is no error, then restart the Nginx service.

nginx -t
systemctl restart nginx

As a result, the configuration of Nginx virtual host for Drupal has been completed.

Setup Nginx virtual host for Drupal

Step 6 - Download Drupal

In this step, we will download and install the latest Drupal version 9 to the '/var/www' directory.

Now go to the '/var/www' directory and download the Drupal source code using the wget command as below.

cd /var/www/
wget -q -O drupal-latest.tar.gz

Extract the drupal source code and rename the directory to 'drupal9'.

tar -xf drupal-latest.tar.gz
mv drupal-9*/ drupal9/

After that, change the ownership of the Drupal installation directory to the user 'www-data'.

chown -R www-data:www-data /var/www/drupal9

As a result, the Drupal installation directory is located at the '/var/www/drupal9' directory.

Download Drupal 9 Source Code

Step 7 - Drupal Post Installation

Open your web browser and type your Drupal URL installation on the address bar.

And you will be redirected to the secure HTTPS connection.

Now choose the default language for your Drupal installation. The default language is 'English'.

Drupal Setup Language

Choose as your preferred language and click the 'Save and continue' button.

Select your Drupal installation profile and click 'Save and continue'. If you're first time installing Drupal, choose the 'Standard' installation profile.

Drupal Installation type

For the MySQL database configurations, type details database created on top and click 'Save and continue' button.

Setup Database for Drupal

And you will get the Drupal installation process as below.

Drupal Installation Process

Once all installation is complete, configure your site name, admin user, password, email, etc.

Drupal Site Configuration

Click 'Save and continue' button.

Now you will be redirected to the Drupal default index page as below.

drupal homepage

Click the 'Configuration' menu on t op, and you will get the Drupal Admin configuration Dashboard.

Drupal Admin Dashboard

As a result, Drupal 9 installation with the LEMP Stack on Debian Buster 10 has been completed successfully.

Share this page:

1 Comment(s)

Add comment

Please register in our forum first to comment.


By: Eugene_Corn

Thank you! This is a very good and detailed guide. It helps me a lot.