Read in 8 minutes

last updated 

How to install Drupal on Ubuntu 18.04

Drupal is one of the the most popular open source CMS platforms worldwide. In this tutorial we will show you how to install Drupal 8.5 on an Ubuntu 18.04 machine. There are multiple ways to install Drupal, this tutorial covers the steps necessary for installing Drupal 8.5 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.


Make sure that you have met the following prerequisites before continuing with this tutorial:

  • You have a domain name pointing to your public server IP. In this tutorial we will use
  • You have Nginx installed by following this instructions.
  • You have a SSL certificate installed for your domain. You can install a free Let’s Encrypt SSL certificate by following this instructions .

Before you begin

Update the the package index and system packages to the latest versions:

sudo apt update && sudo apt upgrade

1. Create a MySQL database

If you have MySQL or MariaDB installed on your server you can skip this step if not you can install the MySQL 5.7 server package from the Ubuntu’s default repositories by typing:

sudo apt install mysql-server

For fresh MySQL installations, it is recommended to run the mysql_secure_installation command to improve the security of your MySQL server.

Now we need to login to the MySQL shell and to create a new database and user account and to give the user the appropriate grant permissions. To login to the MySQL shell type 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 all 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';

2. Install PHP

PHP 7.2 which is the default PHP version in Ubuntu 18.04 is fully supported and recommended for Drupal 8.5. Since we will be using Nginx as a web server we’ll install PHP-FPM too. To install all required PHP modules run the following command:

sudo apt install php7.2-cli php7.2-fpm php7.2-mysql php7.2-json php7.2-opcache php7.2-mbstring php7.2-xml php7.2-gd php7.2-curl

PHP-FPM service will automatically start after the installation process is complete, we can verify it by printing the service status:

systemctl status php7.2-fpm

You should see something similar to this:

● php7.2-fpm.service - The PHP 7.2 FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php7.2-fpm.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2018-05-19 19:54:13 UTC; 9h ago
     Docs: man:php-fpm7.2(8)
 Main PID: 17781 (php-fpm7.2)
   Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
    Tasks: 3 (limit: 507)
   CGroup: /system.slice/php7.2-fpm.service
           ├─17781 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf)
           ├─17796 php-fpm: pool www
           └─17797 php-fpm: pool www

3. Install Composer

Composer is a dependency manager for PHP and we will be using it to download the Drupal template and install all necessary Drupal components. To install composer globally type:

curl -sS | sudo php -- --install-dir=/usr/local/bin --filename=composer

We can verify the installation by printing the composer version:

composer --version

The output should look something like:

Composer version 1.6.5 2018-05-04 11:44:59

4. Install Drupal

Now that we have composer installed, we can proceed and create a new Drupal project using the composer template inside /var/www/my_drupal directory:

sudo 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 some scripts to prepare our project for installation. The process may take few minutes and if it is successful the end of the output should look like the following:

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

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

cd /var/www/my_drupal
sudo vendor/bin/drush site-install --db-url=mysql://drupaluser:[email protected]/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. Consider using the --notify global option.
 [success] Installation complete.  User name: admin  User password: XRkC9Q5WN9

Finally we need to set the correct permissions so that the web server can have full access to the site’s files and directories. Both Nginx and PHP are running as www-data user and www-data group, so we need to run the following command:

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

5. Configure Nginx

By now, you should already have a 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:

# Redirect HTTP -> HTTPS
server {
    listen 80;

    include snippets/letsencrypt.conf;
    return 301$request_uri;

# Redirect WWW -> NON WWW
server {
    listen 443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;
    ssl_trusted_certificate /etc/letsencrypt/live/;
    include snippets/ssl.conf;

    return 301$request_uri;

server {
    listen 443 ssl http2;

    root /var/www/my_drupal/web;

    # SSL parameters
    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;
    ssl_trusted_certificate /etc/letsencrypt/live/;
    include snippets/ssl.conf;

    # log files
    access_log /var/log/nginx/;
    error_log /var/log/nginx/;

    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
        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/php7.2-fpm.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 with your Drupal domain and set the correct path to the SSL certificate files. The snippets used in this configuration are created in this guide .

Enable the server block by creating a symbolic link from to the sites-enabled directory:

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

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

sudo nginx -t

If there are no errors the output should look like this:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

and we can restart Nginx by typing:

sudo systemctl restart nginx

6. Test the Installation

You can open your browser, type your domain and assuming that installation is successful, a screen similar to the following will appear:

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

7. 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 www-data composer require drupal/pathauto

By prepending sudo -u www-data we are running the command as user www-data

Using version ^1.2 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.1.0): Downloading (100%)
  - Installing drupal/ctools (3.0.0): Downloading (100%)
  - Installing drupal/pathauto (1.2.0): Downloading (100%)
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.

8. 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 backup the installation files you can use the following 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 backup the database we can either use the standard mysqldump:

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 www-data composer update drupal/core webflo/drupal-core-require-dev symfony/* --with-dependencies


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.