Installing VestaCP on VPS, using docker to downgrade PHP

Good time!

I will leave here a solution for my hosting on VPS for 5 euros, mainly with the aim of preserving the implementation of the solution to my problem.

A few years ago I rented a dedicated server for 20+ sites, a file hosting service, a database on PostgreSQL for 1C, an IMAP mail server. I used ISPmanager with a β€œperpetual” license as a control panel, CentOS 7 (or even 6) was used as the OS, which I do not really respect, I like Debian / Ubuntu more. In the future, projects went to social networks, sites ceased to be necessary, domain names were freed.

In 2019, I realized that my site and two client sites were really spinning, I only needed IMAP with storing emails on the hosting, file sharing services also went to cloud services.



What to do if one hosting site does not work with PHP above 5.4

I decided to try to clean the project and deploy it on a cheaper VPS with 40GB hdd, 2 CPUs, 4 RAM versus 8 cores i7, 750 SSD, 24 RAM.

The postgresql base moved to an i5 HP mini computer with 16GB of RAM on a wardrobe at home, brought up RouterOS in the new VPS in docker, configured L2TP and accessed through the tunnel 1C databases from another VPS with Windows 8.1 on board. It would be possible to deploy Windows OS on a machine on a wardrobe for these purposes, but all PostgreSQL service scripts are sharpened under Linux, subjectively, it works faster under Linux, there are clients outside my machines hosting the database.

So introductory:

  1. The total size on a hosting of 30 GB together with OS, sites and mail;
  2. Backup data to the cloud;
  3. One self-written site, two on WP;
  4. Databases in MySQL;
  5. The ability to add sites as needed;
  6. Minimum control in the ssh console (need a site control panel);
  7. The ability to deploy a project on a hosting (free space and free capacity).

After studying offers for free control panels, I decided to stop at VestaCP, although I was somewhat surprised that CP does not support the latest versions of the popular RedHat / Debian distributions. Here is a screenshot at the time of writing.



By the minimum system requirements, everything is great with my VPS.

So, hetzner.cloud, create a project, create a CX21 machine in it.

VestaCP puts nginx proxy to apache2, a config is created for each site / user.

I will not describe all the attempts, only the final one is Debian 9.

Getting an SSH-2 RSA Key Using PuTTY
PuTTY puttygen SSH-2 RSA , Dropbox.

Acess hetzner.cloud RSA, PuTTY SSH-> ( PuTTY RUS) Dropbox. .

Updating the system:

apt-get update -y
apt-get upgrade -y 
apt-get install mc -y
reboot

We put VestaCP on Debian 9
.
Debian , exim - , Β«yΒ» exim. - , :

/bin/bash vst-install-debian.sh

β€” VestaCP http://:8083/ admin password, .


After installing the panel, I immediately went to check the Firewall and was surprised that one of the rules allows external access to MySQL (MariaDB is installed).



I recommend immediately disabling access to such services, my bruteforce passwords went about 5 minutes after installation.

