How to Install Drupal on CentOS 7

Posted 

8 min read

Drupal is one of the leading open source CMS platforms worldwide. It is flexible, scalable and can be used to build different types of websites ranging from small personal blogs to large corporate, political, and government sites.

In this tutorial, we’ll explain how to install Drupal 8.6 on CentOS 7.

There are multiple ways to install Drupal. This guide covers the steps necessary for installing Drupal using a composer template for Drupal projects called drupal-project.

We’ll be using Nginx as a web server, the latest PHP 7.2 and MySQL/MariaDB as a database server.

Prerequisites

Before you start the installation, ensure you have met the following prerequisites:

Create a MySQL database

The first step is to create a new database and user account and to grant appropriate permissions to the user.

If MySQL or MariaDB is already installed on your server you can skip this step, if not you can install the MariaDB 5.5 server package from the CentOS’s default repositories by typing:

sudo yum install mariadb-server
For fresh MariaDB/MySQL installations, it is recommended to run the mysql_secure_installation command to improve the security of your database server.

Login to the MySQL shell by typing the following command and enter the password when prompted:

mysql -u root -p

To create a database named drupal, user named drupaluser and to grant the necessary permissions to the user run the following commands:

CREATE DATABASE drupal CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON drupal.* TO 'drupaluser'@'localhost' IDENTIFIED BY 'change-with-strong-password';

Install PHP

CentOS 7 ships with PHP version 5.4, which is outdated and no longer supported. The recommended PHP version for Drupal is PHP 7.2.

To install PHP 7.2 on CentOS 7 first we need to enable the EPEL and Remi repositories:

sudo yum install epel-release yum-utils
sudo yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
sudo yum-config-manager --enable remi-php72

Once the repositories are enabled to install PHP 7.2 and all required PHP extensions run the following commands:

sudo yum install php-cli php-fpm php-mysql php-json php-opcache php-mbstring php-xml php-gd php-curl git

We installed PHP FPM because we will be using Nginx as a web server.

By default PHP FPM will run as user apache on port 9000. We’ll change the user to nginx and switch from TCP socket to Unix socket. To do so open the /etc/php-fpm.d/www.conf file and edit the lines highlighted in yellow:

/etc/php-fpm.d/www.conf
...
user = nginx
...
group = nginx
...
listen = /run/php-fpm/www.sock
...
listen.owner = nginx
listen.group = nginx

Make sure the /var/lib/php directory has the correct ownership using the following chown command:

sudo chown -R root:nginx /var/lib/php

Finally, enable and start the PHP FPM service:

sudo systemctl enable php-fpm
sudo systemctl start php-fpm

Install Composer

Composer is a dependency manager for PHP. We will download the Drupal template and install all necessary Drupal components with composer.

The following command will install composer globally by downloading the Composer installer with curl and moving the file to the /usr/local/bin directory:

curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer

Verify the installation by running the following command which will print the composer version:

composer --version

The output should look something like this:

Composer version 1.8.4 2019-02-11 10:52:10

Install Drupal

Now that composer has been installed, create a new Drupal project using the Drupal template inside /var/www/my_drupal directory:

sudo /usr/local/bin/composer create-project drupal-composer/drupal-project:8.x-dev /var/www/my_drupal --stability dev --no-interaction

The command above will download the template, fetch all required php packages and run the scripts necessary to prepare the project for installation. The process may take a few minutes and if it is successful the end of the output will look like this:

Create a sites/default/settings.php file with chmod 0666
Create a sites/default/files directory with chmod 0777

Next step is to install Drupal using Drush. In the command below we are passing the MySQL database and user information we created in the first section:

cd /var/www/my_drupal
sudo vendor/bin/drush site-install --db-url=mysql://drupaluser:change-with-strong-password@localhost/drupal

The installer will prompt you with the following message, just press enter to continue.

You are about to DROP all tables in your 'drupal' database. Do you want to continue? (yes/no) [yes]:

Once the installation is completed the script will print the administrative username and password. The output should look something like the following:

[notice] Starting Drupal installation. This takes a while.
[success] Installation complete.  User name: admin  User password: frxka2Db5v

Finally, set the correct permissions so that the web server can have full access to the site’s files and directories:

sudo chown -R nginx: /var/www/my_drupal

Configure Nginx

By now, you should already have Nginx with SSL certificate installed on your system, if not check the prerequisites for this tutorial.

To create a new server block for our new Drupal project we will use the Nginx recipe from the official Nginx site.

