Installation
RHEL/CentOS
# vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
Now you can install the service and configure it to start at boot.
# yum install nginx
For RHEL 6
# chkconfig nginx on; service nginx start
For RHEL 7
# systemctl enable nginx; systemctl start nginx
Ubuntu/Debian
# curl -s https://nginx.org/keys/nginx_signing.key | apt-key add
Create a sources file for the respective OS using the name and codename, update the package lists and then proceed with the installation. Note that on these systems the service will be started after installation and be automatically configured to start upon boot. This is using the stable repository, as there is another one called mainline.
# echo “deb http://nginx.org/packages/debian/ $(lsb_release -sc) nginx” >> /etc/apt/sources.list
# echo “deb-src http://nginx.org/packages/debian/ $(lsb_release -sc) nginx” >> /etc/apt/sources.list
## OR
# echo “deb http://nginx.org/packages/ubuntu/ $(lsb_release -sc) nginx” >> /etc/apt/sources.list
# echo “deb-src http://nginx.org/packages/ubuntu/ $(lsb_release -sc) nginx” >> /etc/apt/sources.list
# apt-get update; apt-get install nginx
Patching
Patching is handled via the servers package manager using the respective commands so long as a newer version is available upstream.
# yum update nginx
OR
# apt-get update; apt-get upgrade nginx
Configuration
Web Server
The main configuration file is /etc/nginx/nginx.conf and controls the daemon and other global level directives. nginx refers to site configurations as server blocks instead of virtual hosts (apache). They function is the same but how they are defined and referred to is different.
Nginx is often compared to how Apache’s event MPM works, but is fundamentally different in how it deals with threads. Nginx does not create threads for each connection it serves, instead a single worker can handle many 100s of connections and switch to them when they are ready for IO (avoiding a context-switch to a new thread). The maximum effective number of workers is equal to the CPU count (the idea being that each process will be able to run concurrently across each CPU).
In the below snippet, the worker_processes is hardset at 1 and the worker_connections is set at 1024 (connections that each worker can handle) worker_processes can also be set as auto which will use the CPU core count as its value. On a system that is loaded with other processes (eg. PHP-FPM or MySQL) there might be benefit in reducing the worker_processes to accommodate the fact that not all can be active at once.
For more information on some of these options check out the following pages:
- Nginx Performance Tuning#GzipCompression
- Nginx Performance Tuning#Keepalive
- Nginx Performance Tuning#sendfile
/etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
## Turning off server_tokens prevent the version number of nginx from being displayed to clients.
server_tokens off;
## As an example these settings will be inherited by any vhost which does not have a matching directive.
## WARNING: The settings below are very restrictive and legacy clients will not be able to connect! They
are provided as an
## example on how values are inherited.
## You could also put them in a file at /etc/nginx/conf.d/ssl.conf which would be included later in this
file
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers “EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH”;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
add_header Strict-Transport-Security “max-age=63072000; includeSubdomains; preload”;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
sendfile on;
#tcp_nopush on;
keepalive_timeout 30;
## This can vary if you wish to read virtual host files from additional directories.
include /etc/nginx/conf.d/*.conf;
}
Server Blocks (Virtual Hosts)
Server Blocks(Virtual hosts as known in Apache httpd) as are referred in nginx are configured in with the best practice to name the /etc/nginx/conf.d file “example.com.conf” with “example.com” replaced with your own domain. If the file does not end in .conf it is not read by nginx, a common practice is to append .disabled to the end of any vhost you do not want served, but to keep the VHost for. nginx natively supports SNI so multiple IPs are NOT
needed, simply specify the certificate files in each Server block and have it listen on 443.
When configuring redirects between domains, or HTTP HTTPS, the preferred/recommended solution is to create a server block for that ONLY specific domain you are redirecting from. Using blocks in nginx is bad practice, differing from the Apache paradigms which make use of both if if and RewriteRules everywhere. See of how to, and how to do redirects (converting from Apache style the nginx documentation for examples NOT configs)
Server block files can use an include line to utilize shared configurations between sites to avoid duplicated lines in various configuration files. nginx.conf.
There is not a separate ssl.conf like in Apache. If you want all options to be shared between sites, simply place the directives in the http section of the nginx.conf.
Below is an example virtual host file which shows both HTTP and HTTPS examples. These do not have to be in the same file, but it is recommended for readability.
server {
listen 80;
# listen ip_address:80;
server_name example.com www.example.com;
root /var/www/vhosts/example.com;
index index.html;
location /admin {
allow X.X.X.X;
deny all;
}
access_log /var/log/nginx/example.com_access.log main;
error_log /var/log/nginx/example.com_error.log;
}
server {
listen 443;
# listen ip_address:443;
server_name example.com www.example.com;
root /var/www/vhosts/example.com;
index index.html;
ssl on;
ssl_certificate /etc/nginx/ssl/2011-example.com.crt;
ssl_certificate_key /etc/nginx/ssl/2011-example.com.key;
ssl_session_timeout 5m;
# The following should not be used, but is provided as an example only.
#ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
location /admin {
allow X.X.X.X;
deny all;
}
access_log /var/log/nginx/example.com_ssl_access.log main;
error_log /var/log/nginx/example.com_ssl_error.log;
}
Example Redirects
Redirects are specified in the server block of the virtual host file itself as nginx does not have a concept of .htaccess files. Avoid using directives with domain level redirects, instead where possible put them in a server block by themselves. This means you’ll often end up with 3 for each site:
80: HTTP HTTPS
443: non-www www
443: www hosting actual site/PHP
Further to this, try and avoid using the rewrite syntax where possible, instead using the simpler return syntax. A rewrite should be used when regex is needed (eg. to extract data nginx does not normally put in a variable) or if you want nginx to continue processing the request vs returning a redirect code.
BAD / Apache style
# DO NOT DO THIS
# Instead use separate server blocks
server_name example.com www.example.com;
if ($http_host = example.org) {
rewrite (.*) http://www.example.org$1; # DO NOT DO THIS
}
# ALSO DO NOT DO THIS
if ($http_host != www.example.org) {
rewrite (.*) http://www.example.org$1; # DO NOT DO THIS
}
non-www to www
#
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
http to https
# Redirect HTTP requests to HTTPS (with www)
server {
listen 80 default_server;
server_name www.example.com example.com;
return 301 https://www.example.com$request_uri;
}
# Catchall – redirect all requests with unknown Host to HTTPS version of Host
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
For additional information on redirects and rewrites please see the official nginx documentation here: https://www.nginx.com/blog/creating-nginx rewrite-rules/
Reverse Proxy Example
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://10.0.0.6;
proxy_read_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Training
Paul Durivage wrote an excellent intro to nginx class in mid-2013 which is hosted here: nginx Training Outline
References
https://nginx.org/
https://nginx.org/en/linux_packages.html
http://wiki.nginx.org/Main
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy