For about 10 years
What one could do is just install Nginx from the system packages with yum
however, as I did that the first time I realized that doesn't speed up the website much if at all. What I ended up doing is installing Nginx from source, and that was a bit more tedious than I expected but when it all works, it's worth it!
So, if you aren't root already type in
sudo -i
Update openssl
First we'll want to update openssl (which is needed for Nginx) to the lastest version which unfortunately doesn't come with Centos 7. For that, we basically follow this tutorial
First, we install some packages openssl depends on
yum group install 'Development Tools'
yum install perl-core zlib-devel -y
Now let's go where we'll be installing openssl, download, extract and go into it.
cd /usr/local/src/
wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz
tar -xf openssl-1.1.1d.tar.gz
cd openssl-1.1.1d
Install it (During "make test" a test called enc.t might fail, if it does, no need to panic. It happened to me every time I installed it and all still works fine)
./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib
make
make test
make install
Now according to the source we want to configure shared libraries
cd /etc/ld.so.conf.d/
Now we need to create a file, I like to do that with "vi" or "vim" but "nano" is more intuitive and a better choice if you're not familiar with "vi" or "vim"
nano openssl-1.1.1d.conf
and paste the following in there:
/usr/local/ssl/lib

Exit with Ctrl+x and then I believe it will ask you to save it
Reload the dynamic link
ldconfig -v
Now we configure the openssl binary
Backup the default
mv /bin/openssl /bin/openssl.backup
And let's make the binary
nano /etc/profile.d/openssl.sh
#Set OPENSSL_PATH
OPENSSL_PATH="/usr/local/ssl/bin"
export OPENSSL_PATH
PATH=$PATH:$OPENSSL_PATH
export PATH

Again, exit and save
Make it executable
chmod +x /etc/profile.d/openssl.sh
Reload the openssl environment and check that everything is in place
source /etc/profile.d/openssl.sh
echo $PATH
which openssl
openssl version -a
That last one should show you that you have the version 1.1.1d
Phew, done with the openssl installation. Now take a quick break if you wish, maybe drink some water (I know I will as this post is already getting long).
Install Nginx
Before we get to installing Nginx, let's install all the dependencies
yum install zlib-devel pcre-devel git libxslt-devel gd gd-devel geoip-devel -y
Now let's get the latest Nginx, extract it, and go into it
wget http://nginx.org/download/nginx-1.16.1.tar.gz
tar -xzvf nginx-1.16.1.tar.gz
cd nginx-1.16.1/
Now inside the directory let's get some additional modules we'll need for the caching
git clone https://github.com/openresty/headers-more-nginx-module
git clone https://github.com/FRiCKLE/ngx_cache_purge
And install Nginx
./configure --with-pcre --prefix=/opt/nginx-1.16.1 --user=nginx --group=nginx --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --without-http_charset_module --with-http_perl_module --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --with-openssl=/usr/local/src/openssl-1.1.1d --add-module=./ngx_cache_purge --add-module=./headers-more-nginx-module
Yes, that's a really long line, it tells what modules to add to the Nginx installation
make
make install
Now we have Nginx installed however this doesn't include the system service or the nginx user, so let's add them in
Starting with the service we'll want to create a new file
nano /etc/systemd/system/nginx-1.16.1.service
And put the following inside:
[Unit]
Description=nginx 1.16.1
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/nginx-1.16.1
ExecStart=/opt/nginx-1.16.1/sbin/nginx $CLI_OPTIONS
ExecReload=/opt/nginx-1.16.1/sbin/nginx -s reload
ExecStop=/opt/nginx-1.16.1/sbin/nginx -s quit
[Install]
WantedBy=multi-user.target

Create an environment file for Nginx
nano /etc/sysconfig/nginx-1.16.1
# Command line options to use when starting nginx
#CLI_OPTIONS=""

