Template engine for configuration files
A new mechanism that allows generating Apache and Nginx configuration files. The mechanism is based on a template that enables to use logical branches and parameter setting, allowing for more flexible creation and modification configuration parameters of a web-server.
With this mechanism, you can use the required parameters in order to configure Apache and Nginx. Besides, after you add user parameters into the configuration file, other operations that the template engine performs, won't modify them.
Starting from version 5.57, ISPmanager supports this feature by default. This article will walk you through the steps you need to perform to start using a template engine, describe its general functions and syntax.
How to start?
If you have just installed ISPmanager Lite or ISPmanager Business 5.57 and later, the template engine will be used by default to generate configuration files of the "WWW-domains" module.
If you updated your panel to version 5.57 or later, you need to add the Option EnableWebTemplate parameter in ISPmanager Lite /usr/local/mgr5/etc/ispmgr.conf configuration file and ISPmanager Business /usr/local/mgr5/etc/ispmgr.conf, located on a local cluster node, and restart the panel.
Starting from version 5.57 the AlphaWebTemplate option that enabled this mechanism in older versions is no longer supported.
General principles
In the WWW-domains module every function has a corresponding configuration file template. E.g., web-domain creation/edit function has a corresponding template in the /usr/local/mgr5/etc/templates/default/apache2-vhosts.template file for Apache configuration file, and /usr/local/mgr5/etc/templates/default/nginx-vhosts.template for Nginx.
Files with configuration templates can be re-defined by user parameters. Copy a file with template into the /usr/local/mgr5/etc/templates directory with the same name. If the /usr/local/mgr5/etc/templates directory contains a template file, the template in the /usr/local/mgr5/etc/templates/default/ directory will be ignored. When the panel updates, files in the /usr/local/mgr5/etc/templates/default/ directory will be overwritten, that's why you should make changes in /usr/local/mgr5/etc/templates/.
The table below shows correspondence between a file with a template, and a function to call in the WWW-domains module.
Function | Nginx template | Apache template |
---|---|---|
Add/Edit WWW-domain | nginx-vhosts.templatenginx-vhosts-ssl.template | apache2-vhosts.templateapache2-vhosts-ssl.template |
Add/Edit/Delete error page | nginx-error-page.template | apache2-error-page.template |
Add/Edit/Delete redirects | nginx-rewrite.template | apache2-redirect.template |
Add/Delete access permissions | nginx-access.template | apache2-access.template |
Resume/Suspend WWW-domain | nginx-suspend.template | apache2-suspend.template |
Syntax
All template sections must locate between tags {% and %}. E.g. a variable should look like this: {% $VARIABLE_NAME %}.
Variables
A variable name should meet the following requirements:
- user upper-case letters
- start with $
- have the same name as the parameter passed to the session by the control panel.
If a configuration string in template contains a variable that is not present in the session, the string will be ignored. Let's consider an example where the template will create the VirtualHost section for the Apache configuration file. In the example below, we will use the {%$LISTEN_ON %} variable where an address and port are kept: 192.168.0.1:80.
<VirtualHost {% $LISTEN_ON %}>
</VirtualHost>
As a result, the VirtualHost section will be created in the configuration file:
<VirtualHost 192.168.0.1:80>
</VirtualHost>
Conditions
A condition is the main selection tool. It will choose, what parameter to add or delete depending on variable during condition check. Conditions should start with the if statement and end with endif. Let's consider a simple condition containing only if.
{% if $VARIABLE_NAME == VALUE %}
ParameterName ParameterValue;
{% endif %}
If a result of this condition is true, every parameter located between if and endif will be added into the configuration file (if that parameter is not present). If the result is false, every parameter between if and endif will be deleted from the configuration file.
Advanced conditions
You can create an advanced condition containing else. Parameters located between else and endif will be added into the configuration file if a result of the if statement is false, or deleted from the configuration file, if it is true. Let's consider an example where parameter will be added or deleted depending on Apache version:
<VirtualHost {% $LISTEN_ON %}>
{% if $APACHEITK == ON %}
AssignUserID owner group
{% else %}
SuexecUserGroup owner group
{% endif %}
</VirtualHost>
The VirtualHost section will be created in the configuration file, if ApacheITK is used, the AssignUserID owner group parameter will be added into VirtualHost, and the SuexecUserGroup owner group parameter will be deleted from VirtualHost, if it was present in that section. The following example shows what parameters the configuration file will contain if ApacheITK is used:
<VirtualHost 192.168.0.1:80>
AssignUserID owner group
</VirtualHost>
If another version of Apache is used, the configuration file will contain the following parameters:
<VirtualHost 192.168.0.1:80>
SuexecUserGroup owner group
</VirtualHost>
Conditions for multiple selections
A condition can be enlarged with the elif statement. It can be used if one of the variables have different values, which should be processed. E.g. when creating or editing a web-domain, ISPmanager enables to choose a PHP mode. Let's consider such a situation, and suppose that we have created a web-domain with "PHP as Apache" enabled. Our configuration file looks like that:
<VirtualHost 192.168.0.1:80>
ServerName domain.ru
ServerAlias www.domain.ru
<FilesMatch "\.ph(p[3-5]?|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
</VirtualHost>
We edited web-domain parameters and set PHP as CGI. The template below enables to add or delete the FilesMatch subsection depending on a selected PHP mode.
<VirtualHost {% $LISTEN_ON %}>
{% if $PHP_MODE == MODULE_APACHE %}
<FilesMatch "\.ph(p[3-5]?|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
{% elif $PHP_MODE == CGI %}
<FilesMatch "\.ph(p[3-5]?|tml)$">
SetHandler application/x-httpd-php5
</FilesMatch>
{% endif %}
</VirtualHost>
The VirtualHost section won't be created in the configuration file, as it is already present. All the changes will be made in existing VirtualHost. Based on conditions from our example, the result of the if statement will be false, therefore, all parameters between if and elif will be deleted from VirtualHost. Parameters between elif and endif will be added into VirtualHost. The configuration file will look like that:
<VirtualHost 192.168.0.1:80>
ServerName domain.ru
ServerAlias www.domain.ru
<FilesMatch "\.ph(p[3-5]?|tml)$">
SetHandler application/x-httpd-php5
</FilesMatch>
</VirtualHost>
Table of comparison operators
The following comparison operators can be used in conditions:
Operator | Comparison |
---|---|
== | Equality. This condition is true if two operands are equal |
!= | Inequality. This condition is true if two operands are not equal |
> | Larger. This condition is true if the first operand is larger than the second one |
< | Less. This condition is true if the first operand is less than the second one |
String commenting
You can use {#} to comment strings in the configuration file template. Everything that you add after comment will be ignored by the template engine. Example:
<VirtualHost {% $LISTEN_ON %}>
ServerName {% $NAME %} {#} Comment
{#} ServerAlias {% $ALIASES %}
</VirtualHost>
The configuration file will then look like that:
<VirtualHost 192.168.0.1:80>
ServerName domain.ru
</VirtualHost>
Template import
Other templates can be imported into the configuration file template. Use the import construction. E.g.:
<VirtualHost {% $LISTEN_ON %}>
{% import /path/to/template/apache-params.template %}
</VirtualHost>
Enter an absolute path to a template you want to import.
Parameters that identify sections
Every type of configuration file has certain parameters that are used by the template engine to identify sections. E.g. for the Nginx configuration file, server_name and ssl are selected as key parameters. Therefore, when something should be added or deleted from the configuration file without a control panel, the template engine "knows" exactly where to perform the operation. However, if you are trying to modify those parameters in the configuration file, they are likely not to be added into a required section but will be applied in a new section.
Searching for a modified parameter by key values
There are additional tags — [% и %]. They can contain only variables, such as [% $VARIABLE_NAME %]. This expression is interpreted as a common variable but plays a specific role in parameter search. These tags define values that won't be used during the search process. Let's consider the following example:
<VirtualHost 192.168.0.1:80>
ServerName domain.ru
ServerAlias www.domain.ru
</VirtualHost>
Use the template:
<VirtualHost {% $LISTEN_ON %}>
{% if $ERROR == on %}
ErrorDocument {% $CODE %} [% $URI %]
{% endif %}
</VirtualHost>
If the $ERROR variable is on, the ErrorDocument parameter with variables $CODE and $URI will be added into VirtualHost. The $CODE and $URI values are specified in the control panel on the error page creation form. During that process, the $ERROR variable is set to on, therefore the condition is met, and our configuration file looks like that:
<VirtualHost 192.168.0.1:80>
ServerName domain.ru
ServerAlias www.domain.ru
ErrorDocument 404 /404.php
</VirtualHost>
Then, we decided in the configuration file change the path from /404.php into /404.html. We have the following configuration file:
<VirtualHost 192.168.0.1:80>
ServerName domain.ru
ServerAlias www.domain.ru
ErrorDocument 404 /404.html
</VirtualHost>
In this case, the ErrorDocument parameter differs from the one specified in the control panel. If we decide to delete the error page from the control panel, the template engine won't find a required parameter in the configuration file and won't delete it. But in the template the $URI value is canceled, the search will be made by the ErrorDocument 404 string. Deleting of an error page will set the $ERROR variable to off, therefore the condition used in the template, won't be met. Only ErrorDocument 404 will be used to search for our parameter, thus it will be found and deleted in the configuration file.
Standard variables
Every function you call uses its own set of parameters that are passed to a session. The following list contains standard variables for each WWW-domain management function.
Creating/Editing WWW-domain
The table below contains a list of variables regardless a web-servers type.
Variable | Description |
---|---|
Main parameters of WWW-domain | |
$NAME | WWW-domain name |
$ALIASES | WWW-domains aliases |
$DOCROOT | Root directory |
$HOME | Home directory of a WWW-domain's owner |
$OWNER | WWW-domain's owner |
$OWNER_GROUP | WWW-domain's owner group |
$UID | Owner UID |
$GID | Owner GUID |
$PRESET | Owner templateOnly for ISPmanager Lite |
$PRESET_NAME | Owner templateOnly for ISPmanager Business and if the reseller is not a user's owner |
$RESELLER_NAME | Reseller nameOnly for ISPmanager Business |
$RESELLER_PRESET | Reseller templateOnly for ISPmanager Business |
$IPADDRS | IP-addresses to listen |
$LISTEN_ON | IP-addresses and port to listen |
Administrator email | |
$CHARSET | Encoding |
$DIRINDEX | Index page |
$SSL | WWW-domain uses secure connection. Possible values:
|
$REDIRECT_HTTP | Redirect HTTP-requests to HTTPS. Possible values:
|
$SSL_PORT | Secure connection port |
$LISTEN_ON_SSL | IP-address and port of secure connection |
$SSL_CRT | Path to SSL certificate |
$SSL_KEY | Path to SSL key |
$SSL_BUNDLE | Chain of SSL certificate including root and intermediate certificates |
$HSTS | Advanced SSL secure. Possible values:
|
$SSL_SECURE_PROTOCOLS | SSL protocols |
$SSL_SECURE_CHIPHERS | Cryptographic algorithm |
$SSI | SSI. Possible values:
|
$FOREGROUND | Current WWW-domain has the highest priority. Possible values:
|
Logging | |
$LOG_ACCESS | Allow logging of requests to resources of this WWW-domain. Possible values:
|
$ACCESS_LOG_PATH | Path log-file with requests to resources |
$LOG_ERROR | Allow logging of errors that occur when processing requests to resources of this WWW-domain. Possible values:
|
$ERROR_LOG_PATH | Path to error log-file |
$ROTATION_PERIOD | Rotation period. Possible values:
|
$ROTATION_COUNT | Number of old copies to store |
$ANALYZER | Analyzer. Possible values:
|
$ANALYZER_PERIOD | Report period. Possible values:
|
$ANALYZER_LANG | Report language |
$ANALYZER_SECURE | Restrict access to statistics. Possible values:
|
$ANALYZER_PASSWD | Password to access statistics |
Additional features | |
$AUTOSUBDOMAIN | Auto-subdomain type. Possible values:
|
$PHP | Allow processing of PHP scripts. Possible values:
|
$PHP_MODE | PHP mode |
$PHP_NATIVE_VERSION | PHP version |
Apache variables
Name | Description |
---|---|
$LISTEN_ON | IP-address and port to listen |
$APACHEITK | Apache ITK is used as web-server. Possible values:
|
$CGI | Allow CGI-scripts. Possible values:
|
$CGI_EXT | Additional extensions of files of CGI-scripts |
$CGI_EXT_PATH | A path to the cgi-bin directory |
$INCLUDE | A path to the configuration file of WWW-domain's user resourcesThis variable is set for ISPmanager Business |
$INCLUDE_PHP | A path to the configuration file of WWW-domain's user resources (for PHP as Apache)This variable is set for ISPmanager Business |
Nginx variables
Name | Description |
---|---|
$NGINX_LISTEN_ON | IP-addresses and port to listen |
$NO_TRAFF_COUNT | Traffic statistics. Possible values
|
$AUTOSUBDOMAIN_SUBDOMAIN_PART | Domain's root directory |
$USER_NGINX_RESOURCES_PATH | A path to the configuration file of WWW-domain's user resources (for PHP as Apache)This variable is set for ISPmanager Business |
$NGINX_VHOST_INCLUDES | A path to Nginx service settings |
$SRV_GZIP | Allow compression. Possible values:
|
$GZIP_LEVEL | Compression level |
$SRV_CACHE | Allow caching. Possible values:
|
$EXPIRES_VALUE | Caching period |
$WEBSTAT_LOCATION | Location of statistics directory |
$WEBSTAT_ENCODING | Statistics encoding |
$REDIRECT_TO_APACHE | Redirect request to Apache. Possible values:
|
$BACKEND_BIND_URI | Address and port that Apache listens |
$REDIRECT_TO_PHPFPM | PHP as FastCGI (Nginx + PHP-FPM). Possible values:
|
$PHPFPM_USER_SOCKET_PATH | A path to the unix socketValue is set, if the "PHP as FastCGI (Nginx + PHP-FPM)" is used |
$DDOSSHIELD | Enable DDoS protection. Possible values:
|
$NGINX_LIMITREQUEST | Requests per second |
$NGINX_BURSTREQUEST | Maximum peak attack size |
$SSL_CRT_BUNDLE_PATH | Path to the file with SSL-certificate and bundle |
THIS_BLOCK_FOR_REMOVE_EXPIRES | An auxiliary parameter. Used to remove all data caching directive when using PHP-FPM. For configuration files created in ISPmanager version earlier than 5.171.0. |
Error pages
Name | Description |
---|---|
$NAME | WWW-domain names |
$ALIASES | WWW-domain aliases |
$OWNER | WWW-domain owner |
$LISTEN_ON | IP address and port to listen |
$SSL | WWW-domain uses secure connection. Possible values:
|
$LISTEN_ON_SSL | IP address and port to listen, and secure connection port |
$ERROR | Possible values:
|
$CODE | Error code that will be associated with a page URI |
$URI | Page that will open in case of error |
Redirects
Name | Description |
---|---|
$NAME | WWW-domain name |
$ALIASES | WWW-domain alias |
$OWNER | WWW-domain owner |
$LISTEN_ON | IP address and port |
$SSL | WWW-domain uses secure connection. Possible values:
|
$LISTEN_ON_SSL | IP address and port of the secure connection |
$REDIRECT | Possible values:
|
$PATH | Relative path that will be redirected to another URL |
$URL | Redirect to this URL |
$FLAG | Stop processing directives. Possible values:
|
Access
Name | Description |
---|---|
$NAME | WWW-domain name |
$ALIASES | WWW-domain alias |
$OWNER | WWW-domain owner |
$SSL | WWW-domain uses secure connection. Possible values:
|
$LOCATION_PATH | Relative path to the directory that will be password protected |
$ACCESS | Possible values:
|
$AUTH_FILE | File with usernames and their passwords |
$AUTH_REALM | Name of the login windowParameter is set only when handling the apache-access.template template |
Parameters on your server may vary depending on applications, plug-ins, etc that you use. A current set of parameters of the function that you call, can be found in the /usr/local/mgr5/var/ispmgr.log log file. Function call is shown in green. You can also view parameters that were passed, in the console of your web-browser after the form is sent to server.
Example
Let's consider a situation when we need to generate different parameters of the configuration files depending on account template type that was used for user creation. In our example, we will use only two types of user templates: for CMS «1C-Bitrix» and web-framework «Django». First, we need to create user templates. Log in to ISPmanager Lite-- "Settings" -- "Templates", and create a new template named «Bitrix». You can enter any values in the «Limits» tab. In the «Access» tab select the Can use PHP as Apache checkbox, domain encoding - UTF-8, and PHP mode - Apache. Create a template for Django. Name - Django, enter any limits and access permissions, "Default values" - set the same values as in your previous template.
If you want to manage your site with «1C-Bitrix», in the apache2-vhost.template template you need to define additional parameters. If you want to use Django, you need to install the «mod_wsgi» module for Apache. If you run Debian, execute the command to install the module:
# apt-get install libapache2-mod-wsgi
If you run CentOS, execute the command:
# yum install mod_wsgi
In order to handle requests, we will need a web-interface for the «mod_wsgi» module. A source code of the interface can be found on the Internet in topics related to «Django». In our example, we will define only the interface name — django.wsgi that you should put to the WWW-domain root directory.
Create a configuration file template. Copy the /usr/local/mgr5/etc/templates/default/apache2-vhosts.template template into the /usr/local/mgr5/etc/templates/ directory, as described in General principles, and add parameters at the end of
{% if $USER_PRESET == Bitrix %}
php_admin_value mbstring.func_overload 2
php_admin_value mbstring.internal_encoding UTF-8
php_admin_value opcache.revalidate_freq 0
php_admin_value display_errors on
{% elif $USER_PRESET == Django %}
WSGIScriptAlias / {% $DOCROOT %}/django.wsgi
WSGIDaemonProcess [% $NAME %] processes=2 maximum-requests=5 threads=1
WSGIProcessGroup {% $NAME %}
{% endif %}
VirtualHost template will look like this:
<VirtualHost {% $LISTEN_ON %}>
ServerName {% $NAME %}
ServerAlias {% $ALIASES %}
DocumentRoot {% $DOCROOT %}
ServerAdmin {% $EMAIL %}
DirectoryIndex {% $DIRINDEX %}
AddDefaultCharset {% $CHARSET %}
{% if $APACHEITK == on %}
AssignUserID {% $OWNER %} {% $OWNER_GROUP %}
{% else %}
SuexecUserGroup {% $OWNER %} {% $OWNER_GROUP %}
{% endif %}
{% if $LOG_ACCESS == on %}
CustomLog {% $ACCESS_LOG_PATH %} combined
{% else %}
CustomLog /dev/null combined
{% endif %}
{% if $LOG_ERROR == on %}
ErrorLog {% $ERROR_LOG_PATH %}
{% else %}
ErrorLog /dev/null
{% endif %}
{% if $CGI == on %}
ScriptAlias /cgi-bin/ {% $CGI_EXT_PATH %}
{% endif %}
{% if $INCLUDE %}
Include {% $INCLUDE %}
{% endif %}
{% if $PHP == on and $FILES_MATCH == on %}
<FilesMatch "\.ph(p[3-5]?|tml)$">
SetHandler {% $PHP_HANDLER %}
{% if $APACHE_FCGID == on %}
FCGIWrapper {% $PHP_BIN_WRAPPER %}
Options ExecCGI
{% endif %}
</FilesMatch>
{% endif %}
{% if $PHP_MODE == php_mode_mod %}
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
{% if $INCLUDE_PHP %}
Include {% $INCLUDE_PHP %}
{% endif %}
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f {% $EMAIL %}"
php_admin_value upload_tmp_dir "{% $MOD_TMP_PATH %}"
php_admin_value session.save_path "{% $MOD_TMP_PATH %}"
{% if $OPEN_BASEDIR != / %}
php_admin_value open_basedir "{% $OPEN_BASEDIR %}"
{% endif %}
{% elif $PHP_MODE == php_mode_cgi %}
ScriptAlias /php-bin/ {% $PHP_BIN_DIR %}
AddHandler application/x-httpd-php5 .php .php3 .php4 .php5 .phtml
Action application/x-httpd-php5 /php-bin/php
{% elif $PHP_MODE == php_mode_fcgi_apache and $APACHE_FCGID != on %}
AddType application/x-httpd-fastphp .php .php3 .php4 .php5 .phtml
Alias /php-fcgi/ {% $PHP_BIN_DIR %}
{% endif %}
{% if $VIRTUAL_DOCROOT == on %}
VirtualDocumentRoot {% $VIRTUAL_DOCROOT_PATH %}
{% endif %}
{% if $USER_PRESET == Bitrix %}
php_admin_value mbstring.func_overload 2
php_admin_value mbstring.internal_encoding UTF-8
php_admin_value opcache.revalidate_freq 0
php_admin_value display_errors on
{% elif $USER_PRESET == Django %}
WSGIScriptAlias / {% $DOCROOT %}/django.wsgi
WSGIDaemonProcess [% $NAME %] processes=2 maximum-requests=5 threads=1
WSGIProcessGroup {% $NAME %}
{% endif %}
</VirtualHost>
When creating a WWW-domain, depending on a user template that was used for user creation, configuration data will be generated for «1C-Bitrix» or «Django».