Setting up Wordpress with Nginx, Varnish, Apache, PHP 7 and MariaDB
Published: 2021-01-18 | Last Updated: 2021-02-02 | ~17 Minute Read
Table of Contents
- Context
- System Specs
- Requirements
- Software Installation
- Software Configuration
- Backup Configuration
- SSL Configuration
Context
I recently had to do a setup similar to this and I thought I’d share the process with you as well. This is not a full tutorial, it’s more of an overview but I think it’ll show the general idea behind how the setup was done.
System specs
These were the specs of the Debian server that I was working with.
ubuntu@server:~$ free -h
total used free shared buff/cache availabl
Mem: 2.0Gi 42Mi 1.8Gi 10Mi 126Mi 1.8G
Swap: 0B 0B 0B
ubuntu@server:~$ uname -a
Linux server 4.19.0-8-cloud-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64 GNU/Linux
ubuntu@server:~$ cat /proc/cpuinfo | grep model
model : 85
model name : Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz
ubuntu@server:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 10 (buster)
Release: 10
Codename: buster
Requirements
This setup had a few specific requirements:
- Latest version of Nginx and Apache
- Nginx to be publicly exposed
- Varnish should be used for caching between Nginx and Apache
- Varnish failure should not render the application unusable
- Apache should be Nginx’s final backend and handle PHP via php-fpm
- Apache and php-fpm should communicate via TCP/IP sockets
- PHP 7,x should be used
- Latest version of MariaDB should be used
- PHP-FPM and MariaDB should connect via unix sockets
- Close ports on the server to only have 22, 80 and 443 open
Web-Flow Diagram
This is what it had to look like from a bird’s eye point of view:
#########
# #
# Nginx # - - - - -
# # |
######### |
| |
v |
########### |
# # |
# Varnish # | In case of
# # | varnish
########### | failure
| |
v |
########## |
# # |
# Apache # <- - -
# #
##########
|
| - - - - (Connection via TCP/IP Sockets)
v
###########
# #
# PHP-FPM #
# #
###########
|
| - - - - (Connection via Unix Sockets)
v
###########
# #
# MariaDB #
# #
###########
Software Installation
Installation of Nginx
To install Nginx I added the official repositories to the /etc/apt/sources.list.d/nginx.list
file for the debian version installed:
deb http://nginx.org/packages/debian/ buster nginx
deb-src http://nginx.org/packages/debian/ buster nginx
Installed Nginx version:
ubuntu@server:~$ sudo nginx -v
nginx version: nginx/1.18.0
Installation of Apache
I then installed apache, version installed:
ubuntu@server:~$ sudo apache2 -v
Server version: Apache/2.4.38 (Debian)
Server built: 2019-10-15T19:53:42
Installation of Varnish
Installed Varnish, version installed:
root@server:/etc/init.d# varnishd -V
varnishd (varnish-6.1.1 revision efc2f6c1536cf2272e471f5cff5f145239b19460)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2015 Varnish Software AS
Installation of PHP
Installed PHP, version installed:
root@server:/etc/init.d# php -v
PHP 7.3.19-1~deb10u1 (cli) (built: Jul 5 2020 06:46:45) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.19, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.19-1~deb10u1, Copyright (c) 1999-2018, by Zend Technologies
Installation of PHP-FPM
Installed PHP-FPM, version installed:
root@server:/etc/init.d# /etc/init.d/php7.3-fpm status
● php7.3-fpm.service - The PHP 7.3 FastCGI Process Manager
Jul 30 00:27:20 server systemd[1]: Starting The PHP 7.3 FastCGI Process Manager...
Jul 30 00:27:20 server systemd[1]: Started The PHP 7.3 FastCGI Process Manager.
Domain Configuration
The domain used is domain.com
Set an A
record for the domain pointing to the server IP so we can access the via domain name.
Software Configuration
Nginx Configuration
Updated the default virtual host file /etc/nginx/conf.d/default.conf
and named it domain.com.conf
Updated the contents to include PHP redirection and logging as follows:
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/wordpress.access.log main;
error_log /var/log/nginx/wordpress.error.log crit;
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:8080
#
location ~ \.php$ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
With those updates we can now see the logs here:
root@server:/var/log/nginx# ls
wordpress.access.log wordpress.error.log
Apache Configuration
I did a couple of configuration changes here:
- Updated the
/etc/apache2/ports.conf
file to listen on port8080
on localhost - Updated the default virtual host file
/etc/apache2/sites-available/000-default.conf
todomain.com.conf
. - Created the symbolic link to
/etc/apache2/sites-available/wordpress-backend.conf
from/etc/apache2/sites-enabled/wordpres-backend.conf
- Updated the document root to be the same as Nginx
/user/share/nginx/html
. - Enabled the
remoteip
andheaders
apache modules - Enabled the
mod_rewrite
PHP module - Enabled logging the remote client IP address on the Apache logs with use of the
X-Forwarded-For
environment variable and the customer log format feature from Apache. - Updated the contents of
/etc/apache2/conf-available/php7.3-fpm.conf
to only use TCP/IP sockets for theSetHandler
directive. - Created a symbolic link to
/etc/apache2/conf-available/php7.3-fpm.conf
from/etc/apache2/conf-enabled/php7.3-fpm.conf
- Included the
conf-available/php7.3-fpm.conf
in the/etc/apache2/sites-available/domain.com.conf
file - Installed the
php7.3-mysql
module
Updated the contents to listen on port 8080
on localhost as follows:
<VirtualHost 127.0.0.1:8080>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName backend
ServerAdmin webmaster@localhost
DocumentRoot /usr/share/nginx/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" forwarded
ErrorLog ${APACHE_LOG_DIR}/wordpress.error.log
CustomLog ${APACHE_LOG_DIR}/wordpress.access.log combined env=!forwarded
CustomLog ${APACHE_LOG_DIR}/wordpress.access.log forwarded env=forwarded
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
Include conf-available/php7.3-fpm.conf
</VirtualHost>
PHP-FPM listening status:
root@server:~# ss -tulpn | grep fpm
tcp LISTEN 0 128 127.0.0.1:8081 0.0.0.0:* users:(("php-fpm7.3",pid=9670,fd=9),("php-fpm7.3",pid=9669,fd=9),("php-fpm7.3",pid=9668,fd=7))
Current webflow as seen from logs:
This is the output that we get from the updated log configuration we implemented, we can see the real IP from the client in the Apache log even though it’s behind Nginx.
root@server:~# tail -1 /var/log/nginx/wordpress.access.log
xxx.xxx.xxx.xxx - - [30/Jul/2020:03:59:16 +0000] "GET / HTTP/1.1" 200 21310 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0" "-"
root@server:~# tail -1 /var/log/apache2/wordpress.access.log
xxx.xxx.xxx.xxx - - [30/Jul/2020:03:59:16 +0000] "GET /index.php HTTP/1.0" 200 21310 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"
Varnish Configuration
The configuration changes done for Varnish are the following:
- Updated the name of the default
/etc/varnish/default.vcl
file to/etc/varnish/wordpress-cache.vcl
. - Copied the default
/lib/systemd/system/varnish.service
file to/etc/systemd/system/
- Added the correct configuration file name to the
varnish.service
file - Added the
/etc/varnish/hit-miss.vcl
with the information provided by the Varnish Software team documentation, and added this file to thewordpress-cache.vcl
file as an include
This is what the Varnish service file looks like:
root@server:~# cat /etc/systemd/system/varnish.service
[Unit]
Description=Varnish HTTP accelerator
Documentation=https://www.varnish-cache.org/docs/6.1/ man:varnishd
[Service]
Type=simple
LimitNOFILE=131072
LimitMEMLOCK=82000
ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a 127.0.0.1:6081 -T localhost:6082 -f /etc/varnish/wordpress-cache.vcl -S /etc/varnish/secret -s malloc,256m
ExecReload=/usr/share/varnish/varnishreload
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
This is what the Varnish configuration file looks like:
root@server:/etc/varnish# cat wordpress-cache.vcl
#
# This is an example VCL file for Varnish.
#
# It does not do anything by default, delegating control to the
# builtin VCL. The builtin VCL is called when there is no explicit
# return statement.
#
# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/
# and https://www.varnish-cache.org/trac/wiki/VCLExamples for more examples.
# Marker to tell the VCL compiler that this VCL has been adapted to the
# new 4.0 format.
vcl 4.0;
include "hit-miss.vcl";
import std;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
}
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
#
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.
}
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
}
Nginx Updated Configuration
With the above working as expected, it was time to move on to the next step:
- Updated the
/etc/nginx/conf.d/domain.com.conf
to with an active-backup load balancing method in order to bypass Varnish in case it fails and go directly to Apache instead - Added a location entry to have access to the
/status
page over TCP/IP sockets from localhost only
Nginx updated configuration:
root@server:/etc/varnish# cat /etc/nginx/conf.d/wordpress.conf
upstream backend {
server 127.0.0.1:6081 max_fails=1 fail_timeout=1s;
server 127.0.0.1:8080 backup;
}
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/wordpress.access.log main;
error_log /var/log/nginx/wordpress.error.log crit;
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:8080
#
location ~ \.php$ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://backend;
}
# Access PHP-FPM /status page from localhost for testing
#
location ~ ^/(status|ping)$ {
allow 127.0.0.1;
deny all;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_pass 127.0.0.1:8081;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
Current webflow as seen from logs:
With those updates we now have the following in the logs whenever we get a request:
From the client:
bash-4.3$ curl -I http://domain.com
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 30 Jul 2020 06:09:50 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 21081
Connection: keep-alive
Vary: Accept-Encoding
X-Varnish: 32777 32775
Age: 55
Via: 1.1 varnish (Varnish/6.1)
Accept-Ranges: bytes
From the server:
root@server:/etc/varnish# varnishlog | grep -i cache
- ReqHeader x-cache: hit
- ReqUnset x-cache: hit
- ReqHeader x-cache: hit cached
root@server:/etc/varnish# tail -1 /var/log/nginx/wordpress.access.log
xxx.xxx.xxx.xxx - - [30/Jul/2020:06:09:50 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.71.0" "-"
root@server:/etc/varnish# tail -1 /var/log/apache2/wordpress.access.log
xxx.xxx.xxx.xxx, 127.0.0.1 - - [30/Jul/2020:06:08:55 +0000] "GET /index.php HTTP/1.1" 200 21081 "-" "curl/7.71.0"
MariaDB Configuration
The changes done to the MariaDB info were pretty straight forward;
- Commented out the
bind_address
parameter in the/etc/mysqld/mariadb.conf.d/50-server.cnf
file in order to avoid opening TCP/IP sockets - Ran the secure installation script
- Created the database for the Wordpress deployment with the name of
wpdb
- Created a mysql user
wpuser
and assigned all privileges towpdb
MariaDB listening status:
ubuntu@server:~$ ss -a | grep mysql
u_str LISTEN 0 80 /run/mysqld/mysqld.sock 3455
tcp LISTEN 0 80 *:mysq
Firewall Configuration
This is the first time I use nftables and I enjoyed using it a lot.
- Installed the
nftables
package to use as a firewall. - Updated the default
/etc/nftables.conf
file - Set the service to start on boot
Nftables configuration file:
root@server:~# cat /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
# Accept loopback
iifname lo accept;
# Accept established/related
ct state established,related accept;
# Accept SSH / HTTP / HTTPs
tcp dport {22, 80, 443} counter accept;
# Drop all traffic
policy drop;
}
chain forward {
type filter hook forward priority 0;
# Drop all traffic
policy drop;
}
chain output {
type filter hook output priority 0;
# Accept all traffic
policy accept;
}
}
Github Configuration & Wordpress Deployment
This is how I implemented the website to be able to be easily deployed & updated via Github
- Created a new repository in Github
- Populated the repository with the wordpress installation files on Github
- Installed git on the server
- Deployed the wordpress website via git with
git clone
to the/usr/share/nginx/html/wordpress
folder - Updated ownership of the
/usr/share/nginx/html/wordpress
folder to thewww-data
user and group - Updated Nginx’s configuration for this folder to become the new root folder for the server
- Updated Apache’s configuration for this folder to become the new root folder for the server
- Installed Wordpress from the simple Github deployment
- Committed changes to the site from the server
Backup Configuration
I created a simple backup script that took care of the following:
- Script will create three backups, one incremental and one full local backups as well as a remote backup on the github repository
- The activities of the script will be logged
- Script will be executed everyday at 3:00 am
All files related to backups will be stored under /root
with the following directory structure:
├── wordpress-backup
│ ├── full-backups
│ ├── incremental-backups
│ └── logs
└── wordpress-backup.sh
Full backup implementation
- A backup of the db is done via the
mysqldump
command - A backup of the
/usr/share/nginx/html/wordpress
directory is done with tar - The same tarball includes both the db backup file and the wordpress contents
- Some sanity checks are implemented in case of failures during execution
Partial backup implementation
- A backup of the
/usr/share/nginx/html/wordpress
directory is triggered viarsync
- The database is not backed up in this partial backup
- Some sanity checks are implemented in case of failures during execution
Github backup implementation
- An automatic commit/push will be sent to a backup branch on the github repository for the website based on changes
- Some sanity checks are implemented in case of failures during execution
Script source code
root@server:~# cat wordpress-backup.sh
#! /bin/bash
# Script to backup Wordpress installation on this server
# Define log file variable
BACKUP_EXEC_LOG_FILE=/root/wordpress-backup/logs/backup-execution_`date +%m-%d-%y_%H-%M-%S`.log
# Catch stdout and stderr, and log execution of script
exec 1>> "$BACKUP_EXEC_LOG_FILE"
exec 2>&1
# This script will create three different backups
# 1. An incremental backup with rsync
# 2. A full backup in the .tar.gz format with compression
# 3. Trigger git routines to backup externally to the git repository linked to the site
# All files will be backed up to the /root/wordpress-backup folder
# Define script functions
function checkExitStatus {
# Check if the command exit status is not equal to 0
if [ $? != 0 ]
then
# Echo an error message and exit
echo "$DB_MSG"; exit
fi
}
# Define script variables
BACKUP_EXEC_LOGS_DIR=/root/wordpress-backup/logs
DATE=`date +%m-%d-%y_%H-%M-%S`
BACKUP_SOURCE=/usr/share/nginx/html/wordpress/
FULL_BACKUP_DIR=/root/wordpress-backup/full-backups
INCREMENTAL_BACKUP_DIR=/root/wordpress-backup/incremental-backups/
DB_BACKUP_FILE=/root/wordpress-backup/db-backup.sql
DB_MSG="There was an error creating the DB backup file. Backup not executed, exiting. mysqldump exit status $?"
DB_MSG1="Backup DB file does not exist yet, unable to continue. Backup not executed, exiting"
TAR_MSG="There was an error in creating the tar archive for the backup. Backup not executed, exiting. tar exit status
RSYNC_MSG="There was an error in creating the partial backup. Exiting. rsync exit status $?"
COMMIT_MSG="Daily backup"
NO_COMMIT_MSG="No changes to commit, nothing to push"
# Full backup
# Backup the mariadb database
mysqldump wpdb --single-transaction > $DB_BACKUP_FILE
# Call exit status function
checkExitStatus
# Backup the /wordpress web directory
# Check that the tmp-db-backup file exists before proceeding
if [ -f $DB_BACKUP_FILE ]
then
# Create the backup by using the tar command
tar -cvzpf $FULL_BACKUP_DIR/full-wordpress-backup_$DATE.tar.gz $BACKUP_SOURCE $DB_BACKUP_FILE
# Call exit status function
checkExitStatus
# Delete the DB_BACKUP_FILE from the /root/wordpress-backups directory
rm $DB_BACKUP_FILE
else
# Echo an error message and exit
echo $DB_MSG1 ; exit
fi
# Partial Backup
# Use rsync to create an incremental backup
rsync -ahv --delete $BACKUP_SOURCE $INCREMENTAL_BACKUP_DIR
# Call exit status function
checkExitStatus
# Github repository backup
# Change the working directory to $BACKUP_SOURCE as this is the local git repository
cd $BACKUP_SOURCE
# Checkout the backup branch
git checkout backup
if [ `git diff | wc -l` != 0 ]
then
# Commit all changes
git commit -am "$COMMIT_MSG"
# Push staged changes to github
git push origin backup
else
echo $NO_COMMIT_MSG
fi
# Checkout the master branch
git checkout master
SSL Configuration
I setup a self signed certificate at first and then implemented Let’s Encrypt for the SSL certificate and the configuration overview is as follows;
Nginx configuration
- Created a certificate and a key and stored them in
/etc/nginx/ssl
- Updated the Nginx config to redirect all traffic coming in via HTTP to HTTPs
- Updated wordpress' gui configuration to use https
Nginx updated configuration
- At this point I ran into an issue, there was a redirect loop (301) happening on the
/
of the website - This seems to be occurring due to the proxy request headers that get sent to Apache and the way wordpress does URL rewrites (canonical)
- The Nginx configuration file
/etc/nginx/conf.d/domain.com.conf
was updated and rules were added to the/usr/share/nginx/html/wordpress/wp-config.php
file in order to correct the behavior
The updated Nginx configuration file:
# Configure backend
upstream backend {
server 127.0.0.1:6081 max_fails=1 fail_timeout=1s;
server 127.0.0.1:8080 backup;
}
# Configure https redirect
server {
listen 80;
server_name domain.com;
return 301 https://$server_name$request_uri;
}
# Configure HTTPs connections
server {
listen 443 ssl;
server_name domain.com;
root /usr/share/nginx/html/wordpress;
index index.php;
# Configure Logging
access_log /var/log/nginx/wordpress.access.log main;
error_log /var/log/nginx/wordpress.error.log crit;
# SSL settings
ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:MD5;
# Configure requests for requests to /
location = / {
# Pass connections to the backend
proxy_pass http://backend;
# Rewrite apache output header 'location' value from 'http://' to 'https://'
proxy_redirect http:// $scheme://;
# Set header 'Host' to 'xxx`
proxy_set_header Host $host;
# Pass the address of the client to the backend
proxy_set_header X-Real-IP $remote_addr;
# Set header 'X-Forwarded-For' to the remote address. Apache logs client and proxy address (127.0.0.1)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# set header 'X-Forwarded-Proto' 'https'
proxy_set_header X-Forwarded-Proto $scheme;
}
# Redirect all php requests to backend
location ~ \.php$ {
proxy_pass http://backend;
proxy_redirect http:// $scheme://;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Request that static objects are stored client side as long as possible
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
# Block access to the .htaccess file that wordpress creates
location ~ /\.ht {
deny all;
}
}
Curl output from a client with the above configuration:
bash-4.3$ curl -Ik https://domain.com
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sun, 02 Aug 2020 06:56:19 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 6996
Connection: keep-alive
Link: <https://domain.com/index.php?rest_route=/>; rel="https://api.w.org/"
Vary: Accept-Encoding
X-Varnish: 98732 941
Age: 58
Via: 1.1 varnish (Varnish/6.1)
Accept-Ranges: bytes
The snippets that were added to the wp-config.php
file:
// If the X_FORWARDED_FOR header is present in the request, Get a comma delimited list of IPs from the X_FORWARDED_FOR header and set the remote address to the first IP in the array
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $ips[0];
}
// If the the X_FORWARDED_PROTO header is present in the request and the value is https, set the uri to use https
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$_SERVER['HTTPS'] = 'on';
}
}
Let’s encrypt configuration
This is the setup I did for Let’s encrypt on the server:
- Installed cerbot via apt
- Created keys
- Configured keys manually
- Configured a cronjob for the renewal process
Curl output from a client with the new letsencrypt certificate
bash-4.3$ curl -I https://domain.com
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sun, 02 Aug 2020 08:06:16 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 6996
Connection: keep-alive
Link: <https://domain.com/index.php?rest_route=/>; rel="https://api.w.org/"
Vary: Accept-Encoding
X-Varnish: 98827
Age: 0
Via: 1.1 varnish (Varnish/6.1)
Accept-Ranges: bytes
Research Links
I did some research for this setup and learned a few things along the way. Here are some of the links that I thought were most helpful during the research.