Skip to content

nginx Reverse Proxy Introduction

作者:Lee 等
最后更新:
字数: 539
预计阅读时间: 2 分钟

Overview

This tutorial is based on Debian, using nginx as a reverse proxy example for Docker containers already running.

Why use a reverse proxy?

The following is information found online:

A reverse proxy is a type of server that receives client requests, forwards them to web servers, and then returns the results to the client, as if the proxy server had directly handled the request itself.

A reverse proxy proxies for servers, standing on the same side as the web servers.The real servers are invisible to clients.That is why it is called "reverse".

Reverse proxy can be used for:

Protecting servers by hiding their real IP addresses. Load balancing: distributing requests among different servers according to traffic and server load. Caching static content and handling large volumes of short-lived dynamic requests. Serving as an application layer firewall for protection. Encrypting/decrypting SSL communication.

For example

For example, if we need to run three websites (a, b, c) on a server, all needing port 443, but the server has only one IP and can’t allocate three 443 ports.

At this point, reverse proxy appears: nginx takes over port 443, and routes users accessing a.leetfs.com to site a, users accessing b.leetfs.com to site b, and similarly for c.

Installation

  1. Update the system index: sudo apt update
  2. Install nginx: sudo apt install nginx

After installation is complete, Nginx will automatically start and be set to launch on boot. You can check Nginx’s status with sudo systemctl status nginx .

Configure nginx

  • Default configuration file: /etc/nginx/nginx.conf
  • Website configuration directory: /etc/nginx/sites-available/
  • Directory storing enabled configuration files: /etc/nginx/sites-enabled/

Next, we will configure nginx by modifying files in the /etc/nginx/sites-available/ directory.

Reverse proxy to docker

Our host runs the Weblate service via Docker. It would not be ideal for the container to directly take over the server's port 443, as this would restrict the port to only one service on the server.

You need to have some understanding of docker to read this section.

Configure the dockerfile

Let's look at the container's dockerfile. - 443:4443 under ports means the container listens on the server's port 443 and forwards received requests to port 4443 used by the docker container.

yaml
services:
  weblate:
    ports:
      - 443:4443
    environment:
# ...more below

First, we change port 443, the standard https port, to another unused port on the server, e.g. - 4443:4443 . After modifying, reload the container to apply the changes.

Modify nginx configuration file

Switch to the website configuration directory: /etc/nginx/sites-available/ . Create a new configuration file, named weblate in this example.

Refer to the following code for the configuration file content:

nginx
server {
    listen 443 ssl; # ssl means ssl encryption is used
    listen [::]:443 ssl;

    server_name leetfs.com; # the domain to be reverse proxied

    ssl_certificate /var/lib/docker/volumes/weblate-docker_weblate-data/_data/ssl/fullchain.pem; # ssl certificate
    ssl_certificate_key /var/lib/docker/volumes/weblate-docker_weblate-data/_data/ssl/privkey.pem; # ssl private key

    ssl_protocols TLSv1.2 TLSv1.3;  # Enable TLSv1.2 and TLSv1.3, disable SSLv3 and outdated protocols
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';  # Recommended cipher suites
    ssl_prefer_server_ciphers on;  # Prefer server cipher suites

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;

        proxy_pass https://127.0.0.1:4443; # The reverse proxy destination, set to 4443 because we set the docker port above. 127.0.0.1 means the server itself.

        # Enhance proxy security
        proxy_set_header X-Frame-Options SAMEORIGIN;
        proxy_set_header X-XSS-Protection "1; mode=block";
        proxy_set_header X-Content-Type-Options nosniff;
    }
}

After modifying the configuration file, create a symbolic link to enable it (remember to change 'weblate' to your own file name).

bash
sudo ln -s /etc/nginx/sites-available/weblate /etc/nginx/sites-enabled/
  • Test if the configuration file is correct: sudo nginx -t
  • Reload Nginx configuration: sudo systemctl reload nginx

Obtain the certificate

For the ssl_certificate and ssl_certificate_key above, you need to fill in the certificate and private key paths. Refer to Certbot: Automatically Obtain SSL Certificates.

Disable site configuration

If you want to disable a site's configuration, you only need to delete the symbolic link, without deleting the actual file. This makes it easy to reuse later.

bash
sudo rm /etc/nginx/sites-enabled/filename

After finishing, remember to reload the Nginx configuration: sudo systemctl reload nginx

Add concurrent connection/request rate limit

Place under the http block.

bash
# etc/nginx/nginx.conf

# Concurrent connection limit (no more than 20 simultaneous connections per IP)
limit_conn_zone $binary_remote_addr zone=per_ip_conn:10m;
limit_conn per_ip_conn 20;

# Request rate limit (maximum 20 requests per second per IP)
limit_req_zone $binary_remote_addr zone=per_ip_req:10m rate=20r/s;

# Burst parameter, improving user experience (no immediate rate limiting during burst access)
limit_req zone=per_ip_req burst=40 nodelay;

页面历史

布局切换

调整 VitePress 的布局样式,以适配不同的阅读习惯和屏幕环境。

全部展开
使侧边栏和内容区域占据整个屏幕的全部宽度。
全部展开,但侧边栏宽度可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
全部展开,且侧边栏和内容区域宽度均可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
原始宽度
原始的 VitePress 默认布局宽度

页面最大宽度

调整 VitePress 布局中页面的宽度,以适配不同的阅读习惯和屏幕环境。

调整页面最大宽度
一个可调整的滑块,用于选择和自定义页面最大宽度。

内容最大宽度

调整 VitePress 布局中内容区域的宽度,以适配不同的阅读习惯和屏幕环境。

调整内容最大宽度
一个可调整的滑块,用于选择和自定义内容最大宽度。

聚光灯

支持在正文中高亮当前鼠标悬停的行和元素,以优化阅读和专注困难的用户的阅读体验。

ON开启
开启聚光灯。
OFF关闭
关闭聚光灯。

聚光灯样式

调整聚光灯的样式。

置于底部
在当前鼠标悬停的元素下方添加一个纯色背景以突出显示当前鼠标悬停的位置。
置于侧边
在当前鼠标悬停的元素旁边添加一条固定的纯色线以突出显示当前鼠标悬停的位置。