我正在尝试为 API 设置最小 nginx 配置,但无法使 SSL/HTTPS 正常工作。
长话短说:/healthcheck
端点按预期工作,但其他任何事情都不是。
我有一个 API 应用程序与 nginx 一起在 GCE 实例上的 Docker 容器中运行。
Internet
+
|
|
v
+--------------+----------------+
| GCP |
| |
| +--------------------+ |
| |Google Load Balancer| |
| +---------+----------+ |
| | |
| | |
| | |
| v |
| +----------+------------+ |
| | Google Compute Engine | |
| | | |
| | +-------------------+ | |
| | | Server instance | | |
| | | | | |
| | | +------+ +-----+ | | |
| | | |Docker| |nginx| | | |
| | | | | +-----+ | | |
| | | | API | | | |
| | | +------+ | | |
| | +-------------------+ | |
| +-----------------------+ |
| --------------------------- |
+-------------------------------+
所有 HTTP 流量都会通过负载均衡器并到达 nginx。如果端点是,/healthcheck
它将直接转到 API(返回200 OK
),而其他所有内容都应以 HTTPS 形式通过负载均衡器路由回来。
所有 HTTPS 流量都应直接转至 API。
server
我的配置中有两个块。
第一个块:
server {
listen 80;
server_name my-domain.com;
location /healthcheck {
proxy_pass http://API_IP:8080/healthcheck;
}
location / {
return 301 https://$server_name$request_uri;
}
}
第二区块:
server {
listen 443 ssl;
server_name my-domain.com;
location / {
proxy_pass http://API_IP:8080$request_uri;
}
}
随着失眠 REST 客户端:
当我点击/healthcheck
HTTP 或 HTTPS 时,它可以工作,但/users
仅/reviews
显示错误消息Error: Couldn't resolve host name
。没有状态代码,只有此错误消息。
非常感谢任何帮助。
更新
输出自wget -S my-domain.com/users
(实际域名和IP已更改)
$ wget -S my-domain.com/users
--2018-08-30 14:09:08-- http://my-domain.com/users
Resolving my-domain.com (my-domain.com)... *IP REDACTED*
Connecting to my-domain.com (my-domain.com)|*IP REDACTED*|:80... connected.
HTTP request sent, awaiting response...
HTTP/1.1 301 Moved Permanently
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 30 Aug 2018 12:09:09 GMT
Content-Type: text/html
Content-Length: 194
Location: https://my-domain.com/users
Via: 1.1 google
Location: https://my-domain.com/users [following]
--2018-08-30 14:09:09-- https://my-domain.com/users
Resolving my-domain.com (my-domain.com)... failed: Name or service not known.
wget: unable to resolve host address ‘dev.api.godlypatruljen.no’
答案1
正确的。
我从同事那里得到了一些建议,让我走上了正确的道路。这可能不是最完美的解决方案,但它确实有效。
我server
用一新的:
server {
listen 80;
listen [::]:80;
server_name my-domain.com;
set $redirect_to_https 0;
if ($http_x_forwarded_proto != 'https') {
set $redirect_to_https 1;
}
if ($request_uri = '/healthcheck') {
set $redirect_to_https 0;
}
if ($redirect_to_https = 1) {
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://$api_ip:$api_port;
}
}
由于我需要处理一些边缘情况(服务器上的静态位置,但不在容器内等),所以我还有一些额外的location
s 和if
s(除了这里显示的之外),但这个例子应该很好地说明解决方案。