Install the latest version of NGinx, pagespeed and other modules
published on
This guide will show you how to create your own version of NGinx using the latest version at the time (1.25.2). This version supports HTTP3. We will also add in the latest version of zlib and libressl, brotli, redis, fast_cache_purge, more_headers and pagespeed (or ngx_pagespeed as it is also known).
Install prerequisites
First run the following commands to update your server and add some software we will need to download and compile everything later on.
cd ~
sudo apt update && sudo apt upgrade
sudo apt install apt-utils autoconf automake build-essential libpcre2-dev libpcre3 libpcre3-dev libssl-dev zlib1g zlib1g-dev libgd-dev libcurl4-openssl-dev liblmdb-dev libpcre++-dev libtool libxml2-dev libyajl-dev pkgconf unzip git redis-server
Now download the NGinx source code
Use the following commands to download and extract the NGinx source code:
export NGX_VER=1.25.2
wget http://nginx.org/download/nginx-$NGX_VER.tar.gz
tar -xzvf nginx-$NGX_VER.tar.gz
cd nginx-$NGX_VER/src/http/modules
Changing the version of NGinx you wish to use is as easy as changing the value in the first line above.
Download zlib, brotli, redis, fast_cache_purge, libressl and more_headers
Executing the following commands will download the source for all of the packages we will be compiling along with NGinx. Pagespeed will be added later as a dynamic module.
# download zlib
wget https://www.zlib.net/zlib-1.3.tar.gz
tar -xzvf zlib-1.3.tar.gz
# download brotli
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init
cd ..
# download the redis module
git clone https://github.com/openresty/redis2-nginx-module.git
# download fast_cache_purge
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar -xzvf ngx_cache_purge-2.3.tar.gz
# download libressl
wget https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.8.0.tar.gz
tar -xzvf libressl-3.8.0.tar.gz
# download more_headers
wget https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/v0.34.tar.gz
tar -xzvf v0.34.tar.gz
Now we will configure our custom NGinx
Execute the following two commands to configure the NGinx software installation ready to be compiled and installed.
cd ../../..
./configure --with-cc-opt='-g -O2 -march=westmere -flto -funsafe-math-optimizations -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -I../libressl/build/include' --with-ld-opt='-Wl,-z,relro -Wl,--as-needed,-L../libressl/build/lib' --prefix=/var/www/html --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --modules-path=/etc/nginx/modules --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=www-data --group=www-data --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_auth_request_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-openssl=./src/http/modules/libressl-3.8.0 --with-zlib=./src/http/modules/zlib-1.3 --with-compat --add-module=./src/http/modules/redis2-nginx-module --add-module=./src/http/modules/ngx_cache_purge-2.3 --add-module=./src/http/modules/headers-more-nginx-module-0.34
Now we need to create some directories
sudo mkdir -p /var/cache/nginx/client_temp
sudo mkdir -p /var/cache/nginx/proxy_temp
sudo mkdir -p /var/cache/nginx/fastcgi_temp
sudo mkdir -p /var/cache/nginx/uwsgi_temp
sudo mkdir -p /var/cache/nginx/scgi_temp
sudo mkdir -p /var/cache/nginx/redis_temp
Compile and install your custom version of NGinx
Now we need to execute the make
command to compile your version of NGinx. Once this is complete run sudo make install
to install it.
Once NGinx is installed we need to create a systemd service file by executing sudo nano /etc/systemd/system/nginx.service
and adding in the following lines:
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
We now start NGinx and set it up to automatically start on a reboot of your server:
sudo systemctl daemon-reload
sudo systemctl start nginx
sudo systemctl enable nginx
Compile and install pagespeed (or ngx_pagespeed)
Now it is time to create the pagespeed object file as a dynamic module. Execute the following set of commands to make the pagespeed module and set it up in the correct place.
cd ./src/http/modules
export PSOL="jammy"
wget http://www.tiredofit.nl/psol-${PSOL}.tar.xz
git clone --depth=1 https://github.com/apache/incubator-pagespeed-ngx.git
tar xvf psol-${PSOL}.tar.xz
mv psol incubator-pagespeed-ngx
cd ../../..
./configure --with-compat --add-dynamic-module=./src/http/modules/incubator-pagespeed-ngx
make modules
sudo cp objs/ngx_pagespeed.so /etc/nginx/modules
sudo mkdir /var/ngx_pagespeed_cache
sudo chown www-data:www-data /var/ngx_pagespeed_cache
Now set up NGinx
Now that all of the compiling is done we need to configure NGinx so that we can start using it.
Create a new nginx.conf file by executing the following two lines and inserting the instructions just below them:
sudo rm /etc/nginx/nginx.conf
sudo nano /etc/nginx/nginx.conf
--- custom nginx.conf ---user www-data;
worker_processes auto;
worker_rlimit_core 120540;
worker_rlimit_nofile 120540;
pid /var/run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
# load the pagespeed module
load_module "/etc/nginx/modules/ngx_pagespeed.so";
events {
worker_connections 20000;
multi_accept on;
}
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
reset_timedout_connection on;
send_timeout 30s;
keepalive_timeout 30s;
keepalive_requests 1000;
client_header_timeout 30;
client_body_timeout 30;
client_body_buffer_size 16K;
client_max_body_size 100m;
open_file_cache max=1000 inactive=10s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
include mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_buffer_size 4k;
ssl_session_tickets off;
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:50m;
ssl_ecdh_curve X25519:prime256v1:secp384r1;
ssl_prefer_server_ciphers on;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
charset utf-8;
charset_types
text/css
text/plain
text/vnd.wap.wml
text/javascript
text/markdown
text/calendar
text/x-component
text/vcard
text/cache-manifest
text/vtt
application/json
application/manifest+json;
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 combined;
error_log /var/log/nginx/error.log warn;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_min_length 256;
gzip_http_version 1.1;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/vnd.ms-fontobject
application/wasm
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/eot
font/opentype
font/otf
font/ttf
image/bmp
image/x-icon
image/svg+xml
text/cache-manifest
text/calendar
text/css
text/javascript
text/markdown
text/plain
text/xml
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
gzip_disable "MSIE [1-6]\.";
# aio on;
directio 4m;
directio_alignment 512;
# make sure to update path and zone name
proxy_cache_path /var/cache/nginx/redis_temp levels=1:2 keys_zone=my_cache:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
include ./sites/*;
}
--- custom nginx.conf ---
Now execute the following two lines to help prevent using your NGinx installation as an open proxy:
sudo echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
sudo echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi_params
Create a default NGinx site server block
Run the following commands to set up the default site configuration:
Execute sudo nano /etc/nginx/sites/default.conf
and add the following lines of code to set up the default server block:
server {
# Listen on port 80.
listen 80 default_server;
listen [::]:80 default_server;
# The document root.
root /var/www/html;
# Add index.php if you are using PHP.
index index.html index.htm;
# The server name, which isn't relevant in this case, because we only have one.
server_name _;
}
sudo echo "<html><head><body></body></head></html>" > /var/www/html/index.html
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
sudo systemctl restart nginx
Conclusion
You should now have a working custom NGinx installation that supports http3, brotli, fast_cache_purge, more_headers and pagespeed (along with custom versions of zlib and libressl).
All that is left is for you to create your own server block for your site and configure it the way you would like.
Notes
To use http3 in your server blocks you will need to use the following instructions which differ slightly from the older http2 and http1 versions:
server {
listen 443 quic reuseport;
listen 443 ssl;
listen [::]:443 quic reuseport;
listen [::]:443 ssl;
http2 on;
location / {
# required for browsers to direct them into quic port
add_header Alt-Svc 'h3=":$server_port"; ma=86400';
# signal whether we are using QUIC+HTTP/3
add_header X-protocol $server_protocol always;
}
# the redis stuff - copy this into every location block you want to use it in
# change cache name and validty as suits
proxy_cache my_cache;
proxy_cache_lock on;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
# this next section needs to be in every server block where pagespeed is required
pagespeed on;
# Needs to exist and be writable by nginx. Use tmpfs for best performance.
pagespeed FileCachePath /var/ngx_pagespeed_cache;
# Ensure requests for pagespeed optimized resources go to the pagespeed handler
# and no extraneous headers get set.
location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
add_header "" "";
}
location ~ "^/pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon$" { }