Guides 11792 Published by

This guide explains how to get WonderCMS running on an Ubuntu 20.04 machine with Nginx, covering everything from system updates to PHP configuration. First you install nginx and the needed PHP 8 packages, add a non‑root user for the CMS, clone the GitHub repository into /var/www, run Composer without dev dependencies, and set up write permissions on the storage folder. You then create an Nginx server block pointing at public/, optionally spin up a MySQL database, edit the .env file, run migrations if needed, tweak final permissions for www‑data, and verify the site is serving correctly. Common pitfalls such as wrong PHP‑FPM socket or missing storage rights are highlighted, along with instructions to secure the deployment with Certbot HTTPS, and the author encourages you to check logs first when things go awry.



How to Install WonderCMS on Ubuntu 20.04 (With Nginx)

WonderCMS is a lightweight, file‑based CMS that runs fine under PHP 8 and Nginx. Below you’ll find a step‑by‑step recipe for getting it up and running on an Ubuntu 20.04 box without any fancy bells or whistles.

Why I’m Writing This

I’ve seen people stumble over the same thing: they install Nginx, forget to point PHP‑FPM at their site, or leave files with the wrong permissions, and then all hell breaks loose. That 500 error that pops up every time you hit a page is a classic case of “permissions not set.” This guide will stop that from happening.

What You’ll Need
  • An Ubuntu 20.04 server (or VM) with root access
  • A domain or public IP ready to point at the server
  • Basic familiarity with SSH, command line, and editing text files

If you’re missing any of these, start by bootstrapping a fresh server.

Step 1 – Update & Install Core Packages
sudo apt update && sudo apt upgrade -y
sudo apt install nginx php8.0-fpm php8.0-mysql php8.0-curl php8.0-zip composer git -y

You need the latest security patches, Nginx for serving HTTP, PHP‑FPM as the backend interpreter, MySQL support if you decide to use a database later, and Composer to pull WonderCMS’s dependencies.

Step 2 – Create a User for WonderCMS
sudo adduser --disabled-login cmsadmin

Running your CMS as root is a no‑no. A dedicated user keeps file ownership tidy and limits damage if the site gets compromised.

Step 3 – Grab WonderCMS
cd /var/www
sudo git clone https://github.com/wondercms/wondercms.git wondercms
sudo chown -R cmsadmin:cmsadmin wondercms

Cloning into /var/www keeps everything where the web server expects it. Setting ownership to cmsadmin lets that user manage files without root.

Step 4 – Run Composer Install
cd wondercms
sudo -u cmsadmin composer install --no-dev

Composer fetches all PHP dependencies. The --no-dev flag skips development packages, slimming the deployment.

Step 5 – Configure Permissions for Storage & Cache
sudo mkdir /var/www/wondercms/storage
sudo chown -R cmsadmin:cmsadmin /var/www/wondercms/storage

WonderCMS writes logs and cached files to storage. Without proper write rights you’ll hit “permission denied” errors whenever the site tries to create a file.

Step 6 – Set Up Nginx Server Block

Create /etc/nginx/sites-available/wondercms with:

server {
    listen 80;
    server_name example.com; # change this

    root /var/www/wondercms/public;
    index index.php;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.0-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
    }

    location ~ /\.ht {
        deny all;
    }
}

Then enable it:

sudo ln -s /etc/nginx/sites-available/wondercms /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

The try_files directive is the bread and butter for single‑page apps. The PHP block tells Nginx where to hand off .php requests. And the deny all line keeps hidden files out of reach.

Step 7 – Create a Database (Optional)

If you want database support:

sudo mysql -u root -p
CREATE DATABASE wondercms;
GRANT ALL PRIVILEGES ON wondercms.* TO 'cmsuser'@'localhost' IDENTIFIED BY 'strongpassword';
FLUSH PRIVILEGES;
EXIT;

WonderCMS can operate without a DB, but if you plan to use plugins that store data, set up the schema first.

Step 8 – Configure .env File
cd /var/www/wondercms
sudo -u cmsadmin cp .env.example .env

Edit .env:

  • Set DB_DATABASE, DB_USERNAME, and DB_PASSWORD if you created a database.
  • Adjust APP_URL to match your domain.

.env is the configuration heart of the app. Leaving defaults can lead to subtle bugs, like connecting to the wrong DB.

Step 9 – Run Migrations (If You’re Using a Database)
sudo -u cmsadmin php artisan migrate --force

Migrations create necessary tables. The --force flag skips the interactive prompt in production.

Step 10 – Final Permissions & Owner Fixes
sudo chown -R www-data:www-data /var/www/wondercms/storage
sudo chmod -R 775 /var/www/wondercms/storage

Nginx runs as www‑data. Giving it write access to the storage area is essential.

Step 11 – Test It Out

Open a browser and go to your domain. You should see WonderCMS’s front page or admin login screen. If you hit a blank page, check /var/log/nginx/error.log for clues—most errors stem from missing permissions or wrong PHP version.

Common Pitfalls (and How I Fixed Them)
  • Wrong PHP‑FPM Socket – If the server block points to /run/php/php7.4-fpm.sock, everything will 404. Double‑check the socket name after installing PHP 8.0.
  • Permissions on storage – Forgetting to set write access for Nginx leads to a “Permission denied” 500 error. The chown/chmod combo above fixes that.
  • Missing .env Variables – Leaving DB_HOST=127.0.0.1 while the DB is on another host will break the connection.
Optional: Use Certbot for HTTPS
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com

HTTPS isn’t optional if you’re handling any user data. Certbot automates the whole process.

And that’s it—WonderCMS running on Nginx under Ubuntu 20.04, all done with a few commands and no unnecessary bloat. If you hit a snag, check the logs first; most of the time it’s just a file permission or socket mismatch.