📜 ⬆️ ⬇️

Configuring a dedicated server for the site running HostCMS

In the “life” of almost any web project - be it a small online store or a bar site that is gaining popularity - sooner or later a moment happens when neither the capabilities and resources of the shared hosting nor the resources for the total reorganization of the application architecture are enough. A few years ago, when I was still working in a small web studio, I often had to observe such a picture. In almost all such cases, the same decision was taken - renting a dedicated server and transferring the project to it as it is. At that time, a lot of articles were available on the network on setting up servers with Linux on board. Moreover, almost all of them were not of the best quality and often contained so bad advice that Mr. Oster could have applauded the authors of those materials.

“All this is a matter of days gone by” - this was how I thought more recently, until my old friend turned to me for help in solving a similar problem. As it turned out, the situation has not changed much since: the required section of the documentation has practically not been updated, the developers themselves generally advise using shared hosting from their partners, and there was no sensible material that takes into account the nuances of migration to a dedicated project server to HostCMS. I like the CMS itself, so I decided to correct this omission. If interested - welcome under cat.

First of all make a reservation. In this article I will not consider the issues of choosing a hosting provider - with this, I think, you can handle it yourself. Ubuntu Server 14.04 was chosen as the server OS as one of the most user friendly. I assume that you have a minimal amount of knowledge to work in Linux. Unfortunately, here you will not find the fine tuning of the PAM module for setting user limits on access to files, etc. - if you are looking for such material, then most likely this article will be boring for you.

The first steps


So, we have a dedicated server and data to access it via ssh. Rule one, it’s the main thing, try to avoid constant work on behalf of the privileged user. During the first session, create your own account and set a password for it. For example:
')
useradd user_name -s /bin/bash -U -m -G sudo passwd user_name 

We will carry out further work on behalf of the newly created user.

Install the necessary software


nginx

Nginx will be used as the HTTP server. I think he needs no introduction. We will install it from the repository , kindly deployed by the development team. To do this, you must obtain a key with which the installation packages are signed:

 #          STDOUT #           wget http://nginx.org/keys/nginx_signing.key sudo apt-key add nginx_signing.key rm nginx_signing.key 

And update the list of package sources by adding the lines to /etc/apt/sources.list :

 # 12.04 = precise # 14.04 = trusty deb http://nginx.org/packages/ubuntu/ trusty nginx deb-src http://nginx.org/packages/ubuntu/ trusty nginx 

After this update and install nginx:

 sudo aptitude update && sudo aptitude upgrade -y sudo aptitude install nginx 

To set limits on the number of files opened by the http-server user, you need to add the following lines to /etc/security/limits.conf :

 nginx hard nofile 32768 nginx soft nofile 32768 

Exact numbers should be selected based on the configuration of your server. The limit module is activated by adding the following line to /etc/pam.d/common-session :

 session required pam_limits.so 

You can check that the limits are set by the following command:

 sudo su nginx --shell /bin/bash --command "ulimit -a" 

Php

HostCMS requires the following php modules to be included: curl, gd, xslt and, of course, mysql. In addition, please note that now the php5-json package is not virtual and must be installed separately. Among other things, let's connect the caching module of the xcache opcode. As SAPI (interpreter launch mode) we will use PHP-FPM, however, in order to be able to execute some scripts according to the schedule, the PHP-CLI will also be installed.

 sudo aptitude install php5-common php5-fpm php5-cli php5-curl php5-gd php5-mysql php5-xsl php5-json php5-xcache 

Mysql

MySQL installation is pretty simple. Several times the installer will ask you for the password for the database server’s root, you can safely leave it empty - we will change it later using the mysql_secure_installation utility. When you start it, answer that you want to change the root password, remove the test database and test users, and update the permissions on the service database tables.

 sudo aptitude install mysql-server sudo mysql_secure_installation 

Read in detail about setting up a mysql server here . The article is well written, so I see no reason to duplicate information here.

File Upload Settings


As a file transfer protocol, I suggest using SSH FTP (SFTP) . Firstly, it is safer than regular ftp, since the data will be transmitted in encrypted form. Secondly, you do not have to install additional software: all you need is an ssh server - we already have it. And there are practically no minuses - all modern IDE and data download clients can work with this protocol.
To determine who can connect via sftp, create an additional group of users, for example, sftp :

 sudo groupadd sftp 

And we activate the data transfer by adding lines to the end of the / etc / ssh / sshd_config file:

 Match Group sftp ChrootDirectory %h ForceCommand internal-sftp AllowTcpForwarding no 


Preparing the file system


Traditionally, files related to websites are located in the / var / www / directory. And we will not deviate from this unspoken rule. Create a folder for virtual hosts and the future mount point for the fast cache:

 sudo mkdir -p -m 755 /var/www/data sudo mkdir -m 777 /var/www/tmp 

Then we point out that at the next boot, tmpfs will be mounted into this folder. Add to / etc / fstab :

 tmpfs /var/www/tmp/ tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=128M 0 0 

It is worth noting that some editions of HostCMS have a built-in algorithm for caching responses to files. If you are using one of these editions, it makes sense to mount tmpfs to the cache directory of the CMS itself.

Configuring virtual hosts


If you plan to deploy several sites running HostCMS on your server, you will need to repeat the procedure described below several times. In this case, it makes sense to try to automate the process of establishing a new host. I advise for these purposes to pay attention to a small set of scripts described in this article , and "finish" them for themselves.

The institution user host

