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.
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 aslocalhost - 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.