最近漸漸把原本放在 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 還容易處理。