Install Neos CMS on Ubuntu 20.04 LTS
Introduction
Neos CMS is a free and open-source Content Management System (CMS) available under the GPL v3 license or later. Neos CMS has many valuable features that appeal to both content editors and developers, such as inline editing, full Unicode support, complete internationalization, and built-in SEO. It's easy to combine Neos CMS with other modern front-end technologies using JSON or GraphQL export formats.
This tutorial explains how to install Neos CMS on Ubuntu 20.04 LTS and optionally set up HTTPS using a Let's Encrypt TLS certificate.
Prerequisites
- A Ubuntu 20.04 server.
- Follow Vultr's best practices guides to create a sudo user and update the Ubuntu server.
- (Optional) Configure the Ubuntu firewall (keep the port 80, 443, and 22 open).
This tutorial assumes you own a domain name such as example.com, and you have pointed it to the server IP address. If not, replace example.com with the server IP address.
Make sure to replace example.com in the code examples with your domain name or IP address.
1. Install PHP 7.4
Log in to the server as a non-root sudo user via SSH.
Install PHP-FPM and other required PHP extensions.
$ sudo apt install unzip php-fpm php-mbstring php-tokenizer php-xml php-mysql php-imagick php-zip -y
To enhance the security of your server, create a dedicated user named neos
as the user/group of PHP-FPM processes for Neos CMS. This user also owns the Neos CMS source code files.
$ sudo adduser neos
Every time you want to add, delete, or update the source code files, you need to switch to this user.
Create the configuration file from the default one.
$ sudo cp /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/neos.conf
Rename the default file to disable it and keep it as a backup.
$ sudo mv /etc/php/7.4/fpm/pool.d/www.conf /etc/php/7.4/fpm/pool.d/www.conf.default
Open the /etc/php/7.4/fpm/pool.d/neos.conf
file.
$ sudo nano /etc/php/7.4/fpm/pool.d/neos.conf
In the configuration file, any line starting with ;
is a comment.
Search for the following settings, then:
- Replace [www] with [neos]
- Replace user = www-data with user = neos
- Replace group = www-data with group = neos (do not touch the listen.group = www-data setting)
Make sure the listen = /run/php/php7.4-fpm.sock
setting does not start with ;
Copy and paste the following settings to the end of the file.
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/fpm-php/neos/error.log
php_admin_flag[log_errors] = on
Those settings make PHP-FPM log error messages to the /var/log/fpm-php/neos.error.log
file instead of displaying them to website users.
Save the configuration file and exit. Then create the log folder.
$ sudo mkdir -p /var/log/fpm-php/neos
Make the log folder writable by PHP-FPM processes.
$ sudo chown neos:neos /var/log/fpm-php/neos
Check the new configuration.
$ sudo php-fpm7.4 -t
Reload PHP for the changes to take effect.
$ sudo systemctl reload php7.4-fpm.service
2. Install MySQL 8.0
Install MySQL server.
$ sudo apt install mysql-server -y
Run the mysql_secure_installation
script to improve security and set the password for the root user.
$ sudo mysql_secure_installation
To enforce strong passwords, press Y to set up the VALIDATE PASSWORD
component. Then press 1 to select the MEDIUM
password policy, which is
secure enough.
You can use a free password manager like KeePassXC or an online tool such as Random Password Generator to generate strong passwords.
Enter a strong password twice for the MySQL root
user. Then press Y to confirm.
For other questions, press Y to confirm.
When finished, connect to the MySQL command line as the root
user.
$ sudo mysql -u root -p
Create a MySQL database named neos for Neos CMS.
mysql> CREATE DATABASE neos CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Create a MySQL user named neos for Neos CMS. Replace password with a strong password.
mysql> CREATE USER 'neos'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON neos.* TO 'neos'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> exit
3. Install Neos CMS
Install Composer, the PHP dependency manager.
$ cd ~ && curl -sS https://getcomposer.org/installer | php
Make the composer
command globally available.
$ sudo mv composer.phar /usr/local/bin/composer
Create a folder to store the Neos CMS source code.
$ sudo mkdir -p /var/www/neos
Set neos
as the owner of the source code folder.
$ sudo chown neos:neos /var/www/neos
Switch to the neos
user.
$ sudo su neos
Fetch the Neos CMS source code using Composer. Be patient because this process may take a while.
$ cd /var/www/neos && composer create-project --no-dev neos/neos-base-distribution .
If you see the Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]?
message, press Enter.
Generate all required libraries such as jQuery, Bootstrap, CKEditor.
$ ./flow resource:publish
Don't worry if you see some error messages because the command still generates the whole set of required libraries.
Switch back to the sudo user to continue with the setup.
$ exit
4. Install Nginx
Install Nginx web server.
$ sudo apt install nginx -y
Disable the default configuration.
$ sudo rm /etc/nginx/sites-enabled/default
Create a new configuration for Neos CMS.
$ sudo nano /etc/nginx/sites-available/neos-http.conf
Paste the following contents:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
root /var/www/neos/Web;
index index.php;
location ~ /_Resources/ {
access_log off;
log_not_found off;
expires max;
if (!-f $request_filename) {
rewrite "/_Resources/Persistent/([a-z0-9]{40})/.+\.(.+)" /_Resources/Persistent/$1.$2 break;
rewrite "/_Resources/Persistent(?>/[a-z0-9]{5}){8}/([a-f0-9]{40})/.+\.(.+)" /_Resources/Persistent/$1.$2 break;
}
}
location / {
try_files $uri $uri/ /index.php?$args;
}
# Pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_param FLOW_REWRITEURLS 1;
fastcgi_param FLOW_CONTEXT Production;
fastcgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
fastcgi_param X-Forwarded-Port $proxy_port;
fastcgi_param SERVER_NAME $http_host;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_read_timeout 300;
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
}
}
Save the configuration file and exit. Then enable the new configuration.
$ sudo ln -s /etc/nginx/sites-available/neos-http.conf /etc/nginx/sites-enabled/neos-http.conf
Add the www-data
user to the neos
group so that Nginx processes can access the Neos CMS source code folder.
$ sudo usermod -aG neos www-data
Check the new configuration.
$ sudo nginx -t
Reload Nginx for the changes to take effect.
$ sudo systemctl reload nginx.service
5. (Optional) Configure HTTPS
If you own a valid domain name, you can set up HTTPS for your Neos CMS at no cost. Using the Certbot program, you can get a free TLS certificate from Let's Encrypt, a certificate authority.
Install Certbot with Snap
Ubuntu has built-in Snap Store support that makes it easy to get the latest version of Certbot with features like automatic certificate renewal.
$ sudo snap install --classic certbot
Make the certbot
command globally available.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Get a Let's Encrypt Certificate
Run the following command and press Y when prompted.
$ sudo certbot certonly --webroot -w /var/www/neos/Web -d example.com -m admin@example.com --agree-tos
When finished, certbot
tells you the path of your certificate file and key file:
/etc/letsencrypt/live/example.com/fullchain.pem
/etc/letsencrypt/live/example.com/privkey.pem
Another critical file, located in the same folder, also needed for the next step is chain.pem
.
Install the Certificate with Nginx
Generate a file with DH parameters for DHE ciphers.
$ sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
2048 is the size of DH parameters. This process may take a while, so please be patient.
Rename the old configuration file.
$ sudo mv /etc/nginx/sites-available/neos-http.conf /etc/nginx/sites-available/neos-https.conf
Update the new file to support TLS.
$ sudo nano /etc/nginx/sites-available/neos-https.conf
Find the following lines:
listen 80 default_server;
listen [::]:80 default_server;
Replace them with:
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
# DH parameters file
ssl_dhparam /etc/nginx/dhparam.pem;
# intermediate configuration
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
#
# Uncomment the following line only if your website fully supports HTTPS
# and you have no intention of going back to HTTP, otherwise, it will
# break your site.
#
# add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# Use Cloudflare DNS resolver
resolver 1.1.1.1;
Save the configuration file and exit. Then enable the new configuration.
$ sudo ln -s /etc/nginx/sites-available/neos-https.conf /etc/nginx/sites-enabled/neos-https.conf
Create another configuration file for Neos CMS to redirect HTTP requests.
$ sudo nano /etc/nginx/sites-available/neos-http.conf
Paste the following contents:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
root /var/www/neos/Web;
location / {
return 301 https://$server_name$request_uri;
}
location /.well-known/acme-challenge/ {}
}
This configuration makes Nginx redirect all HTTP requests, except those from Let's Encrypt, to corresponding HTTPS requests.
Save the configuration file and exit. Then check the Nginx configuration.
$ sudo nginx -t
Apply the new configuration.
$ sudo systemctl reload nginx.service
Automate Renewal
Let's Encrypt certificates are valid for 90 days, so you must renew your TLS certificate at least once every three months. The Certbot installation automatically created a systemd timer unit to automate this task. Run the following command to verify the timer is active.
$ sudo systemctl list-timers | grep 'certbot\|ACTIVATES'
After renewing the certificate, Certbot will not automatically reload Nginx, so Nginx still uses the old certificate. You must write a script inside the /etc/letsencrypt/renewal-hooks/deploy
folder to reload Nginx.
Open your text editor.
$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Paste the following contents into the editor:
#!/bin/bash
/usr/bin/systemctl reload nginx.service
Save and exit. Then make the script executable.
$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Test the renewal process with a dry run.
$ sudo certbot renew --dry-run
This Vultr article explains all the above steps in more detail. This kind of TLS setup gives you an A on the SSL Labs test.
6. Configure Neos CMS
Restart the server to see if everything is working fine.
$ sudo reboot
Open the http://example.com/setup
link in your browser. Wait a while for Neos CMS to initialize the setup tool. Then you will see the login screen.
To get the setup password, log in to the server as a non-root sudo user via SSH.
Display the password.
$ sudo cat /var/www/neos/Data/SetupPassword.txt
Copy and paste it into the login screen. Then click the Login button to proceed.
Click the Next button in the Neos requirements check screen.
In the Configure database screen:
- Select the MySQL/MariaDB via PDO option for DB Driver.
- Enter neos for DB Username.
- Enter the database password you created in step 2 for DB Password
- Enter 127.0.0.1 for DB Host.
- Select the neos option for DB Name.
Click Next to go to the Create administrator account screen. Then enter your desired credentials and click Next.
In the Create a new site screen:
- Select the Neos.Demo option for Select a site package.
- Leave other options blank.
Wait for a while for Neos CMS to install its demo data. When finished, it greets you with the Setup complete screen.
For security reasons, you must log in to the Neos CMS dashboard using the created administrator account to remove the Try me page because that page allows anyone to create an account to manage the site. The dashboard link is http://example.com/neos
.
After logging in, select the Try me page from the list on the left and then click the Delete button as shown below.
Click the Publish all button to apply the changes.
Your Neos CMS is now ready. You can start posting articles on it.