Nowadays, everyone is trying to adopt cloud technologies. Currently, there are a few famous cloud service providers in the market such as AWS, Microsoft Azure, GCP, etc. Web developers often use cloud storage to dump static data, such as images, videos, document files, etc.
But the challenge is we don't want our customers to know that the assets are being served from the other server or we generally avoid redirecting. To solve this we will use a very known concept in the world of servers, reverse proxy.
If you want to know what is the difference between proxy(or forwarded proxy) and reverse proxy, then refer to this article.
The prerequisite of this article is:
You have setup Nginx on your server
You have the blob URL ready with you.
In this article, my site name is jrdeveloper.online
and my blob storage URL is /{your_blob}/{buket_name}/content/assets/do_2136825431517347841122/test.mp4
Now what I trying to achieve here is whenever I hit jrdeveloper.online/web-assets/{path_to_asset}
it should proxy this request to the actual blob storage URL and return the requested asset, while I'm on the same URL in the browser.
The /etc/nginx/sites-available/jrdeveloper.online
will look like below:
Now, this will handle all the URLs. But when users ask specifically for jrdeveloper.online/web-assets/{path_to_asset}
in that case, we need to proxy this request to the /{your_blob}/{subfolder}/{path_to_asset}`
For example:
jrdeveloperdevpublic.blob.core.windows.net/web-assets/content/do_12121/marathon.mp4
Let's define a new variable $bucket
and keep the bucket name like below
set $bucket "jrdeveloperdevpublic.blob.core.windows.net";
Then let's add a new location for web-assets
. We will look for web-assets
in the request URL, if it gets matched, the following block of code will be executed:
location /web-assets {
resolver 8.8.8.8;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Connection "";
proxy_set_header Authorization '';
proxy_set_header Host $bucket;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
add_header Cache-Control max-age=31536000;
proxy_pass http://$bucket;
}
This will internally redirect all the requests to blob storage.
Sometimes, we may have different URLs in applications than blob storage URLs. In that case, we need to modify the incoming request to a specific format so that it can satisfy the path on blob storage.
Let's take an example. As of now, the subfolder name web-assets
was the same in both the requested URL and the actual blob storage URL. Now let's say, the application has changed the path to jrdeveloper.online/storage/{path_to_asset}
. In this case, we need to serve requests from the same blob storage.
To solve this we need to alter the requested URL before proxying the request as below:
There are multiple ways to do it, 2 approaches are given below:
- Using condition proxy:
location ~* "/storage/(.*)" {
resolver 8.8.8.8;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Connection "";
proxy_set_header Authorization '';
proxy_set_header Host $bucket;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
add_header Cache-Control max-age=31536000;
proxy_pass http://$bucket/web-assets/$1;
}
# same can be written as below
# location /storage {
# Add header here...
# if ($request_uri ~* "/storage/(.*)") {
# proxy_pass https://$bucket/web-assets/$1
# }
# }
- Using
rewrite
directive:
rewrite ^/storage/(\w+) /web-assets/$1
location /web-assets {
resolver 8.8.8.8;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Connection "";
proxy_set_header Authorization '';
proxy_set_header Host $bucket;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
add_header Cache-Control max-age=31536000;
proxy_pass https://$bucket;
}
Once updated the conf file don't forget to check if everything is fine on nginx with nginx -t
And then reload the server with service nginx reload