Setup: Wordpress with WordFence on Nginx with FastCGI enabled + PHP7.0 with opcache enabled (validate timestamps is false)
Story: With the above setup and confirmed that both FastCGI has HTML cached and PHP Opcache have all PHP files cached or so I assume (it has files but maybe missing some?) when I change the source files (Like mistakenly gzip each file - Oops!) the site goes down. In theory should the site not continue to send the cached files?
As I mentioned above ever so slightly I mistakenly gzip each file and the response from the server was 403 error, which makes sense because gz files are not accessible! But it seemed like it was trying to call something from source. Even more, as I ran the command to unzip everything, the site was still coming back online but was still throwing errors as some files had not been unzipped yet. It just seemed like the system is pulling from source and not cache? After the files unzipped I checked hits on PHP files in cache and confirmed the system is hitting cache.
So again, MAIN Question - Why did the site go down instead of defaulting to cache? If source files were not available but in cache it seemed to not request them or maybe checked if source still existed (even with validate timestamp set to false).
GLOBAL NGINX CONF
# Global settings
index index.htm index.html index.php;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
# Global Security settings
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
# Force all HTTP to HTTPS
server_name _;
return 301 https://$host$request_uri;
}
NGINX CONFIG for Site
fastcgi_cache_path /var/cache/html levels=1:2 keys_zone=FASTCGICACHE:500m inactive=10080m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
map $uri $blogname{
~^(?P<blogpath>/[^/]+/)files/(.*) $blogpath ;
}
# redirect non-www to www
server {
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1h;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5;
server_tokens off;
ssl_dhparam /etc/ssl/certs/dhparams.pem; #Need to run openssl dhparam -out dhparams.pem 4096
##buffer policy
# proxy_buffering on;
# proxy_buffer_size 1k;
# proxy_buffers 24 4k;
# proxy_busy_buffers_size 8k;
# proxy_max_temp_file_size 2048m;
# proxy_temp_file_write_size 32k;
##end buffer policy
server_name *.example.com;
root /pat/to/files/;
client_max_body_size 1000m;
add_header Strict-Transport-Security "max-age=15768000" always;
add_header X-XSS-Protection "1; mode=block";
set $skip_cache 0;
# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache uris containing the following segments
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache FASTCGICACHE;
fastcgi_cache_valid 10080m;
add_header X-FastCGI-Cache $upstream_cache_status;
}
if (!-e $request_filename) {
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
rewrite ^(/[^/]+)?(/wp-.*) $2 last;
rewrite ^(/[^/]+)?(/.*\.php) $2 last;
}
# Restrict access to System Status files
location ^~ /secure-some-files/ {
auth_basic "Site Administrator's Area";
auth_basic_user_file /etc/nginx/.htpasswd;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
location ~* \.(?:css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public";
log_not_found off;
}
# Deny access to sensitive extensions
location ~\.(ini|log|conf)$ {
deny all;
}
location = /favicon.ico { log_not_found off; access_log off; allow all; }
location = /robots.txt { log_not_found off; access_log off; allow all; }
# Deny access to uploads that aren�t images, videos, music, etc.
location ~* ^/wp-content/uploads/.*.(html|htm|shtml|php|js|swf)$ {
deny all;
}
# Deny public access to wp-config.php
location ~* wp-config.php {
deny all;
}
ssl_certificate /path/to/pem/fullchain.pem; # managed by Certbot
ssl_certificate_key /path/to/pem//privkey.pem; # managed by Certbot
}
PHP CONF
[www]
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = ec2-user
listen.group = ec2-user
listen.mode = 0664
user = ec2-user
group = ec2-user
Headers when site loads correctly
*General*
Request URL: https://www.example.com/
Request Method: GET
Status Code: 200
Remote Address: XX.XXX.XXX.XXX:443
Referrer Policy: no-referrer-when-downgrade
*Response Header*
content-encoding: gzip
content-type: text/html; charset=UTF-8
date: Thu, 03 Jan 2019 09:34:54 GMT
link: <https://www.example.com/wp-json/>; rel="https://api.w.org/"
link: <https://www.example.com/>; rel=shortlink
server: nginx
status: 200
vary: Accept-Encoding
x-fastcgi-cache: HIT
x-powered-by: PHP/7.0.32
*Request Header*
:authority: www.example.com
:method: GET
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: no-cache
cookie: {deleted} ; wp-settings-1=libraryContent%3Dbrowse%26advImgDetails%3Dshow%26editor%3Dhtml%26editor_expand%3Don; wp-settings-time-1=1542639953; {deleted}; PHPSESSID={deleted}; wordpress_test_cookie=WP+Cookie+check; _gat_gtag_UA_{deleted}_1=1; nQ_visitId={deleted}
pragma: no-cache
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Mobile Safari/537.36