This is the ultimate and must-known digital tutorial about web-server (VPS/VDS) configuration for Nextpost based on my 6 years of experience in Web Development.
Here I’ve documented the steps I use to configure a new server instance.
- Step 1: Software for Web Development
- Step 2: Create and setup your Droplet/VDS in DigitalOcean
- Step 3: Connect your domain with web-server
- Step 4: Install NGINX
- Step 5: Install and Configure MariaDB
- Step 6: Install and Configure PHP7-FPM
- Step 7: How To Install and Secure phpMyAdmin on Ubuntu 20.04
- Step 8: Set up free SSL Certificates with LetsEncrypt with an auto-renew cronjob
- Step 9: Tell NGINX to use PHP7-FPM. NGINX config for Nextpost. Securing and Optimizing.
- Step 10: Install FFmpeg for Nextpost
- Step 11: Nextpost Installation
- Step 12: Troubleshooting.
I think backend is the hardest side of Web Development.
Since I started my experience I spent a lot of time to find and understand which parameters are best, why we set these values and not any other.
This digital guide is the quintessence of all the information that I found on my way of Web Development.
Let’s get started.
Step 1: Software for Web Development
For the best experience I suggest you download and install these programs to you Mac/Windows laptop or PC:
- Visual Studio Code – for web programming, profiling and code editing.
- FTP Manager:
Step 2: Create and setup your Droplet/VDS in DigitalOcean
The first question that you can have: Which cloud VPS should I choose?.
And the golden answer is: Best of the best cloud VPS provider in the whole world is DigitalOcean. No additional words are needed. Just trust me and follow this guide.
If you are using another hosting provider, configure your droplet with the following settings:
- Ubuntu 18.04 (LTS)
- Min. RAM: 1 GB
2.1. DigitalOcean Droplet Creation
Go to your DigitalOcean Dashboard and create a New Project. Name him as you want, in my example, it’s Eye of God.
After that start the droplet creation process.
In the tab, Distribution click on Ubuntu 18.04.3 (LTS) x64 and select a needed plan. You can start with a minimum plan and upgrade your droplet to a large one in the future. At the moment it’s not so necessary.
Choose the nearest region to you. For me, it’s Frankfurt, Germany. You can use this speed test tool provided by DigitalOcean to compare droplet downloads/upload speeds from your current location.
In section Additional options check following checkboxes:
- Private Networking
The most important step is Authentication. Here we should add laptop/PC SSH keys from all our devices from which we want to have access to our web server.
Follow these instructions to create or add SSH keys on Linux, MacOS & Windows. Windows users without OpenSSH can install and use PuTTY instead.
Create a new key pair, if needed
If you already generated an SSH key for your device go to step Add the public key.
Open a terminal and run the following command:
You will be prompted to save and name the key.
Generating public/private rsa key pair. Enter file in which to save the key (/Users/USER/.ssh/id_rsa):
Next, you will be asked to create and confirm a passphrase for the key (highly recommended):
Enter passphrase (empty for no passphrase):<br>Enter same passphrase again:
This will generate two files, by default called id_rsa and id_rsa.pub. Next, add this public key.
Add the public key
Copy and paste the contents of the .pub.pub file, typically id_rsa.pub, into the SSH key content field on the left.
For more detailed guidance, see How to Add SSH Keys to Droplets
Add your unique SSH key to DigitalOcean.
Add all needed devices and mark SSh keys checkboxes, you can also choose custom hostname and add tags. Finally, choose a project, that we created recently.
I strongly recommend you enable Backups. This will be a lifesaver option if your website somehow will be hacked or broken in unknown reasons.
Recently I have the experience when hackers in an unknown way got access to the webserver and deleted a website with the cost equal to 30k USD. Backup saved my life from unwanted recovery work.
Wait a few minutes while your droplet configurated.
After that go to the droplet section and copy your server IP.
2.2. Server Configuration
When you first create a new Ubuntu 18.04 server, there are a few configuration steps that you should take early on as part of the basic setup.
This will increase the security and usability of your server and will give you a solid foundation for subsequent actions.
Follow this tutorial and make a initial server setup Initial Server Setup with Ubuntu 18.04.
When you open the page with Nano Editor you can see keyboard shortcuts, where ^ symbol is CTRL (control) key. For save changes and exit from nano editor just type CTRL+X in one moment and say yes in prompt.
After that I save changes with CTRL+X command and reload SSH:
sudo systemctl reload sshd
Log out from a web server and login again with this new command where:
- your_server_ip – your own web server (droplet) IP address.
exit ssh [email protected]_server_ip
Step 3: Connect your domain with web-server
At this point, it’s also a good idea to set up your domain name to point to your server.
Once you’ve set it up, it can take up to a couple of days for the change to take effect, but in practice, it usually only takes a few minutes to a couple of hours.
Log in to the site where you registered your domain name and change the nameservers to point to ns1.digitalocean.com, ns2.digitalocean.com, and ns3.digitalocean.com.
After you do that, head over to your DigitalOcean account and go to Networking > Domains.
In the form to “Add a Domain” enter your domain name and then select the droplet, you created in Step 2.
I typically set up my domains to route email through Gmail.
Here, you can find tutorial to set up your DNS to use GMail’s servers.
Add 2 A-records for connecting your domain with the webserver.
Finally, it’s should look like that.
Step 4: Install NGINX
Let’s install a custom version of NGINX. From the command line.
Every command you should type from a new line and press Enter.
sudo apt-get update sudo apt-get install nginx sudo ufw allow 'Nginx Full' sudo ufw enable
Step 5: Install and Configure MariaDB
MariaDB is a drop-in replacement for MySQL. You can read about why people think it’s better, but I’m mostly convinced by the performance arguments. The MariaDB website has a convenient tool for configuring the correct repositories in your Ubuntu distro. Using the tool, I came up with the following steps for installing the DB:
sudo apt-get install software-properties-common sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8 sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.2/ubuntu xenial main' sudo apt-get update sudo apt-get install mariadb-server
Go next and run this command:
After that press Enter and y to create a new root password. Make sure you provide a good secure password that is different from the password you used for your user account.
Since you’ve already set up a secure password for your root user, you can safely answer “no” to the question asking you to create a new root password. Answer “Yes” to all of the other questions.
Now we can set up a separate MariaDB account and database for our Nextpost instance. At the command prompt type the following:
sudo mysql -u root -p
Type in your password when prompted.
This will open up a MariaDB shell session. Everything you type here is treated as an SQL query, so make sure you end every line with a semicolon! This is very easy to forget. Here are the commands you need to type in to create a new database, user, and assign privileges to that user:
CREATE DATABASE nextpost_db DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; GRANT ALL ON nextpost_db.* TO 'nextpost_db_user'@'localhost' IDENTIFIED BY 'securepassword'; FLUSH PRIVILEGES; quit
Note that although it’s customary to use ALL CAPS to write SQL statements like this, it is not strictly necessary.
Also, where I’ve used “nextpost_db” and “nextpost_db_user” feel free to use your own database and user names, and as securepassword use own secure password value.
Finally, it is recommended that you create a MariaDB sources.list file. This file will make sure that when your server periodically looks for updates, it will also check the MariaDB repository to keep it up to date.
Create the file and open it for editing by typing the following at the command prompt:
sudo nano /etc/apt/sources.list.d/MariaDB.list
Copy and paste the following code into that file:
# MariaDB 10.2 repository list - created 2019-10-1 18:00 UTC # http://downloads.mariadb.org/mariadb/repositories/ deb [arch=amd64,i386] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.2/ubuntu xenial main deb-src http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.2/ubuntu xenial main
Save and close the file by typing CTRL + X.
Check how much free RAM there is on the server with command:
Set MySQL buffer pool size in /etc/my.cnf less than amount of free RAM.
In our example, we have 122M free, and for innodb_buffer_pool_size we will set 100M. Your value will be different but should be less than the amount of free RAM.
For our example:
Restart MySQL service with :
service mariadb restart
Step 6: Install and Configure PHP7-FPM
One of the cool things about Ubuntu 20.04 is that it’s default PHP packages now default to version 7!
Installing PHP is as simple as typing the following:
sudo apt-get install -y zip unzip php-fpm php-mysql php-xml php-gd php-mbstring php-zip php-curl
Note that this also installs the MySQL, XML, Curl and GD packages so that Nextpost can interact with the database and also automatically crop and resize images. It also installs zip/unzip.
Now run this command in the console:
From that line, we can find the current PHP version of our server. This should be a 7.4.
And now we can run this command to edit php.ini settings:
sudo nano /etc/php/7.4/fpm/php.ini
Also, the easiest way to edit files of our server is to use File Manager and connect to the server via FTP. Software for this you can find in Step 1.
When you use FTP Manager it’s really useful to open the file in Microsoft Visual Studio Code and edit him directly. All changes will be applied to the server file after we save changes in the Visual Studio Code.
Open /etc/php/7.4/fpm/php.ini (your PHP version can be higher 7.3 or 7.4) and change the default values to these:
max_execution_time = 60 memory_limit = 512M display_errors = On post_max_size = 100M upload_max_filesize = 100M default_socket_timeout = 300 opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.validate_timestamps=1 opcache.revalidate_freq=60
After that save changes in the file.
Open the next one /etc/php/7.4/fpm/pool.d/www.conf.
Set pm to dynamic:
pm = dynamic
Configure dynamic pool
For the main application server, due to obvious advantages, they often choose a dynamic pool. Its operation is described by the following settings:
- pm.max_children – the maximum number of child processes
- pm.start_servers – the number of processes at startup
- pm.min_spare_servers – the minimum number of processes waiting for a connection (requests for processing)
- pm.max_spare_servers – the maximum number of processes waiting for a connection (requests for processing)
In order to correctly set these values, you must consider:
- how much memory does the child process consume on average
- amount of RAM available
To find out the average memory value per php-fpm process on an already running application, use the scheduler:
ps -ylC php-fpm --sort:rss
In my case, I use Nextpost + Hyperloop Masslooking module and one process takes ~50Mb.
The total / available / used memory can be viewed using free:
# free -m
total used free ... Mem: 1993 181 1574
My server has 2GB of RAM. Next, we take the formula for calculating pm.max_children (source) as a basis, and perform an example calculation:
Total Max Processes = (Total Ram - (Used Ram + Buffer)) / (Memory per php process) Total RAM: 2GB RAM used: 200MB Security buffer: 400MB Memory for one child php-fpm process (average): 30MB The maximum possible number of processes = (2000 - (200 + 400)) / 50 = 28 Even number: 28 rounded down to 20
pm.max_children = 20 pm.min_spare_servers = Total RAM = 2 pm.max_spare_servers = 2 * Total RAM = 4 pm.start_servers = min_spare_servers + (max_spare_servers - min_spare_servers) / 2 = 3 pm.max_requests = 0
For example, I have a server with 4GB and use the following settings in /etc/php/7.4/fpm/pool.d/www.conf:
pm = dynamic pm.max_children = 60 pm.min_spare_servers = 4 pm.max_spare_servers = 8 pm.start_servers = 6 pm.max_requests = 0
To get PHP to load the changes you need to restart it by typing:
sudo service php7.4-fpm restart
Step 7: How To Install and Secure phpMyAdmin on Ubuntu 20.04
For easy database management, I’m using phpMyAdmin.
Here you can find a tutorial about how to install phpMyAdmin on Ubuntu.
Then set the appropriate permissions for the phpMyAdmin root directory to prevent access errors.
sudo chmod 775 -R /usr/share/phpmyadmin/ sudo chown -R www-data:www-data /usr/share/phpmyadmin/
If the login with the root username fails (because it requires sudo starting with MySQL 5.7), you may need to create a new administrator account in order to access the mariadb shell using the root account from the terminal.
sudo mysql -u root -p
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'securepassword'; GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES;
Now you can use the new credentials to enter in phpMyAdmin to manage the MySQL databases.
- Error – count(): Parameter must be an array or an object that implements Countable – FIXED, the solution is here.
Step 8: Set up free SSL Certificates with LetsEncrypt with an auto-renew cronjob
In the next step, we’re going to add an SSL certificate to our site and then configure NGINX to use it. I recommend that you read DigitalOcean’s entire tutorial on securing NGINX on Ubuntu 20.04 with LetsEncrypt, but I’ll provide just the steps you need here.
First, install LetsEncrypt:
sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install python-certbot-nginx
Next, we’ll install our certs using:
sudo certbot --nginx certonly -d yoursite.com
If all will be ok you will see something like this:
Repeat process for www.yoursite.com
sudo certbot --nginx certonly -d www.yoursite.com
[OPTIONAL] If you are running Nextpost on the subdomain you should obtain certificates for subdomain:
- subdomain – your custom unique name
First of all, add DNS A-records for the subdomain in DNS management.
- subdomain and server-IP
- www.subdomain and server-IP
After that obtain certificates.
sudo certbot --nginx certonly -d subdomain.yoursite.com sudo certbot --nginx certonly -d www.subdomain.yoursite.com
Next, we’ll edit the configuration snippet for NGINX that was created by Certbot and which will contain all of our SSL parameters.
Open the file as follows:
sudo nano /etc/letsencrypt/options-ssl-nginx.conf
Edit the file so that it looks like the one below. The top six or seven lines should have been created automatically for you by Certbot, and the ones below add the extra parameters we’ll need to take advantage of our heightened security profile:
# This file contains important security parameters. If you modify this file # manually, Certbot will be unable to automatically provide future security # updates. Instead, Certbot will print and log an error message with a path to # the up-to-date file that you will need to refer to when manually updating # this file. ssl_session_cache shared:le_nginx_SSL:1m; ssl_session_timeout 1440m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-R$ # MANUALLY ADD THESE ssl_ecdh_curve secp384r1; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 188.8.131.52 184.108.40.206 valid=300s; resolver_timeout 5s; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff;
Save and exit this file.
It is important to note that SSL certificates from LetsEncrypt expire every 90 days. In order that you don’t have to log into your server every 3 months to renew your certs, we’re going to set up a CRON job to auto renew them.
From the command line:
sudo crontab -e
Type just Enter in prompt.
Remove everything in the file and add the following lines:
30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log 35 2 * * 1 /bin/systemctl reload nginx
This will update the LetsEncrypt client and then attempt to renew and load your certs (if necessary) every Monday.
In case you’d like to test to make sure the automated renewal will work, you can use the following command to do a dry run:
sudo certbot renew --dry-run
Step 9: Tell NGINX to use PHP7-FPM. NGINX config for Nextpost. Securing and Optimizing.
Open up the configuration file with File Manager for your default site for NGINX:
Edit the file so that it looks like this but change yoursite.com and www.yoursite.com to reflect the URL for your website.
This NGINX configuration file already optimized for use with any Nextpost installation.
If you are running Nextpost on subdomain change yoursite.com everywhere to subdomain.yoursite.com.
Your PHP version can be higher 7.3 or 7.4:
- fastcgi_pass unix:/run/php/php7.3-fpm.sock;
- fastcgi_pass unix:/run/php/php7.4-fpm.sock;
After that save changes in the config file and restart web server using these commands:
sudo service nginx restart sudo service php7.4-fpm restart sudo service mysqld restart sudo service cron reload
And also change folder permissions from root to www-data, if you are logged in in FTP Manager as the root user.
sudo chown -R www-data:www-data /var/www/html
For a test that all working well create a file index.php in /var/www/html with this content:
<?php phpinfo(); ?>
Now go to the browser and open page with your domain. You will see information about your PHP, that we installed before.
Delete this file index.php file.
Step 10: Install FFmpeg for Nextpost
Q: How to post videos in Nextpost? Install ffmpeg?
A: For install ffmpeg just run this command in Terminal, add binary path to config and enable Video checkpoints in Packages and User Settings:
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg apt install ffmpeg
Q: How do I know the path of ffmpeg?
Use these commands:
whereis ffmpeg whereis ffprobe
Step 11: Nextpost Installation
Place all Nextpost script files in /var/www/html/ folder.
Now you can start standard Nextpost installation. All steps explained here.
Step 12: Troubleshooting.
12.1. Hyperloop Masslooking module. Task status all time is “Scheduled” and don’t changed to “Active”.
Please check is cronjob works in all you modules correctly. If cron not working correctly in one of modules, it’s can break all cronjob system.
/var/log/ – here you can find server logs
That’s all, thank you!
Now clean browser cache and take a look at your changes. For example I attached screenshot from Chrome.