Web Hosting

Install Drupal on Ubuntu 24.04 with Nginx

Drupal is a powerful open-source content management system (CMS) built in PHP. It is used by governments, universities, and enterprises to build complex, content-heavy websites with fine-grained access control, multilingual support, and extensive customization through modules and themes.

Original content from computingforgeeks.com - post 61195

This guide walks through installing Drupal 11 on Ubuntu 24.04 LTS with Nginx as the web server, MariaDB as the database backend, and PHP 8.3. By the end, you will have a fully functional Drupal site ready for production use with SSL and cron configured.

Prerequisites

Before starting, make sure you have the following in place:

  • A server running Ubuntu 24.04 LTS with at least 2GB RAM and 2 CPU cores
  • Root or sudo access to the server
  • A registered domain name pointing to your server’s public IP address
  • Ports 80 (HTTP) and 443 (HTTPS) open in your firewall

Step 1: Install Nginx Web Server

Nginx is a high-performance web server that handles PHP requests through FastCGI. It is lighter on resources than Apache and well-suited for Drupal deployments. Start by updating the package index and installing Nginx.

sudo apt update
sudo apt install -y nginx

After installation, enable Nginx to start on boot and verify it is running:

sudo systemctl enable --now nginx
sudo systemctl status nginx

The output should show the service as active (running):

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Sat 2026-03-22 10:15:32 UTC; 5s ago

Step 2: Install PHP and Required Extensions

Drupal 11 requires PHP 8.3 or newer. Ubuntu 24.04 ships PHP 8.3 in its default repositories, which meets this requirement. Install PHP-FPM along with all the extensions Drupal needs:

sudo apt install -y php8.3-fpm php8.3-cli php8.3-common php8.3-mysql \
  php8.3-xml php8.3-gd php8.3-mbstring php8.3-curl php8.3-zip \
  php8.3-opcache php8.3-intl php8.3-bcmath php8.3-soap php8.3-readline

Confirm the installed PHP version:

php -v

You should see PHP 8.3.x confirmed:

PHP 8.3.6 (cli) (built: Apr 15 2024 19:21:47) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.6, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.6, Copyright (c), by Zend Technologies

For optimal Drupal performance, adjust a few PHP settings. Open the PHP-FPM configuration file:

sudo vi /etc/php/8.3/fpm/php.ini

Update these values to match Drupal’s recommendations:

memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
date.timezone = UTC

Restart PHP-FPM to apply the changes:

sudo systemctl restart php8.3-fpm

Step 3: Install MariaDB Database Server

Drupal 11 supports MariaDB 10.6 and newer. Ubuntu 24.04 includes MariaDB 10.11 in its repositories, which works well. If you need a detailed walkthrough on installing MariaDB on Ubuntu, we have a dedicated guide. For this setup, install it directly:

sudo apt install -y mariadb-server mariadb-client

Enable and start the MariaDB service:

sudo systemctl enable --now mariadb
sudo systemctl status mariadb

The service should show active (running). Next, run the security hardening script to set a root password and remove test databases:

sudo mariadb-secure-installation

Answer the prompts as follows:

  • Enter current password for root – press Enter (blank by default)
  • Switch to unix_socket authentication – n
  • Change the root password – Y, then set a strong password
  • Remove anonymous users – Y
  • Disallow root login remotely – Y
  • Remove test database – Y
  • Reload privilege tables – Y

Step 4: Create Drupal Database and User

Drupal stores all content, configuration, and user data in a database. Create a dedicated database and user for Drupal with the proper permissions. Log into the MariaDB shell:

sudo mariadb -u root -p

Run the following SQL commands to create the database, user, and grant privileges. Replace StrongPassword123! with your own secure password:

CREATE DATABASE drupal CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'drupaluser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON drupal.* TO 'drupaluser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

The utf8mb4 character set is required by Drupal for full Unicode support including emojis.

Step 5: Download Drupal with Composer

Drupal 11 requires Composer 2.7.0 or higher for dependency management. Install Composer globally first:

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Verify Composer is installed correctly:

composer --version

The output should show Composer version 2.7.0 or newer:

Composer version 2.8.6 2025-02-25 13:03:50

Now create the Drupal project using the recommended Composer template. This downloads Drupal core and all dependencies into /var/www/drupal:

cd /var/www
sudo composer create-project drupal/recommended-project drupal

Set the correct file ownership so the web server can read and write files as needed:

sudo chown -R www-data:www-data /var/www/drupal
sudo find /var/www/drupal -type d -exec chmod 755 {} \;
sudo find /var/www/drupal -type f -exec chmod 644 {} \;

Drupal’s web root is located at /var/www/drupal/web – this is the directory Nginx needs to serve.

Step 6: Configure Nginx for Drupal

Create an Nginx server block configuration for your Drupal site. Replace example.com with your actual domain name throughout. If you are new to Nginx virtual host configuration, our guide on setting up Nginx on Ubuntu covers the fundamentals. Open a new configuration file:

sudo vi /etc/nginx/sites-available/drupal

