Host a PHP-based content management system
Most PHP content management systems (CMS) follow the same pattern: a PHP stack, a MariaDB database, a folder of files and a web-based installer. This guide prepares all three so the installer can run smoothly. Check your CMS's own requirements page first, because version numbers and extensions vary between products.
Before you begin
- A working LEMP or LAMP stack with PHP 8.3 (see Install a LEMP stack or Install a LAMP stack). This guide uses nginx paths, with notes for Apache.
- A hardened MariaDB installation (see Secure your MariaDB installation).
- The CMS release archive (a
.zipor.tar.gzfile) downloaded from the project's official website, on your computer. - A domain pointed at the VPS, and SSH access as a sudo user (this guide uses
alex).
Step 1: Install the PHP extensions the CMS needs
Content management systems use image processing, internationalization, and archive handling. Install the common set, then confirm the one most often required is loaded:
sudo apt install -y php8.3-fpm php8.3-mysql php8.3-gd php8.3-intl php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip unzip
php -m | grep -i intl
intl
If you use Apache, replace php8.3-fpm with libapache2-mod-php8.3. The other packages stay the same.
Step 2: Raise PHP's upload and memory limits
Default PHP limits are small. A CMS installer or media library often needs bigger uploads and more memory. Open the web-server version of php.ini:
sudo nano /etc/php/8.3/fpm/php.ini
Find these lines (use the search key Ctrl+W in nano) and set the values as shown:
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 120
Restart PHP-FPM so the change takes effect, then check the values:
sudo systemctl restart php8.3-fpm
sudo grep -E "^(upload_max_filesize|post_max_size|memory_limit|max_execution_time)" /etc/php/8.3/fpm/php.ini
On Apache, edit /etc/php/8.3/apache2/php.ini and restart apache2 instead.
Step 3: Create the database and user
Create a database and account for the CMS, following the pattern in Create a database and a dedicated user. Generate a strong password first with openssl rand -base64 24.
sudo mariadb
CREATE DATABASE cms_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'cms_user'@'localhost' IDENTIFIED BY 'PASTE_YOUR_PASSWORD_HERE';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP ON cms_db.* TO 'cms_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Step 4: Upload and extract the CMS files
From your computer, copy the archive to your home folder on the server:
scp cms-release.zip alex@203.0.113.10:~/
On the server, create the site folder, extract the archive into it, and set ownership so you can manage files while the web server can write where it must:
sudo mkdir -p /var/www/example.com
sudo unzip -q ~/cms-release.zip -d /var/www/example.com
sudo chown -R alex:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 750 {} \;
sudo find /var/www/example.com -type f -exec chmod 640 {} \;
Most CMS releases need a few folders the web server can write to, such as uploads or a cache. Check the CMS documentation for the exact list, then grant write access to those folders only:
sudo chown -R www-data:www-data /var/www/example.com/public/uploads
ls /var/www/example.com shows one folder with the CMS inside, move the contents up one level or point nginx at that folder.Step 5: Configure the web server
Point nginx at the CMS's public folder, and allow larger uploads. nginx limits request bodies to 1 MB by default, so client_max_body_size must match the PHP limit:
sudo nano /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html;
client_max_body_size 64M;
location / {
try_files $uri $uri/ /index.php?$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.(?!well-known) {
deny all;
}
}
Replace public in the root line with the CMS's actual web folder if its documentation says otherwise. Enable the site and reload nginx:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
Step 6: Run the installer
Open http://example.com in your browser and follow the installer. When it asks for database details, enter cms_db as the name, cms_user as the user, the password you generated, and localhost as the host.
When the installer finishes, it usually asks you to delete its installation folder. Do so, because a leftover installer can be used to reset your site. Then create your admin account with a long, unique password.
Troubleshooting
- The installer reports a missing PHP extension. Install the package it names (for example
php8.3-intl), then runsudo systemctl restart php8.3-fpm. - Large uploads fail with "413 Request Entity Too Large". Check both
client_max_body_sizein nginx andupload_max_filesizein PHP, then reload or restart the matching service. - "Permission denied" when saving settings or media. The folder the CMS writes to is not owned by
www-data. Fix it withchownas shown in Step 4. - A blank white page. Read
sudo tail -n 50 /var/log/nginx/error.logand the PHP-FPM log for the real error.
Next steps
Enable HTTPS, keep the CMS and its plugins updated, and back up both the files and the database regularly. Afterglow snapshots are a convenient way to capture a whole server before major changes.
Something not working? Chat or email our support team and we will help you get unstuck.
Contact support