Nginx代理HTTPS到Docker指定端口

  假设我在服务器上的 Docker 运行了一个应用,在 Docker 启动的时候,我指定他监听了 localhost 的 9000 端口,定向到 Docker 的 9002 的应用上。

  那么,这个应用就是运行在了 Docker 的 9002 端口上、监听者 9000 端口,我只需要访问 localhost:9000 就可以使用这个应用。

  现在把问题再复杂化一点:我有一个域名 test.jxtxzzw.com,一个 SSL 证书。

  我现在想要访问 https://test.jxtxzzw.com 就可以访问这个应用,例如这是一个云盘的应用,那么我在访问了上面这个网址的时候,就可以使用了。

  同时,这一台服务器上还运行着其他的应用,假设有博客、私有代码仓库等等。

  首先明确,直接访问 http://test.jxtxzzw.com:9000 或者 http://111.222.111.222:9000 是可以的,但是 https://test.jxtxzzw.com:9000 是不行的(而且带着端口号不好看)。

  由于我的服务器是 LNMP 环境的,所以可以使用 Nginx 反向代理到 Docker 的指定端口。

  继续阅读这篇文章之前,您最好需要熟练掌握配置 Nginx 虚拟主机的基本知识,或者说至少已经使用过几个虚拟主机的配置文件并在带有注释的情况下能看懂绝大多数配置项的含义。

  具体配置如下。

  首选确认 /usr/local/nginx/conf/nginx.conf 里面启用了 MIME 的支持。

include       /etc/nginx/mime.types;

  然后,在虚拟主机的配置文件(/usr/local/nginx/conf/vhost/test.jxtxzzw.com.conf)里面加上:

default_type  application/octet-stream;

upstream test.jxtxzzw.com {
server localhost:9000;
}

  然后首先配置 HTTP 访问。

# http
server
{
listen 80;
server_name test.jxtxzzw.com;

# Force redirect to https
# If you dont want https force redirect, comment out the rewrite line
rewrite ^/(.*) https://$server_name/$1 permanent;

location / {
proxy_pass http://test.jxtxzzw.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

  这里的关键是 4 个 proxy。

  然后是 HTTPS 访问。也是一样的,只是监听端口变成了 443,然后需要指定 SSL(.crt 或者 .pem)。当然,还可以进行更多的 SSL 的配置,比如 session timeout 等。

ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;

  proxy_pass 还是到 HTTP,不需要 https://test.jxtxzzw.com。

# https
server
{
listen 443 ssl;
server_name test.jxtxzzw.com;
ssl_certificate /home/wwwcert/test.jxtxzzw.com.pem; # .crt or .pem
ssl_certificate_key /home/wwwcert/test.jxtxzzw.com.key;
location / {
proxy_pass http://test.jxtxzzw.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

  你已经发现了,本质上,这是利用了 Nginx 的负载均衡,有点杀鸡用牛刀的感觉。

  但是问题不大,只有一台服务器的话,那就是 100% 负载了嘛。

  了解更多 Nginx 负载均衡的配置,请自行谷歌。