在 docker 下,用 Nginx 做反向代理

Jiajun Xu 發表於 週六, 03/07/2020 - 03:07

最近漸漸把原本放在 GCP 上的幾個專案,遷到自己主機,然後用 docker 來管理,並挑戰用 Nginx 作為反向代理。這主要牽涉到 docker 的 network 概念,花了好幾天才比較掌握,趕快記下來以免忘記:

舉例來說,假設我運行了兩個 containers,除了作為反向代理的 Nginx 以外,另一個 container 是 Wordpress,ID 為 "example",映射在 8080 port。然後他們同處於 "mynet" 這個虛擬網路裡。以下看 docker-compose.yml

version: "3"
services:
  nginx:
    restart: unless-stopped
    image: nginx:latest
    container_name: nginx
    networks:
      - mynet
    ports:
      - 80:80
      - 443:443

  example:
    image: wordpress:latest
    container_name: example
    networks:
      - mynet
    depends_on: 
      - db
    restart: unless-stopped
    ports:
      - 8080:80

networks:
  mynet:
    external: true

如果我們直接在 host 端要連到 example 的話,位址就是 127.0.0.1:8080。

但在寫 nginx config 的時候有更好的辦法。原來,處在同一 network 的 containers,他們的 hostname 預設值就是 container id(參考文件),所以 proxy_pass 把 container id 寫進去就好了。以下是給 example 做反向代理的 nginx conf:

server {
    server_name www.example.tw;
    index index.html index.htm index.nginx-debian.html

    proxy_connect_timeout       300;
    proxy_send_timeout          300;
    proxy_read_timeout          300;
    send_timeout                300;

    location ~ / {
        proxy_redirect off;
        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 $http_x_forwarded_proto;
        proxy_set_header Host $host;

        proxy_pass http://example;
    }
}

雖然很多人都說 Nginx 反向代理很地獄,放在 docker 裡更加地獄;但搞清楚概念後,其實還比直接運行在 localhost 還容易處理。

標籤 (Tags)