We would like to launch a NextJS 10 app using NGINX so we use a configuration similar to:
location /_next/static/ {
alias /home/ec2-user/my-app/.next/static/;
expires 1y;
access_log on;
}
It works great, it caches for a year our statics but as we use NextJS images I'm failing to add an expires tag on on-the-fly resized images.
If I do:
location /_next/image/ {
alias /home/ec2-user/my-app/.next/image;
expires 1y;
access_log on;
}
It just returns a 404 on images.
Here is my server part NGINX config :
server {
listen 80;
server_name *.my-website.com;
# root /usr/share/nginx/html;
# root /home/ec2-user/my-app;
charset utf-8;
client_max_body_size 20M;
client_body_buffer_size 20M;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
underscores_in_headers on;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "same-origin" always;
location = /robots.txt {
proxy_pass https://api.my-website.com/robots.txt;
}
location /_next/static/ {
alias /home/ec2-user/my-app/.next/static/;
expires 1y;
access_log on;
}
location / {
# reverse proxy for merchant next server
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_request_headers on;
proxy_cache_bypass $http_upgrade;
proxy_buffering off;
}
}
Here is an example how you can rely of upstream Content-Type header to set up the Expires and Cache-Control headers:
map $upstream_http_content_type $expire {
~^image/ 1y; # 'image/*' content type
default off;
}
server {
...
location / {
# reverse proxy for merchant next server
proxy_pass http://localhost:3000;
...
expires $expire;
}
}
The same way you can tune cache control headers for any other content type of proxied response. The $upstream_http_<name> nginx variable is described here.
Update
To add cache control headers only by specific URIs you can use two chained map blocks:
map $uri $expire_by_uri {
~^/_next/image/ 1y;
default off;
}
map $upstream_http_content_type $expire {
~^image/ $expire_by_uri;
default off;
}
And if you don't expect anything but the images from /_next/image/... URIs, you can just use the
map $uri $expire {
~^/_next/image/ 1y;
default off;
}
Related
I'm struggling for few days to find a solution. It seems that my nuxt/axios proxy configuration are not taken into account when my site is on production. Locally everything is working fine but once the site is on the server my ajax calls hit mysite.com/api/ect... instead of being proxy to mysite.com/api/v1/ect. I tried to play with axios.baseURL and various configuration but nothing seems to work.
axios: {
proxy: true,
credentials: true,
},
proxy: {
'/api/': { target: 'mysite.com/api/v1', pathRewrite: {'^/api/': ''} },
},
Maybe the issue comes from my Nginx configuration ? I use a reverse proxy to serve a nuxt app on mysite.com and a laravel api on mysite.com/api. Can this be the problem ?
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/mysite.com/before/*;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mysite.com;
server_tokens off;
root /home/forge/api/public;
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/....
ssl_certificate_key /etc/nginx/ssl/....
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers .....
ssl_prefer_server_ciphers off;
ssl_dhparam /etc/nginx/dhparams.pem;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/mysite.com/server/*;
location /api {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/mysite.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
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;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/mysite.com/after/*;
Thanks for your help and recommendation,
Don't use API_URL if you use proxy mode. Use prefix instead of.
Turn on debug for check the proxyRequest:
proxy property in nuxt.config.js:
proxy: {
// target, others options
logLevel: ‘debug’,
onProxyReq(proxyReq, req, res) {
// console.log here
}
}
When i start octane it always use this host http ://127.0.0.1:8000 , which is usable in local development, but in production environnement i use domain name instead of localhost
Is there a way to change the hostname like http ://domain.com:8000 when we start octane.
Update:
I'm using apache
Update:
I switched to Nginx so, it works better than apache. But if someone managed to resolve this in Apache feel welcome to leave your configuration.
You need Nginx or Apache. It's already on Octane Documentation.
In the Nginx configuration example below file, Nginx will serve the site's static assets and proxy requests to the Octane server that is running on port 8000:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80; // or 8000
listen [::]:80; // or 8000
server_name domain.com;
server_tokens off;
root /your/octane_path/public;
index index.php;
charset utf-8;
location /index.php {
try_files /not_exists #octane;
}
location / {
try_files $uri $uri/ #octane;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/domain.com-error.log error;
error_page 404 /index.php;
location #octane {
set $suffix "";
if ($uri = /index.php) {
set $suffix ?$query_string;
}
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header SERVER_PORT $server_port;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://127.0.0.1:8000$suffix;
}
}
You can change the hostname by passing the option --host=your-host to the octane command.
I have a nuxt application SPA for the front end and a laravel API. Nuxt calls on API for request. I am trying to deploy this in one digital ocean droplet but I am having problems with it. My laravel application seems to be working but I cant get nuxt to show here is my set up
Ubuntu 20
nginx 1.18
php 7.4
laravel nginx server block
server {
listen 80;
server_name DROPLET_IP;
root /var/www/laravel-api/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
here is my nuxt server block:
server {
listen 3000;
server_name DROPLET_IP;
keepalive_timeout 60;
index index.html;
location / {
root /var/www/nuxt-front/dist;
}
}
both of these are in their own sites-available and symlink to sites enable.
for some reason when I access http://DROPLET_IP:3000. it just hangs.
Is there a special way I should be doing this to run as expected?
Use root
server {
listen 80;
server_name example.com;
keepalive_timeout 60;
root /var/www/nuxt-front/dist;
}
or
use proxy pass
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
How to make a preemptive cache with nginx?
Currently, the cache becomes stale and unloads lots of images at once.
In my http section I have
proxy_cache_path /var/cache/nginx levels=1:1 keys_zone=zone:10m;
In my server configuration I have something like
server {
listen 80 default deferred;
server_name myservername
root /myapp/public;
client_max_body_size 2G;
proxy_cache_bypass $http_pragma;
proxy_cache_valid 200 301 302 304 1M;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache zone;
gzip_static on;
try_files $uri #app;
location #app {
if ($request_uri ~* "\.(ico|css|js|gif|jpe?g|png)\?[0-9]+$") {
expires max;
break;
}
client_body_buffer_size 32k;
proxy_buffers 8 64k;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://myupstream;
}
}
I want to fetch a file from the cache conditionally, based on a custom header in the request.
If the X-Proxy header is present in the request, return the file only if it's present in the cache. Otherwise fetch it from the internet if necessary.
Here's my .conf file:
worker_processes 1;
events {
worker_connections 1024;
}
http {
proxy_cache_path /home/nginx/proxy levels=1:2 keys_zone=one:15m inactive=7d max_size=1000m;
proxy_temp_path /home/nginx/temp;
proxy_buffering on;
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;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
server {
listen 8000;
location / {
root /home/nginx/preload;
try_files /$uri #local #remote;
}
location #local {
internal;
add_header X-Local true;
add_header X-Cache $upstream_cache_status;
proxy_pass http://$http_host$uri$is_args$args;
proxy_cache one;
proxy_cache_key backend$request_uri;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout invalid_header;
}
location #remote {
resolver 8.8.8.8;
add_header X-Remote true;
add_header X-Cache $upstream_cache_status;
if ($http_x_proxy) {
return 404;
}
proxy_pass http://$http_host$uri$is_args$args;
proxy_cache one;
proxy_cache_key backend$request_uri;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout invalid_header;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
The problem is that the try_files directive always passes into my #remote location, even if the fetched file is cached. How do I tell it that the file was found when it returns from #local?
try_files directive only accepts one named location, so apparently it goes for the last one. This blog post proposes a workaround that works in your case. In case you don't won't read the whole post, you can add the following lines at the end of #local block:
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 = #remote;
and change your try_files to this:
try_files /$uri #local;