I have a website on an EC2 instance with NGINX and Ubuntu 18.0.4. I have setup the server block for the site the site is loading correctly. I have also enabled caching for images, javascript and css files.
I want to exclude certain paths from getting cached and I tried some config examples available on the internet. None of them are working and I am getting a 404 error for the locations that I am trying to exclude.
My server block is as follows:
# Expires map
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/javascript max;
~image/ max;
~font/ max;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
expires $expires;
location /path1/ {
add_header Cache-Control "private";
}
location /path2/subpath1/ {
add_header Cache-Control "private";
}
location /path2/subpath2/ {
add_header Cache-Control "private";
}
location /path2/subpath3/ {
add_header Cache-Control "private";
}
}
The paths (path1, path2) which I have tried to exclude from caching are returning a 404 not found error. Can someone please help?
Related
I've a Nginx configuration, where I get certain files from AWS S3 bucket, like call from *.my.api.com/file.js will get the file from X folder in S3.
I've an exceptional domain (like xx.my.api.com) for which I will add the
Cache-Control "no-store, no-cache";
Pragma "no-cache";
headers and for the rest of *.my.api.com the headers will be default (it's cache-control: public now).
On my local environment, the file is hosted on my machine, so the headers are set correctly. However, on production, the headers come as default as cache-control: public.
I've read answers like this saying there should be no trouble with it, but it's not working for me.
Is there anything I'm doing wrong? Is it related to the file being hosted on AWS?
My Nginx configuration is as below:
server {
listen 80;
root /var/xyz/public;
index index.html index.htm;
server_name my.api.com *.my.api.com;
add_header Access-Control-Allow-Origin "*";
if ($http_host ~* "^(.*).my.api.com$"){
set $myName $1;
}
location ~ /myfile.js {
resolver 8.8.8.8;
proxy_buffering off;
proxy_set_header Content-Length "";
proxy_set_header Cookie "";
proxy_method GET;
proxy_pass_request_body off;
proxy_max_temp_file_size 0;
if ($myName = "mySpecialName") {
proxy_pass http://path/to/aws/s3/bucket/file.js;
add_header Cache-Control "no-store, no-cache";
add_header Pragma "no-cache";
add_header X-XSS-Protection "1";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options nosniff;
}
if ($query_string !~* "myQueryString=([^&]*)") {
proxy_pass http://path/to/aws/s3/bucket/file.js;
}
if ($query_string ~* "myQueryString=([^&]*)") {
proxy_pass http://path/to/some/other/aws/s3/bucket/file.js;
}
}
}
I've tried:
always
proxy_pass_request_headers on
proxy_set_header
copying the server code and adjusting for xx.my.api.com only
proxy_hide_header (can't be used because of if block)
more_set_headers
but none of them worked.
Any help would be appreciated, thanks in advance.
We've solved it by adding the headers from our DNS panel, which was used for caching the file stored in S3.
I have an use-case where for a particular request with path say /test-abc, i want the request to go to S3 rather than kong and all requests with path other than /test-abc should flow to kong gateway. I tried adding the location block in nginx-kong.conf as below, But I don't see requests going to s3. Can someone please help me understand what I'm missing here?
# Kong's Proxy server block
server {
server_name kong;
# any contents until the location / block
...
location / {
...
}
location /test-abc {
proxy_pass <s3-url-here>
add_header 'content-type' 'application/json';
add_header 'cache-control' 'public, max-age=0';
add_header 'vary' 'Accept-Encoding';
add_header 'accept-ranges' 'bytes';
charset UTF-8;
default_type application/json;
}
}
I have two react repos and corresponding builds at /www/web and /www/mobile
I am trying to serve my static files based on User Agent.
By default static files will be served from /www/web directory and if it's a mobile device then static files will be served from /www/mobile
Following is my nginx default.conf
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/javascript max;
~image/ max;
~font/ max;
}
map $http_user_agent $ua_device {
default 'desktop';
~*(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge\ |maemo|midp|mmp|mobile.+firefox|netfront|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ ce|xda|xiino/i 'mobile';
~*android|ipad|playbook|silk/i 'tablet';
}
map $ua_device $root_content {
default '/www/web';
'mobile' '/www/mobile';
}
server {
listen 80 default_server;
server_name _;
root $root_content;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires $expires;
}
Now, with this config, web is working fine. But if i check on mobile then I am getting 500 with following error message.
rewrite or internal redirection cycle while internally redirecting to
"/index.html"
I have been at this for a long while now, so any pointers would be really great help.
I added the Access-Control-Allow-Origin under the server section. That works as expected for any 'images'. When I call the 'canonical link' (1.pdf) the Access-Control-Allow-Origin is missing in the response. Why? And how can that be solved?
I don't want do add this line to all of my canonical links.
server {
server_name myserver.de;
listen 10.11.12.13:443 ssl http2;
access_log /var/log/nginx/ssl_access.log;
error_log /var/log/nginx/ssl_error.log error;
add_header 'Access-Control-Allow-Origin' 'https://foo.bar';
location / {
root /data/images/;
location ~ (.*)/1.pdf$ {
#add_header 'Access-Control-Allow-Origin' 'https://foo.bar';
add_header Link "<http://foo.bar/a-pdf>; rel=\"canonical\"";
}
}
There could be several add_header directives. These directives are
inherited from the previous level if and only if there are no
add_header directives defined on the current level.
You can use ngx_headers_more module to solve this problem
If you don't want to use above module, try something like this
server {
set $headerA 'https://foo.bar';
set $headerB "";
if (something) {
set $headerB "something";
}
add_header 'Access-Control-Allow-Origin' $headerA;
add_header Link $headerB;
}
Only use add_header in the server block and remove all add_header from location block. Note that Link would not be returned if headerB is empty
I am trying to use NginX as a reverse proxy for a few IIS Servers. The goal is to have NginX sit in from of the IIS / Apache servers caching static items such as CSS / JS / Images. I am also trying to get NginX to automatically minify js / css files using its perl module.
I found a sample script for minification here:
http://petermolnar.eu/linux-tech-coding/nginx-perl-minify-css-js/
With the scrip everything works fine, except the reverse proxy breaks.
Questions:
Is what i am trying to accomplish even possible? I want NginX to first minify the scripts before saving them to cache.
Can nginX automtically set the proper expires headers so that static items are cached as long as possible, and only replaced when querystrings are changed (jquery.js?timestamp=march-2012)
Can NginX GZIP the resources before sending them out.
Can NGinx Forward requests or serve up a "Down For Maintenance page" if it cannot connec to back end server.
Any help would be greatly appreciated.
Here is what i have in my sites-enabled/default so far.
server {
location / {
proxy_pass http://mywebsite.com;
proxy_set_header Host $host;
proxy_cache STATIC;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error timeout invalid_header updating
http_500 http_502 http_503 http_504;
}
location #minify {
perl Minify::minify_handler;
}
location ~ \.css$ {
try_files $uri.min.css #minify;
}
location /*.js {
expires 30d;
}
}
Nginx is the ideal solution for reverse-proxy, it's also Unix way "do one thing and do it well". So I'd advice you to split content serve and minification process out instead of using third-party plugins to do many things at once.
Best practice is to do minify&obfuscate phase on local system before you do a deployment on production, this is easy to say and not hard to do, see the google way to compress static assets. Once you got assets ready-to-use, we can setup nginx configuration.
Answers:
use minify&obfuscate before deploy it on production
you can find assets by regexp (directory name or file extension)
location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
break;
}
use gzip on and gzip_static on to serve gzipped files instead of compress it every time when request is coming.
use try_files to detect the maintenance page exists or not
try_files $uri /system/maintenance.html #mywebsite;
if (-f $document_root/system/maintenance.html) {
return 503;
}
See the full nginx config for your case:
http {
keepalive_timeout 70;
gzip on;
gzip_http_version 1.1;
gzip_disable "msie6";
gzip_vary on;
gzip_min_length 1100;
gzip_buffers 64 8k;
gzip_comp_level 3;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml;
upstream mywebsite {
server 192.168.0.1 # change it with your setting
}
server {
try_files $uri /system/maintenance.html #mywebsite;
location #mywebsite {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://mywebsite;
}
location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
break;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
}
}