Add the Nginx user like this:
adduser --system --no-create-home --user-group --shell /bin/false nginx
You can now start the Nginx service:
systemctl start nginx-1.16.1
And make sure it starts on bootup
systemctl enable nginx-1.16.1
One last thing, let's check that it actually runs
systemctl status nginx-1.16.1
Configure php and the websites to work with Nginx
Now we have Nginx installed and running, but that doesn't mean the websites will work with it yet. We still need to tell php so nginx controlls it not apache and configure our websites to work with nginx instead of apache
Let's start with php
nano /etc/php-fpm.d/www.conf
find where it says
user = apache
group = apache
and replace with
user = nginx
group = nginx
Let's restart php for the changes to take effect
systemctl restart php-fpm
Now unlike a standard Nginx installation this one will have everything related to Nginx installed in one place: "/opt/nginx-1.16.1/". There are 2 configs we need to edit purely for Nginx and then configs for however many sites you have on your machine
I'll show you how the configs I have look like. Before modifying whatever you have to look like what I have, please make a backup of it as you never know if you might need to go back to it.
This is the fastcgi config where I added most of the caching settings
nano /opt/nginx-1.16.1/conf/fastcgi.conf
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200; fastcgi_pass_header Set-Cookie; fastcgi_pass_header Cookie; fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_intercept_errors on; include fastcgi_params; fastcgi_no_cache $no_cache; fastcgi_cache_bypass $no_cache; fastcgi_cache drm_custom_cache; fastcgi_cache_key $server_name|$request_uri; fastcgi_cache_valid 404 60m; fastcgi_cache_valid 200 60m; fastcgi_max_temp_file_size 4m; fastcgi_cache_use_stale updating; fastcgi_pass localhost:9000;
The main Nginx config
nano /opt/nginx-1.16.1/conf/nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#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 logs/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
#keepalive_timeout 0;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 9;
gzip_buffers 16 8k;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# skipped comments
location ~* .(ico|jpg|webp|jpeg|gif|css|png|js|ico|bmp|zip|woff)$ {
access_log off;
log_not_found off;
add_header Pragma public;
add_header Cache-Control "public";
expires 14d;
}
location ~* .(php|html)$ {
access_log off;
log_not_found off;
add_header Pragma public;
add_header Cache-Control "public";
expires 14d;
}
}
# skipped comments
include /opt/nginx-1.16.1/conf/conf.d/*;
fastcgi_cache_path /dev/shm/nginx levels=1:2
keys_zone=stupidfast:16m max_size=1024m inactive=60m;
}
Yes I skipped a ton of comments where it says "#skipped comments", but otherwise there would be a whole lot of unnecessary stuff that just clutters the page
And the site config (replace DOMAIN_NAME with your website's domain name like "example.com")
First we need to make the directory for the site config
mkdir /opt/nginx-1.16.1/conf/conf.d
Now the site config
nano /opt/nginx-1.16.1/conf/conf.d/DOMAIN_NAME.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name DOMAIN_NAME www.DOMAIN_NAME;
root html/DOMAIN_NAME;
index index.php;
location / {
try_files $uri $uri/ =404;
}
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
#SECURITY
#Ignore other host headers
if ($host !~* ^(DOMAIN_NAME|www.DOMAIN_NAME)$ ) {
return 444;
}
#Obfuscation rule (hide identifying files)
location ~ /(.|wp-config.php|readme.html|licence.txt) {
return 404;
}
#Only allow GET , POST, and HEAD
if ($request_method !~ ^(GET|POST|HEAD)$ ) {
return 444;
}
#Disable viewing of hidden files (files starting with a dot)
location ~ /. {
deny all;
}
}
Now create the directory for your website and move it there
mkdir /opt/nginx-1.16.1/html/DOMAIN_NAME
mv path_to_site /opt/nginx-1.16.1/html/DOMAIN_NAME
As a last step, let's change the attributes so Nginx has access to the website
chown -R nginx:nginx /opt/nginx-1.16.1/html/DOMAIN_NAME
That's it, we made it!
You can also make sure Apache doesn't bother you anymore if you had it installed and running:
systemctl disable apache
systemctl stop apache
One Reply to “Moving from Apache to NGINX on Centos 7”