Website¶
Our website module provides everything you need, to manage, deploy and run your website. It is type and environment based which means you have to select a particular type (e.g. typo3cms) and environment (e.g. PROD). According those settings, our automation will setup the server/vhost as required.
By adding a website, the following parts are created on the server:
system user and group
home directory (/home/username/)
directory for temporary files (/home/username/tmp/)
directory for log files (/home/username/log/)
directory for additional configuration files (/home/username/cnf/)
directory for backups (used for database dumps, /home/username/backup/)
environment variables for bash and zsh (~/.profile and ~/.zprofile)
SSH authorised keys
webserver vhost configuration (for custom configurations, see Custom configuration)
Types¶
You have to define one of the following types for each website.
Note
If you need a type not mentioned here yet, do not hesitate to contact us
typo3cmsv10¶
Web server |
nginx with ModSecurity WAF, core rule set and TYPO3 10.x compatible white/blacklists |
runtime environment |
PHP 7.2 |
Database |
MySQL (MariaDB 10.x ) with database, user, and grants |
Default webroot |
~/web |
PHP and nginx settings adjusted to TYPO3 10 requirements
latest TYPO3 CMS 10 LTS cloned into
/opt/typo3/TYPO3\_10/
PHP and nginx settings adjusted to TYPO3 10 requirements
TYPO3 application context can be set by setting the
TYPO3_CONTEXT
environment variable in custom JSON, see Environment Variables for detailsTYPO3 Scheduler executed every 5 minutes
Warning
EOL Mismatch: This server generation is end of life before TYPO3. We recommend a newer managed server.
typo3cmsv9¶
Web server |
nginx with ModSecurity WAF, core rule set and TYPO3 9.x compatible white/blacklists |
runtime environment |
PHP 7.2 |
Database |
MySQL (MariaDB 10.x ) with database, user, and grants |
Default webroot |
~/web |
PHP and nginx settings adjusted to TYPO3 9 requirements
latest TYPO3 CMS 9 LTS cloned into
/opt/typo3/TYPO3\_9/
PHP and nginx settings adjusted to TYPO3 9 requirements
TYPO3 application context can be set by setting the
TYPO3_CONTEXT
environment variable in custom JSON, see Environment Variables for detailsTYPO3 Scheduler executed every 5 minutes
typo3cmsv8¶
Web server |
nginx with ModSecurity WAF, core rule set and TYPO3 8.x compatible white/blacklists |
runtime environment |
PHP 7.2 |
Database |
MySQL (MariaDB 10.x ) with database, user, and grants |
Default webroot |
~/web |
PHP and nginx settings adjusted to TYPO3 8 requirements
latest TYPO3 CMS 8 LTS cloned into
/opt/typo3/TYPO3\_8/
TYPO3 application context can be set by setting the
TYPO3_CONTEXT
environment variable in custom JSON, see Environment Variables for detailsTYPO3 Scheduler executed every 5 minutes
typo3cmsv7¶
Web server |
nginx with ModSecurity WAF, core rule set and TYPO3 7.x compatible white/blacklists |
runtime environment |
PHP 7.2 |
Database |
MySQL (MariaDB 10.x ) with database, user, and grants |
Default webroot |
~/web |
PHP and nginx settings adjusted to TYPO3 7 requirements
latest TYPO3 CMS 7 LTS cloned into
/opt/typo3/TYPO3\_7/
TYPO3 application context can be set by setting the
TYPO3_CONTEXT
environment variable in custom JSON, see Environment Variables for detailsTYPO3 Scheduler executed every 5 minutes
neos¶
Web server |
nginx with ModSecurity WAF, core rule set and Neos compatible white/blacklists |
runtime environment |
PHP 7.2 |
Database |
MySQL (MariaDB 10.x ) with database, user, and grants |
Default webroot |
~/web |
PHP and nginx settings adjusted to Neos requirements
FLOW_CONTEXT
set according the selected environment (see Environments)FLOW_REWRITEURLS
enabled
required configuration¶
Warning
our approach to dynamically configure PHP is not compatible with Neos by default
As a workaround, we have to let know Neos about the environment variable
required to load the appropriate PHP settings, by defining the the
PHP_INI_SCAN_DIR
environment variable in Configuration/Settings.yaml
:
Neos:
Flow:
core:
subRequestEnvironmentVariables:
PHP_INI_SCAN_DIR: '/etc/php72/user/<username>/:/home/<username>/cnf/'
Hint
see this Neos Discuss thread for technical details
magento2¶
Web server |
nginx with ModSecurity WAF, core rule set and Magento 2 compatible white/blacklists |
runtime environment |
PHP 7.1 |
Database |
MySQL (MariaDB 10.x ) with database, user, and grants |
Default webroot |
~/pub |
PHP and nginx settings adjusted to Magento 2 requirements
Magento 2 cronjobs running every minute
wordpress¶
Web server |
nginx with ModSecurity WAF, core rule set and Wordpress compatible white/blacklists |
runtime environment |
PHP 7.2 |
Database |
MySQL (MariaDB 10.x ) with database, user, and grants |
Default webroot |
~/www |
PHP and nginx settings adjusted to WordPress requirements
WP-CLI installed and available by using the
wp
commandwp-cron.php is called every 5 minutes over CLI
We have a request limit for
wp-login.php
andxmlrpc.php
in place. For both options, our default limit is set to 10 request per minuteYou can override our defaults inside the Website custom JSON as shown in the exmaple below:
{ "wordpress_limit_login": "20r/m", "wordpress_limit_xmlrpc": false, }
Request limit for
wp-login.php
is set to 20 requests per minuteRequest limit for
xmlrpc.php
is disabled
Hint
Please disable the built in HTTP call to wp-cron.php by setting define('DISABLE_WP_CRON', true);
. This additional call is not necessary and disabling it will lower the load on your system.
php72¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
PHP 7.2 |
Database |
Optional: MySQL, MongoDB or PostgreSQL |
Default webroot |
~/www |
php71¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
PHP 7.1 |
Database |
Optional: MySQL, MongoDB or PostgreSQL |
Default webroot |
~/www |
html¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
for static content only |
Database |
unavailable |
Default webroot |
~/www |
uwsgi¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
uWSGI Daemon, Python virtualenv |
Database |
Optional: MySQL, MongoDB or PostgreSQL |
Default webroot |
~/www |
uWSGI Daemon (Symlink your appropriate wsgi configuration to
~/wsgi.py
)Python virtualenv
venv-<sitename>
configured within uWSGI and the user login shellall requests are redirected to the uWSGI daemon by default. To serve static files, add appropriate locations to the Custom configuration like this:
location /static/ { root /home/user/application/; }
Hint
to control the uwsgi daemon, use the uwsgi-reload
and uwsgi-restart
shortcuts
redirect¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
for redirects only |
Database |
unavailable |
Default webroot |
unavailable |
redirects everything to a custom target
by default, we send a 307 HTTP code. To use your own code, add the
target_code
parameter to the websites custom JSON:{ "target_code": "301" }
Hint
you can use any nginx variable as target (for example $scheme://www.example.com$request_uri
), see the nginx Documentation for available variables
proxy¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
for reverse proxy only |
Database |
unavailable |
Default webroot |
unavailable |
nginx vhost configured as reverse proxy
Hint
to use advanced features or multiple backends, create your own upstream configuration in /etc/nginx/custom/http.conf
and point proxy_pass
to it. For security reasons, we only allow access to this configuration for the devop user.
docker¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
own container with docker |
Database |
Optional: MySQL, MongoDB or PostgreSQL |
Default webroot |
unavailable |
nginx vhost configured as reverse proxy
install docker and puts the user into the docker group
Hint
to use advanced features or multiple backends, create your own upstream configuration in /etc/nginx/custom/http.conf
and point proxy_pass
to it. For security reasons, we only allow access to this configuration for the devop user.
Warning
To persist data in docker containers use volumes instead of bind mounts, due to permission conflicts.
nodejs¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
nodejs daemon, controlled by monit |
Database |
Optional: MySQL, MongoDB or PostgreSQL |
Default webroot |
socket: ~/cnf/nodejs.sock |
select custom node version trough nvm, by default, the latest node lts version is installed
symlink your app.js to
~/app.js
or overwrite path or other daemon options inOPTIONS
at~/cnf/nodejs-daemon
:OPTIONS="/home/nodejs/application/app.js --prod"
nodejs has to listen on the
~/cnf/nodejs.sock
socket, permission660
all requests are redirected to the nodejs daemon by default. To serve static files, add appropriate locations to the Custom configuration like this:
location /static/ { root /home/user/application/; include /etc/nginx/custom/security.conf; }
Hint
to control the nodejs daemon, use the nodejs-restart
shortcut
ruby¶
Web server |
nginx with ModSecurity WAF and core rule set |
runtime environment |
ruby rbenv and foreman daemon |
Database |
Optional: MySQL, MongoDB or PostgreSQL |
Default webroot |
socket: |
ruby rbenv configured within foreman and the user login shell
foreman daemon, controlled by monit
symlink your Procfile to
~/
or overwrite path or other daemon options inOPTIONS
at~/cnf/ruby-daemon
:OPTIONS="start web -f project/Procfile"
ruby has to listen on the
~/cnf/ruby.sock
socket, permission660
all requests are redirected to the ruby daemon by default. To serve static files, add appropriate locations to the Custom configuration like this:
location /static/ { root /home/user/application/; }
Hint
to control the ruby daemon, use the ruby-start
/ ruby-stop
/ ruby-restart
shortcuts
Environments¶
You have to select one of those environments for each website:
PROD¶
for live sites
no access protection
phpinfo disabled (visible database credentials from environment variables)
E-Mails get sent to their designated recipient (PHP mail() only, see E-Mail Handling for details)
Hint
You can enable phpinfo by setting disable_functions=
to a empty string in ~/cnf/php.ini
(don’t forget php-reload
). Important: phpinfo exposed many infos like environment variables such as database credentials. We recommend not to use phpinfo on a publicly accessible website. Please be careful and deactivate phpinfo afterwards.
STAGE¶
for stage / preview / testing access
password protected (User “preview”, password from “preview_htpasswd” option)
phpinfo enabled
E-Mails get saved as file into the ~/tmp/ directory (PHP mail() only, E-Mail Handling for details)
DEV¶
for development
password protected (User “preview”, password from “preview_htpasswd” option)
phpinfo enabled
Xdebug enabled, see PHP debugging for details)
E-Mails get saved as file into the ~/tmp/ directory (PHP mail() only, E-Mail Handling for details)
User Handling¶
The preview user gets applied to all non PROD environments and is intended for your own use, but also to allow access to other parties like your customer. Use the “Preview password” option to set a particular password to the preview user. You have to use a htpasswd encrypted value which you can generate like this on your local workstation:
htpasswd -n preview
Furthermore, you can add additional users trough the “website::users” configuration like this:
{
"website::users": {
"alice": {
"preview": "$apr1$RXDs3l18$w0VJrVN5uoU6DMY.0xgTr/"
},
"bob": {
"preview": "$apr1$RSDdas2323$23case23DCDMY.0xgTr/"
}
}
}
You can add such uers for yourself and your co-workers. If you work on multiple websites, you do not have to look up the corresponding password all the time but just use the global one.
To rename the default “preview” username, use the preview_username
parameter on a website:
{
"preview_username": "showme",
}
Furthermore, its possible to set the preview username globally through website::preview_username
.
Note
Please keep in mind that this password gets often transfered over unencrypted connections. As always, we recommend to use a particular password for only this purpose
Disable exceptions¶
Never show detailed application based exeptions on PROD, to avoid information leakage. Disable the output directly in your application. For example in TYPO3:
$TYPO3_CONF_VARS['SYS']['displayErrors'] = '0';
Default Environment Variables¶
For each website, the following environment variables are created by default, and are available within the shell and also the webserver.
SITE_ENV (DEV, STAGE or PROD)
DB_HOST (Database hostname, only if there is a database)
DB_NAME (Database name, only if there is a database)
DB_USERNAME (Database username, only if there is a database)
DB_PASSWORD (Database password, only if there is a database)
PROXY_PASS (Proxy Pass, only for type proxy)
Hint
to use the .profile environmet within a cronjob, prepend the following code to your command: /bin/bash -c 'source $HOME/.profile; ~/original/command'
Example usage in PHP¶
As soon there is a database installed, the following variables are added to the environment and can be used from within your application. TYPO3 Example:
$typo_db_username = $_SERVER['DB_USERNAME'];
$typo_db_password = $_SERVER['DB_PASSWORD'];
$typo_db_host = $_SERVER['DB_HOST'];
$typo_db = $_SERVER['DB_NAME'];
Additionaly, you can use the “SITE_ENV” variable to set parameters according the current environment:
switch ($_SERVER['SITE_ENV']) {
case 'DEV':
$recipient = 'dev@example.net';
break;
case 'STAGE':
$recipient = 'dev@example.net';
break;
case 'PROD':
$recipient = 'customer@example.com';
break;
}
If you configure your application like this, you can copy all data between different servers or vhosts (DEV/STAGE/PROD) and all settings are applied as desired.
Example usage in typoscript¶
[globalString = _SERVER|SITE_ENV = DEV]
# doSometing
[global]
TLS Certificates¶
By adding a TLS certificate to your website, the following configurations/features are applied to the vhost:
SPDY 3.1
TLS 1.0, 1.1, 1.2
SNI
HSTS
daily Expiration Date Check
global HTTP to HTTPS redirect
Let’s Encrypt¶
We support free tls certificates by Let’s Encrypt. You can activate Letsencrypt for your website in the cockpit. The certificates are automatically renewed 30 days before expiration.
Debug validation problems¶
In order to debug validation issues, we introduced the letsencrypt-renew
shortcut which will trigger a run of our Let’s Encrypt client, and let you see all debug output to identifiy possible problems.
Make sure that all hosts added to
Server name
point to the correct server (A and AAAA DNS records).Let’s Encrypt will try to reach your website at the endpoint
/.well-known/acme-challenge/
for validation purposes. Make sure that you do not overwrite this path within your own nginx configuration.You can check access to the validation directory by yourself by fetching the control file reachable at
http://example.com/.well-known/acme-challenge/monitoring
Renewal¶
Certificates from Let’s Encrypt will be valid for 90 days. They are renewed automatically as soon as they expire in under 30 days. You can follow these checks and renewals by grep for letsencrypt
in /var/log/syslog
.
Furthermore, we check all certificates from our monitoring and will contact you if there are certificates expiring in less than 21 days.
Export¶
Existing Lets Encrypt certificates can be read with the devop user. This is useful if you want to temporarily use the old certificate on a new server (e.g. for a migration).
You can find your certificates under /etc/nginx/ssl
.
Warning
As soon as the certificates leave our servers, we no longer have control over them. Please be aware of this and be careful.
Order certificate¶
Requirements¶
To validate domain ownership, our certificate issuer will send a E-Mail to one of the following addresses:
Create certificate and key¶
$ openssl req -newkey rsa:4096 -x509 -nodes -days 3650 -out www.example.net.crt -keyout www.example.net.key
Country Name (2 letter code) [AU]:CH
State or Province Name (full name) [Some-State]:Luzern
Locality Name (eg, city) []:Luzern
Organization Name (eg, company) [Internet Widgits Pty Ltd]:example Ltd
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:www.example.net
Email Address []:webmaster@example.net
Extract certificate signing request¶
openssl x509 -x509toreq -signkey www.example.net.key -in www.example.net.crt
Submit this CSR to us for further processing, or order certificate by yourself from the issuer of your choice.
Configure website¶
SSL key: generated private key
SSL key: signed certificate, including appropriate intermediate certificates
Warning: Make sure the first Server name
used is valid within your
certificate as we redirect all HTTP requests within this vHost to
https://first-in-server_name
HTTP redirect¶
By default, all HTTP requests within a given vHost are redirected to HTTPS keeping the hostname supplied by the client. If you want to change this behaviour somehow, for example by always redirect to the first hostname of the vhost, you can set http_redirect_dest
to another value like https://$server_name$request_uri
.
Furthermore, its possible to set the redirect destination globally through website::http_redirect_dest
which will be used on all HTTP redirects without a explicitly set http_redirect_dest
.
~/cnf/nginx-redirect.conf¶
Included within the server block of each HTTP to HTTPS redirect. You can use this file to configure specific redirect rules and settings.
Cipher Suite¶
You can configure a desired cipher suite configuration trough website::ssl_ciphers:
{
"website::ssl_ciphers": "desired-cipher-suites"
}
Warning
We configure and update this value with sane defaults. Overwrite only when really required, and if you are aware of the consequences.
Diffie-Hellman parameters¶
Diffie-Hellman parameters are used for perfect forward secrecy. We supply default Diffie-Hellman parameters and update them on a regular schedule. If you want to use your own Diffie-Hellman parameters, you can generate them:
openssl dhparam -out /tmp/dhparam.pem 4096
and configure them trough website::ssl_dhparam:
{
"website::ssl_dhparam": "-----BEGIN DH PARAMETERS-----\nMIICCAKCAgEAoOePp+Uv2M34IA+basW9CBHp/jsZihB3FI8KVRLVFJPIUJ9Llm8F\n...\n-----END DH PARAMETERS-----"
}
HSTS Header¶
By default, we add a HTTP Strict Transport Security (HSTS) header to each TLS enabled website:
Strict-Transport-Security max-age=63072000;
Use the header_hsts parameter to override the default HSTS header:
{
"header_hsts": "max-age=3600; includeSubDomains; preload"
}
Web Application Firewall¶
We use ModSecurity as additional protection against application level attacks such as cross site-scripting or SQL injections. By default, the core rules set will be loaded, and we block common vulnerabilities and zero day attacks by adding some more global rules.
Warning
this is just a additional security measure. Regardless its existence, remember to keep your application, extensions and libraries secure and up to date
Hint
keep up to date with changes by subscribing to our status uppdates at opsstatus.ch
Identify blocks¶
nginx error log¶
If a request is blocked, the server will issue a 403 forbidden error. There are detailed informations available in the error log file:
YYYY/MM/DD HH:MM:SS [error] 171896#0: *29428 [client 2a04:500::1] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/etc/nginx/modsecurity/crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "2a04:500::1"] [uri "/"] [unique_id "154850909196.529239"] [ref ""], client: 2a04:500::1, server: example.net, request: "GET /?union%20select=%22waf%20demo HTTP/2.0", host: "example.net"
Hint
for details, see the ModSecurity documentation
modsecurity audit log¶
More detailed informations including a full dump of the request and response can be obtained from the audit log file.
You’ll find this at /var/log/nginx/modsecurity.log
.
Hint
you cannot read /var/log/
from within the web applications context for security reasons, please use the generic devop
account to take a look at them
custom WAF configuration¶
The rules added from the core rules set and the custom rules added by us are there for a reason.
If you trigger a false positive, you should think about changing your application first of all.
As this is not always possible or feasible, you can disable certain rules or even the whole WAF
through the local nginx configuration located in ~/cnf/nginx.conf
:
# disable blocking triggered requests but still detect and log them
modsecurity_rules 'SecRuleEngine DetectionOnly';
# disable WAF alltogether
modsecurity_rules 'SecRuleEngine Off';
# disable certain rule
modsecurity_rules 'SecRuleRemoveById 90001';
# add custom rule
modsecurity_rules 'SecRule "ARGS_NAMES|ARGS" "@contains blocked-value" "deny,msg:blocled,id:91001,chain"'
Hint
to apply the changes reload the nginx configuration with the nginx-reload
shortcut
Hint
for details, see the ModSecurity documentation
Request limits¶
The number of connections and requests are limited to ensure that a single user (or bot) cannot overload the whole server.
Limits¶
50 connections / address
50 requests / second / address
150 requests / second (burst)
>150 requests / second / address (access limited)
With this configuration, a particular visitor can open up to 50 concurrent connections and issue up to 50 requests / second.
If the visitor issues more than 50 request / second, those requests are delayed and other clients are served first.
If the visitor issues more than 150 request / second, those requests will not processed anymore, but answered with the 503 status code.
Adjust limits¶
To adjust this limits (e.g. for special applications such as API calls,
etc), set a higher “load zone” in your local configuration
(~/cnf/nginx.conf
):
# connection limits (e.g. 75 connections)
limit_conn addr 75;
# limit requests / second: (small, medium, large)
limit_req zone=medium burst=500;
limit_req zone=large burst=1500;
Hint
to apply the changes reload the nginx configuration with the nginx-reload
shortcut
Zones¶
small = 50 requests / second (burst: 150req/sec)
medium = 150 requests / second (burst: 500 req/sec)
large = 500 requests / second (burst: 1500 req/sec)
Note: the default zone is “small” and will fit most use cases
Warning
in SPDY, each concurrent request is considered a separate connection
Hint
for Details, see the Module ngx_http_limit_req_module documentation
Custom configuration¶
nginx¶
You can add specific configurations like redirects or headers within the
~/cnf/
directory.
Warning
You have to reload nginx after changes with the nginx-reload
shortcut
~/cnf/nginx.conf¶
Included within the server block and used to configure specific redirects, enable gzip and other stuff directly in the nginx.conf.
if ($http_host = www.example.net) {
rewrite (.*) http://www.example.com;
}
or you can password protect a subdirectory:
location ~* "^/example/" {
auth_basic "Example name";
auth_basic_user_file /home/user/www/example/.htpasswd;
root /home/user/www/;
}
or add a IP protection:
allow <your-address>;
allow 2a04:503:0:102::2:4;
allow 91.199.98.23;
deny all;
Hint
Always allow access from 91.199.98.23 and 2a04:503:0:102::2:4 (monitoring)
or add custom MIME types:
include mime.types;
types {
text/cache-manifest appcache;
}
if you like to run PHP in this subdirectory, don’t forget to add this nested in the location section from the example on top:
location ~ \.php {
try_files /dummy/$uri @php;
}
Hint
for Details, see the Server Block Examples and Rewrite Rule documentation
~/cnf/nginx-prod.conf¶
Included within the server block on each website with environment set to PROD. For configuration examples, see the description of ~/cnf/nginx.conf above.
~/cnf/nginx-stage.conf¶
Included within the server block on each website with environment set to STAGE. For configuration examples, see the description of ~/cnf/nginx.conf above.
~/cnf/nginx-dev.conf¶
Included within the server block on each website with environment set to DEV. For configuration examples, see the description of ~/cnf/nginx.conf above.
~/cnf/nginx_waf.conf¶
Configure WAF exeptions here, see Web Application Firewall for details.
/etc/nginx/custom/http.conf¶
This file is directly integrated in http { }
, before server { }
and can only be edited with the devop
user. You can use this file for settings that must be configured at nginx http context.
custom configuration include¶
Include your own, external configuration files within server { }
or http { }
by including the following configuration to your server’s Custom JSON
:
server level: set
nginx::global_config::server_file
http level: set
nginx::global_config::http_file
Warning
if the configured files can not be found, the webserver will not be able to start.
"nginx::global_config::server_file": "/absolut/path/to/your/file.conf"
Hint
with this setting, you can deploy own, system wide configuration files from a Git repository. See Globalrepo Service for details.
custom webroot¶
By default, the webroot directory location is choosen according vendor recommendations, depending on the selected type.
Some deployment workflows require other locations, which you can select through the custom_webroot parameter, relative to the home directory.
Warning
by now, the directory specified here needs to be a real directory (no symlinks allowed)
{
"custom_webroot": "deploy/current/html"
}
custom log format¶
To alter the format used for nginx access logs, for example due to privacy reasons, you can use the website::wrapper::nginx::log_format
configuration.
This configuration is only available globally for all websites on a server, to change to default “combined” format to replace the actual visitors ip address with 127.0.0.1, use the following example:
"website::wrapper::nginx::log_format": "127.0.0.1 - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\""
PHP¶
You can set custom PHP configurations trough the ~/cnf/php.ini
file.
See the PHP Documentation for details.
Warning
You have to reload php after changes with the php-reload
shortcut
memory_limit = 1G
extension = ldap.so
Hint
list available extensions in /opt/php/php72/lib/php/extensions/no-debug-non-zts-20170718/
node¶
Warning
use only to enable node within another website type for actions like gulp. To run your own node based website, use the nodejs type
To execute custom node commands (for example gulp), add nvm (Node Version Manager) to any website by setting the following custom JSON:
{
"nvm": true
}
By default, the latest node lts version will be installed, however you can also install and select any other version.
$ nvm ls-remote
$ nvm install <version>
Hint
see the nvm readme for details
security configuration¶
Access to certain private files and directories like .git
is forbidden by including the global /etc/nginx/custom/security.conf
file within the vhost configuration.
This file also contains the following security headers:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block always";
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
You can disable this include by setting security_conf
to false
within the custom JSON configuration. If you disable this, we recommend to copy the content into your own nginx.conf and adjust it to your own needs (you can view the content with the devop user). Please be aware of any ramifications, and do not disable this
settings unless you absolutely know what you’re doing.
Warning
make sure to deny access to private files and directories manually, or include our global security locations from /etc/nginx/custom/security.conf
within your own configuration.
Cronjobs¶
Add custom cronjobs through the crontab -e command:
SHELL=/usr/local/vzscripts/sfoutputtosyslog
PHP_INI_SCAN_DIR=:/etc/php5/cli/user/<username>/
# +------------------------------------ minute (0 - 59)
# | +---------------------------- hour (0 - 23)
# | | +-------------------- day of month (1 - 31)
# | | | +------------ month (1 - 12)
# | | | | +---- day of week (0 - 6) (Sunday=0 or 7)
# | | | | |
# 10 2 * * * <command>
5 * * * * <path-to-job>
Hint
For PHP based jobs, please set PHP_INI_SCANDIR manually to make sure that user specific settings are respected
Listen¶
By default, nginx will bind to the primary IP address of the eth0 interface and the 80/443 port. You can specify listen options explicitly per website, for example within setups where Varnish is used and the nginx vhost does not have to listen on external interfaces.
{
"website::sites": {
"username": {
"env": "PROD",
"type": "php",
"listen_ip": "127.0.0.1",
"listen_port": "8080",
"listen_options": "option_value",
"ipv6_listen_ip": "::1",
"ipv6_listen_port": "8080",
"ipv6_listen_options": "option_value"
}
}
}
Hint
If you set listen_options
and ipv6_listen_options
to default_server
, the corresponding web page becomes the default server and listens to every server name.
Monitoring¶
All sites with "env": "PROD"
are monitored 24/7 by default. If you
have some sites with frequent outages (e.g. for development purposes),
which have to have "env": "PROD"
for other reasons, or sites which
are not reachable from everywhere due to security reasons, please
deactivate monitoring by setting "monitoring": "false"
in custom JSON:
{
"monitoring": false
}
Environment Variables¶
To set or override environment variables per website, use the envvar
option in custom JSON:
{
"envvar": {
"MYENVVAR": "this is the value",
"DB_HOST": "override global DB_HOST variable here",
"http_proxy": "override global http_proxy variable here"
}
}
White label¶
Default Virtual Host¶
The default vhost is stored in /var/www/
. You can use your own content stored in a git repository with the following configuration.
{
"website::default::webroot::gitsource": "git@git.example.com:acme/project",
"website::default::webroot::gitkey": "-----BEGIN RSA PRIVATE KEY-----[..]-----END RSA PRIVATE KEY-----",
}