Tag Archives: Nginx

Nginx Notion Proxy

What these configs do:

  • Proxy all traffic from Notion to your custom domain notion.example.tld and deliver it to your clients
  • WebSocket proxy support
  • Image local disk caching support
  • Correct URL rewriting
  • Get access logs from real request IPs

This post is a proof of concept proxying a general XaaS without using any vendor-locked FaaS such as Cloudflare Workers or AWS Lambda.

Continue reading

Nginx Multiple Upstreams with HTTPS Support

This example can make sure all requests to the upstreams are handled via HTTPS.

upstream source.example.tld {
  server s1.example.tld:443;
  server s2.example.tld:443 max_fails=2 fail_timeout=5s;
  server s2.example.tld:443;

server {
    proxy_pass https://source.example.tld/;
    proxy_ssl_protocols     TLSv1.2 TLSv1.3;
    proxy_ssl_verify        off;
    proxy_ssl_session_reuse on;

Nginx `nodelay` Option in Action

The nodelay option for limit_req can delay excessive requests but it’s not desired in some situations. I just found an intuitive way to show the difference while tweaking the GitHub Avatar proxy.

Every grid is an image loaded from GitHub avatar.

With nodelay:

Without nodelay:

So in my use case with nodelay option can make clients feel faster loading. But may hit request limit more easily. Without nodelay keep excessive requests in the burst bucket and load them in sequence. But clients may feel slow.

GeoIP Bypassing for Nginx Proxy


  • Proxy content for requests in specific country or region
  • Redirect any requests made outside specific country or region to original URL (to save bandwidth
geoip_country         /usr/share/GeoIP/GeoIPv6.dat;
map $geoip_country_code $proxy_direct_pass {
  default yes;
  CN no;

location ~* ^/proxied-content/(.*)$ {
  if ($proxy_direct_pass = yes) {
    return 302 https://original_content/$1$is_args$args;

  proxy_pass https://original_content/$1$is_args$args;

Proxying and Caching WebP Images Using the Same URI Based on User Accept Headers with Nginx


  • The proxied image backend serves WebP images when the client requests support it with Accept headers ($http_accept)
  • The backend also provides the same URI for all WebP requests. That means URI like image.png can also be in WebP format

The solution:

  • Using Nginx map module
  • Apply variables to different cache pools

In nginx.conf:

# Proxy cache pools for image caching
proxy_cache_path        /dev/shm/image_cache

proxy_cache_path        /dev/shm/image_cache_webp

# Differenate WebP requests
map $http_accept $webp_pool {
  default                 image_cache;
  ~*webp                  image_cache_webp;

In your site config:

proxy_cache             $webp_pool;

Allow WordPress Embedded Posts with Global X-Frame-Options for Nginx Servers

The problem: when you enables X-Frame-Options globally. You won’t be able to embed your posts with latest WordPress embed posts method.

The solution: you can simply exclude it in your Nginx configuration. I’ll use Nginx map for better performance:

map $request_uri $x_frame_options_headers {
  default                 SAMEORIGIN;
  # Matching WordPress embed page, ie. https://example.com/my-post/embed#?secret=vLi4CQcWkH
  ~/embed                 "";

# Don't allow the browser to render the page inside an frame or iframe
add_header X-Frame-Options $x_frame_options_headers;
Embedding Demo

SELinux policy for nginx and GitLab unix socket in Fedora 19

The installation of GitLab in Fedora 19 went fine. I followed the official installation guide with some deviations where necessary, mostly taken from the CentOS guide in gitlab-recipes. I setup nginx using the ssl config, and poked some holes in iptables. For systemd services I used these files.

Source: SELinux policy for nginx and GitLab unix socket in Fedora 19