Add the following Nginx configuration. This handles clean URLs, PHP processing, and security headers that Drupal expects:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    root /var/www/drupal/web;
    index index.php index.html;

    # Drupal clean URLs
    location / {
        try_files $uri /index.php?$query_string;
    }

    # Block access to hidden files and directories
    location ~ (^|/)\. {
        return 403;
    }

    # PHP-FPM processing
    location ~ \.php$|^/update.php {
        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        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_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_read_timeout 300;
    }

    # Block access to Drupal private files
    location ~ ^/sites/.*/private/ {
        return 403;
    }

    # Block access to vendor directory
    location ~ /vendor/.*\.php$ {
        deny all;
        return 404;
    }

    # Handle Drupal image styles
    location ~ ^/sites/.*/files/styles/ {
        try_files $uri /index.php?$query_string;
    }

    # Serve static files directly
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        try_files $uri @rewrite;
        expires max;
        log_not_found off;
    }

    location @rewrite {
        rewrite ^ /index.php;
    }

    # Deny access to .htaccess files
    location ~ /\.ht {
        deny all;
    }
}

Enable the site and test the Nginx configuration for syntax errors:

sudo ln -s /etc/nginx/sites-available/drupal /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t

If the test passes, you should see this confirmation:

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

Reload Nginx to apply the new configuration:

sudo systemctl reload nginx

Step 7: Complete Drupal Installation via Web Installer

Before launching the web installer, create the Drupal settings file and files directory with the correct permissions:

sudo cp /var/www/drupal/web/sites/default/default.settings.php /var/www/drupal/web/sites/default/settings.php
sudo mkdir -p /var/www/drupal/web/sites/default/files
sudo chown -R www-data:www-data /var/www/drupal/web/sites/default/settings.php
sudo chown -R www-data:www-data /var/www/drupal/web/sites/default/files
sudo chmod 666 /var/www/drupal/web/sites/default/settings.php

Open your browser and navigate to your domain or server IP address:

http://example.com

The Drupal installation wizard guides you through the setup in a few steps:

  • Choose language – Select your preferred language and click Save and continue
  • Choose profile – Select Standard for a full-featured installation with commonly used modules enabled
  • Database configuration – Select MySQL/MariaDB, then enter: Database name: drupal, Username: drupaluser, Password: your password. Under Advanced, leave Host as localhost
  • Install – Drupal installs the core modules and themes automatically
  • Configure site – Enter your site name, admin username, password, and email address

After the installation completes, tighten the permissions on the settings file to prevent unauthorized changes:

sudo chmod 444 /var/www/drupal/web/sites/default/settings.php

Step 8: Configure Drupal Cron

Drupal uses cron jobs to perform routine maintenance tasks like checking for module updates, indexing content for search, and cleaning up log files. Set up a system cron job to run Drupal’s cron every 3 hours:

sudo crontab -u www-data -e

Add the following line at the end of the file. Replace example.com with your domain:

0 */3 * * * cd /var/www/drupal && vendor/bin/drush cron > /dev/null 2>&1

Alternatively, you can trigger cron via HTTP using Drupal’s built-in cron URL. Find it at Administration > Configuration > System > Cron in your Drupal admin panel.

Step 9: Configure Firewall and SSL with Let’s Encrypt

If UFW firewall is active on your server, allow HTTP and HTTPS traffic. These ports (80/TCP and 443/TCP) are required for web access and SSL certificate validation:

sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

The status output should confirm both Nginx and SSH ports are allowed:

Status: active

To                         Action      From
--                         ------      ----
Nginx Full                 ALLOW       Anywhere
OpenSSH                    ALLOW       Anywhere
Nginx Full (v6)            ALLOW       Anywhere (v6)
OpenSSH (v6)               ALLOW       Anywhere (v6)

For production sites, SSL is essential. Install Certbot to obtain a free Let’s Encrypt certificate. Our guide on generating Let’s Encrypt SSL certificates covers this in more detail:

sudo apt install -y certbot python3-certbot-nginx

Request and install the certificate for your domain. Certbot automatically configures Nginx to use SSL and sets up HTTP-to-HTTPS redirection:

sudo certbot --nginx -d example.com -d www.example.com

Follow the Certbot prompts to enter your email and agree to the terms of service. After completion, verify the certificate renewal process works correctly:

sudo certbot renew --dry-run

If the dry run succeeds, automatic certificate renewals are configured and will run via a systemd timer. After enabling SSL, update Drupal’s trusted host patterns. Open the settings file:

sudo vi /var/www/drupal/web/sites/default/settings.php

Add the following at the end of the file, replacing example\.com with your escaped domain name:

$settings['trusted_host_patterns'] = [
  '^example\.com$',
  '^www\.example\.com$',
];

This protects against HTTP Host header attacks by restricting which hostnames Drupal responds to.

Conclusion

You now have Drupal 11 running on Ubuntu 24.04 with Nginx, PHP 8.3, and MariaDB. The site is secured with a Let’s Encrypt SSL certificate, and automated cron handles routine maintenance tasks. For a production deployment, consider setting up regular database backups, enabling Redis or Memcached for caching, and configuring a CDN for static asset delivery. Check the Drupal system requirements page periodically to stay current with supported PHP and database versions.

Related Articles

Containers Configure LDAP, SSSD and Kerberos Authentication on Ubuntu Virtualization How to use existing virtual machines with Vagrant Ubuntu Install Chromium Browser on Ubuntu 22.04/20.04 Terminal Install Tilix GTK3 terminal emulator on Ubuntu / Debian

Leave a Comment

Press ESC to close