We check the version of PHP: 7.0.33 out of the box. I proceed to solve the problem of downgrading PHP to 5.4.16 (it was decided to deploy it on the old CentOS 7 hosting, epel, httpd + php:

wget https://download.docker.com/linux/debian/gpg
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list.d/docker.list
apt-get install docker-ce
systemctl enable docker
docker login

(If you have not registered yet, you need to register in the Docker Hub.

First, fill in the site script in VestaCP and the database for the site. The script is located by default: /home/site1/wev/site1.ru/public_html

In docker, we create our own CentOS release based on default centos: 7. I will bring my DockerFile:

FROM centos:7
MAINTAINER Dmitry Luponos <info@adm55.ru>
VOLUME /home/site1
EXPOSE 8082
RUN yum update -y && yum install mc -y
RUN yum install epel-release -y
RUN yum install yum-utils -y
RUN yum-config-manager --disable remi-safe
RUN yum-config-manager --enable remi
RUN yum-config-manager --enable remi-php54
RUN yum install -y httpd
RUN yum install php-fpm php-cli php-mysqlnd php-gd php-ldap php-odbc php-pdo php-pecl-memcache php-pear php-xml php-xmlrpc php-mbstring php-snmp php-soap php-zip php-opcache php-imap php php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mcrypt php-mbstring php-curl php-xml php-pear php-bcmath php-json -y
RUN yum clean all

So, what am I doing:

FROM centos: 7 - I select the installation of docker hub
VOLUME / home / site1 - I forward the directory from the OS to the
EXPOSE 8082 guest machine - I open the httpd port - 8082
RUN - I run the command in the machine without the
RUN console yum clean all - I clear cache so that the machine takes up less space.

I am starting to create my own docker image for CentOS 7:

docker pull centos:7
cd /<  Dockerfile>
docker build -t bessome/centos:7 . 
docker run -it --name centphp54 --expose 8082 --restart always -v /home/site1:/home/site1 bessome/centos7:php54 /bin/bash

and we get to the console (-it switch) of the created docker instance.

To get to the instance console in the future, I use the machine ID, which can be obtained with the command
docker ps -a
kind of "e8b6d6ef6c1a".

docker exec -it e8b6d6ef6c1a /bin/bash


and I'm inside.

In the future, I refused EXPOSE - I do not need to open the port outside, it suits that nginx sees the site on the 172.17.0.0/24 network, on port 8082 of the docker instance.

Key

--restart always

tells the machine to restart always when the Docker service is restarted, if you forget then you can do this:

docker update --restart always e8b6d6ef6c1a

Check if the host directory forwarding is hooked:

ls /home/site1
[root@e8b6d6ef6c1a centos.docker]# cd /home/site1
[root@e8b6d6ef6c1a centos.docker]# ls
conf  mail  tmp  web
du -sh
418M    .

Here are the key settings for the httpd instance while we are in the console:
httpd.conf:
Listen 8082
IncludeOptional conf.d/*.conf

/home/site1/conf /etc/httpd/conf.d/site1.conf:

<VirtualHost *:8082>

    ServerName site1.ru
    ServerAlias www.site1.ru
    ServerAdmin info@site1.ru
    AddDefaultCharset off
    DocumentRoot /home/site1/web/site1.ru/public_html
    ScriptAlias /cgi-bin/ /home/site1/web/site1.ru/cgi-bin/
    Alias /vstats/ /home/site1/web/site1.ru/stats/
    Alias /error/ /home/site1/web/site1.ru/document_errors/
    <FilesMatch "\.ph(p[3-5]?|tml)$">
        SetHandler application/x-httpd-php
    </FilesMatch>
    DirectoryIndex index.html index.php
    <FilesMatch "\.phps$">
        SetHandler application/x-httpd-php-source
    </FilesMatch>
    <Directory /home/site1/web/site1.ru/public_html>
        AllowOverride All
        Require all granted
        Options +Includes -Indexes +ExecCGI
        php_admin_value open_basedir /home/tehnolit/web/site1.ru/public_html:/home/site1/tmp
        php_admin_value upload_tmp_dir /home/site1/tmp
        php_admin_value session.save_path /home/site1/tmp
        php_admin_flag engine on
    </Directory>
    <Directory /home/site1/web/site1.ru/stats>
        AllowOverride All
    </Directory>

    IncludeOptional /home/site1/conf/web/apache2.site1.ru.conf*

</VirtualHost>


Each site VestaCP will have its own home directory, site1.ru - test, for example.

Next, we will deal with docker autorun and the machine in it, in addition, systemctl gives an error when trying to start the httpd service inside the instance, we start from rc.local VPS:

 cat rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

docker exec 5473051a7b3c /usr/sbin/httpd
/opt/mpr-start
iptables-restore < /usr/src/iptables.lst

exit 0

Pre- create a service to start the rc.local boot .

I must say that all manipulations with the site settings are made from VestaCP or VPS, with one caveat: editing nginx.conf to access httpd CentOS7:

server {
    listen      <IP-VPS>:80;
    server_name site1.ru www.site1.ru;
    error_log  /var/log/apache2/domains/site1.ru.error.log error;

    location / {
#   docker : 
        proxy_pass      http://172.17.0.2:8082;
        location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|htm|html|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
            root           /home/site1/web/site1.ru/public_html;
            access_log     /var/log/apache2/domains/site1.ru.log combined;
            access_log     /var/log/apache2/domains/site1.ru.bytes bytes;
            expires        max;
            try_files      $uri @fallback;
        }
    }

    location /error/ {
        alias   /home/site1/web/site1.ru/document_errors/;
    }

    location @fallback {
#   docker : 
        proxy_pass      http://172.17.0.2:8082;
    }

    location ~ /\.ht    {return 404;}
    location ~ /\.svn/  {return 404;}
    location ~ /\.git/  {return 404;}
    location ~ /\.hg/   {return 404;}
    location ~ /\.bzr/  {return 404;}

    include /home/site1/conf/web/nginx.site1.ru.conf*;
}

Further, it’s a technical matter - we hook onto MySQL, setting up the corresponding site file containing the connection settings, indicating the internal address 172.17.0.1 of the head VPS, of course, the base should already be deployed and access to it is configured.

As a result, when accessing the site1.ru site, everything should work normally, if not, then somewhere the configuration error crept in, we recheck.

All other sites work correctly with PHP 7.0, so I will not describe the configuration of VestaCP itself.

Thus, I achieved the tasks that I set for myself. I’ll leave it outside the scope of this article to find out the ip-address of the docker instance 172.17.0.xxx, pings and other things, they are not in the DockerFile, I installed the corresponding packages through yum.

PS Along the way, I decided to deploy RouterOS in Docker as well, I had a backup of the L2TP server configuration file from my home router, so only the process:

docker pull evilfreelancer/docker-routeros
docker run -d -p 22202:22 -p 8728:8728 -p 8729:8729 -p 5900:5900 --restart always -ti evilfreelancer/docker-routeros

iptables-save > iptables.lst

We will add access to winbox to iptables via iptables.lst (we will add an access port similar to the ones forwarded when creating 8728 and 5900):

-A INPUT -p tcp -m tcp --dport 8291 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 8291 -j ACCEPT
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 8291 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8291 -j DNAT --to-destination 172.17.0.3:8291

and applicable in VPS:

iptables-restore < iptables.lst

Forward ports to instances docker makes when initializing the machine, during docker update, or you can enter them yourself through the iptables firewall - it's all about the taste.

Next, I deployed the RouterOS configuration, forwarded the ports for access inside docker RouterOS, everything works.

I will not give performance measurements, at the moment everything suits me and the clients. If necessary, I'll take the next VPS with an increase in power and RAM.

Thank you for your attention, I hope someone can help the article quickly deal with docker, and I can return to it after a while and recall the entire installation process.

All Articles