Neos is a free and open-source content management system (CMS) that allows you to build complex websites easily without needing to code. You can create a blog, news website, portfolio page, or a company website using it. It offers a rich set of features such as inline editing, supports multiple websites on a single installation, built-in SEO tools, human-readable URLs, plugin manager, device preview, and supports multiple templates. It supports modern-day technologies such as REST API, JSON, GraphQL, and oEmbed.
In this tutorial, you will learn how to install Neos CMS on a server running Rocky Linux 8 OS.
Prerequisites
-
A server running Rocky Linux 8.
-
A non-root sudo user.
-
Make sure everything is updated.
$ sudo dnf update
-
Install basic utility packages. Some of them may already be installed.
$ sudo dnf install wget curl nano unzip yum-utils -y
Step 1 - Configure Firewall
The first step is to configure the firewall. Rocky Linux uses Firewalld Firewall. Check the firewall's status.
$ sudo firewall-cmd --state running
The firewall works with different zones, and the public zone is the default one that we will use. List all the services and ports active on the firewall.
$ sudo firewall-cmd --permanent --list-services
It should show the following output.
cockpit dhcpv6-client ssh
Allow HTTP and HTTPS ports.
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
Recheck the status of the firewall.
$ sudo firewall-cmd --permanent --list-services
You should see a similar output.
cockpit dhcpv6-client http https ssh
Reload the firewall to enable the changes.
$ sudo firewall-cmd --reload
Step 2 - Install Nginx
Rocky Linux ships with an older version of Nginx. You need to download the official Nginx repository to install the latest version.
Create and open the /etc/yum.repos.d/nginx.repo
file for creating the official Nginx repository.
$ sudo nano /etc/yum.repos.d/nginx.repo
Paste the following code in it.
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
Save the file by pressing Ctrl + X and entering Y when prompted.
Install Nginx.
$ sudo dnf install nginx
Verify the installation.
$ nginx -v nginx version: nginx/1.20.2
Enable and start the Nginx service.
$ sudo systemctl enable nginx --now
Step 3 - Install PHP and extensions
For our tutorial, we need to install the latest version of PHP using Remi's repository. The first step is to grab the Epel repository.
$ sudo dnf install epel-release
Next, install the Remi repository.
$ sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
Check for available PHP streams.
$ dnf module list php -y Last metadata expiration check: 0:00:12 ago on Fri 03 Dec 2021 09:39:32 AM UTC. Rocky Linux 8 - AppStream Name Stream Profiles Summary php 7.2 [d] common [d], devel, minimal PHP scripting language php 7.3 common [d], devel, minimal PHP scripting language php 7.4 common [d], devel, minimal PHP scripting language Remi's Modular repository for Enterprise Linux 8 - x86_64 Name Stream Profiles Summary php remi-7.2 common [d], devel, minimal PHP scripting language php remi-7.3 common [d], devel, minimal PHP scripting language php remi-7.4 common [d], devel, minimal PHP scripting language php remi-8.0 common [d], devel, minimal PHP scripting language php remi-8.1 common [d], devel, minimal PHP scripting language Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
The default version is 7.2. Enable Remi's PHP 8.0 repository.
$ sudo dnf module reset php $ sudo dnf module enable php:remi-8.0
Next, install PHP and its extensions required by Neos along with ImageMagick.
$ sudo dnf install php-fpm php-mbstring php-xml php-curl php-mysqlnd php-zip php-cli php-imagick ImageMagick php-intl
Verify the installation.
$ php --version PHP 8.0.14 (cli) (built: Dec 16 2021 03:01:07) ( NTS gcc x86_64 ) Copyright (c) The PHP Group Zend Engine v4.0.14, Copyright (c) Zend Technologies
Step 4 - Install and Configure MySQL Server
We will use MySQL database to store the data. Rocky Linux's Appstream repository ships with the latest version of MySQL.
Install MySQL.
$ sudo dnf install mysql-server
Enable and start the MySQL service.
$ sudo systemctl enable mysqld --now
Secure MySQL installation.
$ sudo mysql_secure_installation
For the first step, you will be asked if you want to set up the Validate Password Plugin, which you can use to test the strength of your MySQL password. Choose Y
to proceed. You will be asked to choose the password validation level in the next step. Choose 2
which is the strongest level and will require your password to be at least eight characters long and include a mix of uppercase, lowercase, numeric and special characters.
Securing the MySQL server deployment. Connecting to MySQL using a blank password. VALIDATE PASSWORD COMPONENT can be used to test passwords and improve security. It checks the strength of password and allows the users to set only those passwords which are secure enough. Would you like to setup VALIDATE PASSWORD component? Press y|Y for Yes, any other key for No: Y There are three levels of password validation policy: LOW Length >= 8 MEDIUM Length >= 8, numeric, mixed case, and special characters STRONG Length >= 8, numeric, mixed case, special characters and dictionary file Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2
You will be asked to choose a root password in the next step. Choose a strong password that fulfills the requirements of the password validation plugin. In the next step, you will be asked whether to continue with the chosen password. Press y
to continue.
Please set the password for root here. New password: Re-enter new password: Estimated strength of the password: 100 Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y
Press Y
and then ENTER
key for all the following prompts to remove anonymous users and the test database, disable root logins and load the newly set rules.
... Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y Success. ... Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y Success. ... Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y - Dropping test database... Success. - Removing privileges on test database... Success. Reloading the privilege tables will ensure that all changes made so far will take effect immediately. ... Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y Success. All done!
Enter the MySQL shell. Enter your root password to continue.
$ mysql -u root -p
Create neos
user. Make sure the password meets the requirements set before.
mysql> CREATE USER 'neos'@'localhost' IDENTIFIED BY 'Your_password2';
Create neosdb
database.
mysql> CREATE DATABASE neosdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Grant the user privileges on the neosdb
database.
mysql> GRANT ALL PRIVILEGES ON neosdb.* TO 'neos'@'localhost';
Exit the Shell.
mysql> exit
Step 5 - Install Composer
Composer is a dependency management tool for PHP and is required by Neos CMS to work.
Download the Composer installer script.
$ curl -sS https://getcomposer.org/installer -o composer-setup.php
Run the following commands to verify the installer.
$ HASH=`curl -sS https://composer.github.io/installer.sig` $ echo $HASH $ php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
The above commands grab the hash value of the installer and match it with your downloaded script. You should see the following output if the installer is safe to run.
Installer verified
Install Composer.
$ sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
Verify the installation by checking its version.
$ composer --version Composer version 2.2.3 2021-12-31 12:18:53
Step 6 - Install Neos CMS
Create a root directory for installing Neos.
$ sudo mkdir -p /var/www/neos
Change the ownership of the root directory to the currently logged-in user.
$ sudo chown -R $USER:$USER /var/www/neos
Switch to the root directory.
$ cd /var/www/neos
Use Composer to install Neos and its dependencies.
$ composer create-project --no-dev neos/neos-base-distribution .
Don't forget the dot at the end of the command that tells Composer to install it in the current directory. You may get the following warnings while installation. Enter y
to proceed. The installation won't be hampered because of it.
- Installing neos/composer-plugin (2.1.3): Extracting archive neos/composer-plugin contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins Do you trust "neos/composer-plugin" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] y - Installing composer/package-versions-deprecated (1.11.99.4): Extracting archive composer/package-versions-deprecated contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins Do you trust "composer/package-versions-deprecated" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] y
Change the ownership of the root directory to nginx
.
$ sudo ./flow core:setfilepermissions $USER nginx nginx
Add the currently logged-in user to the nginx
group.
$ sudo usermod -a -G nginx $USER
That's it for now. We will perform the remaining configurations later on.
Step 7 - Configure SELinux Permissions
Use SELinux's chcon
command to change the file security context for the web content being served from /var/www/neos
directory.
$ sudo chcon -t httpd_sys_content_t /var/www/neos -R $ sudo chcon -t httpd_sys_rw_content_t /var/www/neos -R
Configure SELinux to allow network connections for the Neos CMS.
$ sudo setsebool -P httpd_can_network_connect on
Step 8 - Install and Configure SSL
To install an SSL certificate using Let's Encrypt, we need to download the Certbot tool. We need the Epel repository to install Certbot, but we can skip this step since we installed it earlier in the tutorial.
Install Certbot.
$ sudo dnf install certbot
Stop the Nginx server as it interferes with the Certbot tool.
$ sudo systemctl stop nginx
Generate an SSL certificate.
$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d neos.example.com
The above command will download a certificate to the /etc/letsencrypt/live/neos.example.com
directory on your server.
Generate a Diffie-Hellman group certificate.
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Create a challenge web root directory for Let's Encrypt auto-renewal.
$ sudo mkdir -p /var/lib/letsencrypt
Create a Cron Job to renew the SSL. It will run every day to check the certificate and renew if needed. For that, first, create the file /etc/cron.daily/certbot-renew
and open it for editing.
$ sudo nano /etc/cron.daily/certbot-renew
Paste the following code.
#!/bin/sh certbot renew --cert-name neos.example.com --webroot -w /var/lib/letsencrypt/ --post-hook "systemctl reload nginx"
Save the file by pressing Ctrl + X and entering Y when prompted.
Change the permissions on the task file to make it executable.
$ sudo chmod +x /etc/cron.daily/certbot-renew
Step 9 - Configure Nginx and PHP
Configure PHP-FPM
Open the file /etc/php-fpm.d/www.conf
.
$ sudo nano /etc/php-fpm.d/www.conf
We need to set the Unix user/group of PHP processes to nginx. Find the user=www-data
and group=www-data
lines in the file and change them to nginx
.
... ; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. ; RPM: apache user chosen to provide access to the same directories as httpd user = nginx ; RPM: Keep a group allowed to write in log dir. group = nginx ...
Save the file by pressing Ctrl + X and entering Y when prompted.
Start the PHP service.
$ sudo systemctl start php-fpm
Configure Nginx
Create and open the file /etc/nginx/conf.d/neos.conf
for editing.
$ sudo nano /etc/nginx/conf.d/neos.conf
Paste the following code in it.
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name neos.example.com; access_log /var/log/nginx/neos.access.log; error_log /var/log/nginx/neos.error.log; # SSL ssl_certificate /etc/letsencrypt/live/neos.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/neos.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/neos.example.com/chain.pem; ssl_session_timeout 5m; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; 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_ecdh_curve X25519:prime256v1:secp384r1:secp521r1; ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; resolver 8.8.8.8; root /var/www/neos/Web/; index index.php; location / { try_files $uri $uri/ /index.php?$args; } # Pass PHP Scripts To FastCGI Server location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_pass unix:/run/php-fpm/www.sock; # Depends On The PHP Version fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; 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 REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_NAME $http_host; fastcgi_read_timeout 300; fastcgi_buffer_size 128k; fastcgi_buffers 256 16k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; include fastcgi_params; try_files $uri =404; } 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; } } } # enforce HTTPS server { listen 80; listen [::]:80; server_name neos.example.com; return 301 https://$host$request_uri; }
Notice the root directory to be used in the Nginx configuration is /var/www/neos/Web/
and not /var/www/neos/
.
Save the file by pressing Ctrl + X and entering Y when prompted once finished.
Open the file /etc/nginx/nginx.conf
for editing.
$ sudo nano /etc/nginx/nginx.conf
Add the following line before the line include /etc/nginx/conf.d/*.conf;
.
server_names_hash_bucket_size 64;
Save the file by pressing Ctrl + X and entering Y when prompted.
Verify the Nginx configuration file syntax.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart the Nginx service to enable the new configuration.
$ sudo systemctl restart nginx
Step 10 - Complete Neos Installation
Launch the URL https://neos.example.com
in your browser, and you will get the following setup screen.
Click on the Go to setup button to proceed. You will be redirected to the login screen.
Run the following command in the terminal to get your password.
$ cat /var/www/neos/Data/SetupPassword.txt The setup password is: SCPUYmmQ After you successfully logged in, this file is automatically deleted for security reasons. Make sure to save the setup password for later use.
Enter the password and click on Login to proceed. Neos will check for PHP image libraries.
Click Next to proceed. You will be asked to enter your database credentials. Enter the credentials created in step 4. Once the credentials are verified, you will get a Connection established message on the screen.
Click on Next to proceed. You will be asked to set up an administrator account. Fill in your details.
Click Next to proceed. Next, you will be asked to select whether you want to import a Demo site or create one from scratch. If you want to create a new site from scratch, you must fill in both boxes. For example, if you are creating a news site, fill in the boxes as given. Remember, if you start from scratch, there will be no CSS on the site, and you will have to do it yourself.
Package Name: Neos.HowtoForgeNews Site Name: HowtoForgeNews
For our tutorial, we will stick to the Demo site. To import a demo site, leave all the fields blank.
Click Next to proceed. You will get the setup completion screen.
Click on Go to the backend button to open the login screen for the control panel. Enter your username and password and click Login to open the administration panel.
Since we imported the demo site, the first step is to delete the Try me page, allowing anyone to set up backend accounts with rights to edit the website.
Switch to the Try me page from the left sidebar and click the Delete button highlighted in the screenshot below.
Click the orange-colored arrow to the right of the Published - Live button to open the dropdown menu and click Publish all to save the changes.
Your Neos CMS installation is ready for use.
Conclusion
In this tutorial, you installed and configured Neos CMS using a LEMP stack on a Rocky Linux 8 based server. If you have any questions, post them in the comments below.