Joomla is a mature open-source CMS that sits between WordPress and Drupal: flexible content structures, multilingual sites built in, granular access control, and a large extension ecosystem. It’s popular for business sites, portals and community websites. Here’s how to install Joomla 5 on a LEMP stack.

Requirements

  • PHP 8.1+ (8.2/8.3 recommended for Joomla 5), with mysqli or pdo_mysql, json, xml, zip, gd, intl, mbstring and curl.
  • MySQL 8 or MariaDB 10.4+ (PostgreSQL is supported too).
  • Nginx (or Apache) with HTTPS.
sudo apt install nginx mariadb-server php-fpm php-mysql php-xml php-zip php-gd php-intl php-mbstring php-curl unzip

See Nginx with PHP-FPM and install MySQL.

1. Database

CREATE DATABASE joomla CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'joomla'@'localhost' IDENTIFIED BY 'a-strong-password';
GRANT ALL PRIVILEGES ON joomla.* TO 'joomla'@'localhost';
FLUSH PRIVILEGES;

See MySQL users and privileges.

2. Download Joomla

Get the full package for the current version from downloads.joomla.org:

sudo mkdir -p /var/www/joomla && cd /var/www/joomla
sudo wget -O joomla.zip "https://downloads.joomla.org/cms/joomla5/5-2-3/Joomla_5-2-3-Stable-Full_Package.zip?format=zip"
sudo unzip joomla.zip && sudo rm joomla.zip
sudo chown -R www-data:www-data /var/www/joomla

(Replace the version in the URL with the current one.)

3. Nginx configuration

server {
    server_name example.com www.example.com;
    root /var/www/joomla;
    index index.php index.html;
    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    # block access to sensitive files
    location ~* /(administrator/logs|logs|tmp|cache)/ { deny all; }
    location ~* \.(ini|log|sh|sql|bak|dist)$ { deny all; }
    location ~ /\. { deny all; }

    location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|woff2?)$ {
        expires 30d;
        access_log off;
    }
}
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d example.com -d www.example.com

See Nginx try_files and Let’s Encrypt.

4. Web installer

Open https://example.com:

  1. Site name and language.
  2. Admin account (a strong password, and not the username “admin”).
  3. Database: type MySQLi, host localhost, user, password, database name, and a custom table prefix (not jos_).

After installation, Joomla removes the installation/ folder. Make sure it’s gone.

5. Enable SEF URLs

System → Global Configuration → Site → SEO: enable Search Engine Friendly URLs and Use URL Rewriting. With the try_files rule above, URLs like /blog/my-article work without index.php.

Security hardening

  • Update promptly. Joomla core and extension vulnerabilities are actively exploited. Enable update notifications.
  • Two-factor authentication for administrators (built in).
  • Protect /administrator with an IP allow-list, or HTTP basic auth in Nginx:
location /administrator {
    allow 203.0.113.50;
    deny all;
    try_files $uri $uri/ /index.php?$args;
}
  • File permissions: code not writable by PHP where possible, and configuration.php set to 444 after setup.
  • Install only well-maintained extensions from the Joomla Extensions Directory.
  • Add Fail2Ban or WAF rules for login brute force. See Fail2Ban for Nginx and WAF explained.

Performance

  • Enable OPcache, and Joomla’s caching (Global Configuration → System → Cache: Conservative caching, plus the Page Cache plugin for public pages).
  • Use Redis or Memcached as the cache handler on busy sites. See install Redis.
  • Optimise images, and enable Gzip or Brotli. See website speed optimization.

Backups and updates

  • Akeeba Backup (an extension) is the standard Joomla backup tool, or back up manually:
mysqldump --single-transaction joomla | gzip > /backups/joomla-db-$(date +%F).sql.gz
tar -czf /backups/joomla-files-$(date +%F).tar.gz -C /var/www joomla

See backup strategy.

  • Update via System → Update → Joomla, after a backup, and test extensions on staging for major versions (e.g. 4 → 5). See updating self-hosted apps.

Quick reference

Task Where
Admin panel /administrator
SEF URLs Global Configuration → SEO
Main config configuration.php
Update System → Update → Joomla
Cache Global Configuration → System

Related: Drupal and WordPress on a VPS.

  • CMS
  • PHP
  • Nginx