Open your text editor and create the following file:

sudo nano /etc/nginx/conf.d/example.com
/etc/nginx/conf.d/example.com
# Redirect HTTP -> HTTPS
server {
    listen 80;
    server_name www.example.com example.com;

    include snippets/letsencrypt.conf;
    return 301 https://example.com$request_uri;
}

# Redirect WWW -> NON WWW
server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;

    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    root /var/www/my_drupal/web;

    # SSL parameters
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;

    # log files
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    location ~ \..*/.*\.php$ {
        return 403;
    }

    location ~ ^/sites/.*/private/ {
        return 403;
    }

    # Block access to scripts in site files directory
    location ~ ^/sites/[^/]+/files/.*\.php$ {
        deny all;
    }

    # 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 /index.php?$query_string;
    }

    location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;
    }

    # Don't allow direct access to PHP files in the vendor directory.
    location ~ /vendor/.*\.php$ {
        deny all;
        return 404;
    }


    location ~ '\.php$|^/update.php' {
        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
        include fastcgi_params;
        # Block httpoxy attacks. See https://httpoxy.org/.
        fastcgi_param HTTP_PROXY "";
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_intercept_errors on;
        fastcgi_pass unix:/run/php-fpm/www.sock;
    }

    # Fighting with Styles? This little gem is amazing.
    # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
    location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
        try_files $uri @rewrite;
    }

    # Handle private files through Drupal. Private file's path can come
    # with a language prefix.
    location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
        try_files $uri /index.php?$query_string;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        try_files $uri @rewrite;
        expires max;
        log_not_found off;
    }

}
Don’t forget to replace example.com with your Drupal domain and set the correct path to the SSL certificate files. All the HTTP requests will be redirected to HTTPS. The snippets used in this configuration are created in this guide.

Before restarting the Nginx service make a test to be sure that there are no syntax errors:

sudo nginx -t

Restart the Nginx service for changes to take effect by typing:

sudo systemctl restart nginx

Test the Installation

Open your browser, type your domain and assuming the installation is successful, a screen similar to the following will appear:

You can log in as an admin and start customizing your new Drupal installation.

Install Drupal Modules and Themes

Now that you have your Drupal project installed, you’ll want to install some modules and themes. Drupal modules and themes are hosted on a custom composer repository, which drupal-project configures for us out of the box.

To install a module or a theme, all you need to do is to cd to the project directory and type composer require drupal/module_or_theme_name. For example, if we want to install the Pathauto module, we need to run the following command:

cd /var/www/my_drupal
sudo -u nginx /usr/local/bin/composer require drupal/pathauto
By prepending sudo -u nginx we are running the command as user nginx
Using version ^1.3 for drupal/pathauto
./composer.json has been updated
> DrupalProject\composer\ScriptHandler::checkComposerVersion
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 3 installs, 0 updates, 0 removals
  - Installing drupal/token (1.5.0): Downloading (100%) 
  - Installing drupal/ctools (3.2.0): Downloading (100%)
  - Installing drupal/pathauto (1.3.0): Downloading (100%)
Package phpunit/phpunit-mock-objects is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating autoload files
> DrupalProject\composer\ScriptHandler::createRequiredFiles

As you can see from the output above composer also installs all of the package dependencies for us.

Update Drupal Core

Before upgrading it is always a good idea to take a backup of your files and database. You can either use the Backup and Migrate module or manually backup your database and files.

To back up the installation files you can use the following rsync command, of course, you’ll need to use the correct path to the installation directory:

sudo rsync -a /var/www/my_drupal/  /var/www/my_drupal_$(date +%F)

To back up the database we can either use the standard mysqldump command:

mysqldump -u root -p > /var/www/my_drupal_database_$(date +%F).sql

or drush sql-dump:

cd /var/www/my_drupal
vendor/bin/drush sql-dump > /var/www/my_drupal_database_$(date +%F).sql

Now that we created a backup we can continue and update all Drupal core files by running the following command:

sudo -u nginx /usr/local/bin/composer update drupal/core webflo/drupal-core-require-dev symfony/* --with-dependencies

Conclusion

Congratulations, you have successfully installed Drupal 8 using composer and learned how to install modules and themes. You can now start customizing your site. The Drupal 8 User Guide is a good starting place to learn more about how to manage your Drupal installation. Also, do not forget to visit the Drupal Composer template project on Github.

If you have questions feel free to leave a comment below.