For security reasons, all files associated with our site will belong to a specially instituted user in the system. Connecting via sftp and executing PHP scripts will occur on its own behalf. To make it easier, you can call it by the name of your site:

 sudo useradd -b /var/www/data -s /usr/lib/sftp-server -m -U -G sftp example.com sudo passwd example.com sudo su example.com --shell /bin/bash --command "mkdir -m 0755 ~/data ~/log && mkdir -m 0777 ~/tmp" 

For chroot to work correctly, you need to make root the owner of this user's home directory:

 cd /var/www/data sudo chown root:root example.com 

Establishment of a pool of PHP-FPM

The php-fpm pool will run on behalf of the user we created in the previous step. To interact with the front-end server will be used Unix-socket. In addition, you can configure the number of running processes to process requests, the type of logging and some other php parameters specific to your site.
Pula configuration example
 [example.com] user = example.com group = example.com listen = /var/run/php5_example.com.sock listen.backlog = 4096 listen.owner = nginx listen.group = nginx listen.mode = 0660 process.priority = 0 chdir = / pm = dynamic pm.max_children = 64 pm.start_servers = 8 pm.min_spare_servers = 4 pm.max_spare_servers = 16 pm.process_idle_timeout = 60s; pm.max_requests = 256 access.log = /var/www/data/example.com/log/php.access.log access.format = "%R # %{HTTP_HOST}e # %{HTTP_USER_AGENT}e # %t # %m # %r # %Q%q # %s # %f # %{mili}d # %{kilo}M # %{user}C+%{system}C" slowlog = /var/www/data/example.com/log/php.slow.log request_slowlog_timeout = 2s request_terminate_timeout = 300s php_admin_flag[display_errors] = off php_admin_flag[log_errors] = on php_admin_value[error_log] = /var/www/data/example.com/log/php.error.log php_admin_value[memory_limit] = 32M php_admin_value[open_basedir] = /var/www/data/example.com/:. php_admin_value[upload_tmp_dir] = /var/www/data/example.com/tmp php_admin_value[session.save_path] = /var/www/data/example.com/tmp 


Creating a virtual host config

In the nginx host configuration file, you will need to specify the domain name of the site, the path for recording access logs, and the address of the unix socket that is listening to php-fpm. To handle requests for non-existent files, we will use the named location — in this way we will emulate the operation of mod_rewrite for Apache2. Before giving the script to our backend for processing, check its existence. This will avoid the problem described here . In order to reduce the load on the site from unregistered users, we will use caching on the side of nginx. To do this, create the configuration file /etc/nginx/conf.d/cache with the following contents:

  fastcgi_cache_path /var/www/tmp/cache levels=1:2 keys_zone=cache:32m max_size=128m; fastcgi_temp_path /var/www/tmp/proxy 1 2; fastcgi_ignore_headers Expires Cache-Control; fastcgi_cache_lock on; fastcgi_cache_lock_timeout 60s; fastcgi_cache_use_stale error timeout updating invalid_header; fastcgi_cache_bypass $cookie_PHPSESSID; fastcgi_no_cache $cookie_PHPSESSID; fastcgi_cache_key $scheme$host$request_uri; 

And then connect it to the virtual host config.

Nginx host config example
 server { listen 80; server_name example.com www.example.com; access_log /var/www/data/example.com/log/nginx.access.log main; error_log /var/www/data/example.com/log/nginx.error.log; root /var/www/data/example.com/data; error_page 404 /404/; location / { index index.html index.php; try_files $uri $uri/ @hostcms; } # php    php-fpm,     location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5_example.com.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; include /etc/nginx/conf.d/cache; } #  ,     ,   index.php location @hostcms { fastcgi_pass unix:/var/run/php5_example.com.sock; fastcgi_param SCRIPT_FILENAME $document_root/index.php; include fastcgi_params; include /etc/nginx/conf.d/cache; } 


Creating a site database

Now almost everything is ready, it remains only to expand the database and create a user on whose behalf the connection will be made to it. To do this, in the mysql console, run a few simple commands:

 CREATE USER 'example_com'@'localhost' IDENTIFIED BY ''; GRANT USAGE ON * . * TO 'example_com'@'localhost' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0; CREATE DATABASE IF NOT EXISTS example_com_db DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; GRANT ALL PRIVILEGES ON example_com_db . * TO 'example_com'@'%'; 

Please note that the connection to the database on behalf of this user is allowed from any address.
If you have a dump of the previously used database, then you can deploy it using the following set of commands all in the same mysql console:

 use example_com_db; source ; 


Setting up backup and log rotation


If you did everything right, then you should already have a fully configured environment to run your project. The last two in the list remain, but not least in importance, setting up backup and log rotation. As a tool for creating backups, I recommend using backup-manager. On Habré there is an excellent article about him, so we will not dwell on it in detail.

To rotate the logs, we just need to create the correct config for the logrotate utility.
For example, such
 /var/www/data/example.com/log/nginx*.log { weekly missingok rotate 52 compress delaycompress notifempty create 640 root root sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript } /var/www/data/example.com/log/php*.log { weekly missingok rotate 52 compress delaycompress notifempty create 640 root root postrotate invoke-rc.d php5-fpm reopen-logs > /dev/null endscript } 



Instead of conclusion


Perhaps this is all I wanted to say.
Perhaps someone will consider the article not very relevant due to the domination of the hosting control panels. Although, in my opinion, they are good for mass provision of services and are completely inappropriate when it comes to honing the server settings for a specific project.
Others will find it a bit messy. It is possible that this is the case: in the article I just tried to reflect my confused experience in the field of server administration.
In any case, I will be glad if this material will help someone. Comments and additions are welcome.

Source: https://habr.com/ru/post/240725/


All Articles