NGINX 反向代理不适用于在 Docker 中运行的 .NET 核心 webAPI [英] NGINX reverse proxy not working for .NET core webAPI running in Docker
问题描述
我在 .NET 核心中有一个简单的示例 webAPI,在 docker 容器中运行.我也在 docker 容器中运行 Nginx 作为 https 重定向的反向代理.webAPI 可以通过 http 访问,但是在访问 https url 时,API 没有响应.
I have a simple example webAPI in .NET core, running in a docker container. I'm running Nginx also in a docker container as a reverse proxy for https redirection. The webAPI is accessible on http, but when accessing the https url, the API is not responding.
我在 nginx.conf 文件中尝试了许多不同的配置.我试过使用 localhost、0.0.0.0 和 127.0.0.1.我试过使用几个不同的端口,例如 5000、8000 和 80.我试过使用上游并直接在 proxy_pass 行上指定 url.
I have tried many different configurations in the nginx.conf file. I've tried using localhost, 0.0.0.0, and 127.0.0.1. I've tried using several different ports such as 5000, 8000, and 80. I've tried using upstream and also specifying the url on the proxy_pass line directly.
docker-compose.yml:
docker-compose.yml:
version: '3.4'
networks:
blogapi-dev:
driver: bridge
services:
blogapi:
image: blogapi:latest
depends_on:
- "postgres_image"
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:80"
expose:
- "8000"
environment:
DB_CONNECTION_STRING: "host=postgres_image;port=5432;database=blogdb;username=bloguser;password=bloguser"
ASPNETCORE_ENVIRONMENT: development
#REMOTE_DEBUGGING: ${REMOTE_DEBUGGING}
networks:
- blogapi-dev
tty: true
stdin_open: true
postgres_image:
image: postgres:latest
ports:
- "5000:80"
restart: always
volumes:
- db_volume:/var/lib/postgresql/data
- ./BlogApi/dbscripts/seed.sql:/docker-entrypoint-initdb.d/seed.sql
environment:
POSTGRES_USER: "bloguser"
POSTGRES_PASSWORD: "bloguser"
POSTGRES_DB: blogdb
networks:
- blogapi-dev
nginx-proxy:
image: nginx:latest
container_name: nginx-proxy
ports:
- 80:80
- 443:443
networks:
- blogapi-dev
depends_on:
- "blogapi"
volumes:
- ./nginx-proxy/nginx.conf:/etc/nginx/nginx.conf
- ./nginx-proxy/error.log:/etc/nginx/error_log.log
- ./nginx-proxy/cache/:/etc/nginx/cache
- /etc/letsencrypt/:/etc/letsencrypt/
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./:/etc/nginx/
networks:
blogapi-dev:
driver: bridge
volumes:
db_volume:
nginx.conf:
nginx.conf:
events {}
http {
upstream backend {
server 127.0.0.1:8000;
}
server {
server_name local.website.dev;
rewrite ^(.*) https://local.website.dev$1 permanent;
}
server {
listen 443 ssl;
ssl_certificate localhost.crt;
ssl_certificate_key localhost.key;
ssl_ciphers HIGH:!aNULL:!MD5;
server_name local.website.dev;
location / {
proxy_pass http://backend;
}
}
}
Startup.cs:
Startup.cs:
namespace BlogApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING");
services.AddDbContext<BlogContext>(options =>
options.UseNpgsql(
connectionString));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
}
当我去http://127.0.0.1:8000/api/blog,浏览器从我的api返回json响应.这告诉我应用程序在端口 8000 上启动并运行,尽管它不应该通过 http 访问:
When I go to http://127.0.0.1:8000/api/blog, the browser returns the json response from my api. This tells me that the app us up and running on port 8000, although it should not be accessable via http:
[{"id":1,"title":"Title 1","body":"Body 1","timeStamp":"1999-01-08T04:05:06"},{"id":2,"title":"Title 2","body":"Body 2","timeStamp":"2000-01-08T04:05:06"},{"id":3,"title":"Title 3","body":"Body 3","timeStamp":"2001-01-08T04:05:06"},{"id":4,"title":"Title 4","body":"Body 4","timeStamp":"2002-01-08T04:05:06"}]
当我转到 127.0.0.1 时,浏览器正确重定向到 https://local.website.dev/ 但我没有得到 api 的响应,只是 chrome local.website.dev 拒绝连接.ERR_CONNECTION_REFUSED.什么时候转到 https://local.website.dev/api/blog一>.
When I go to 127.0.0.1, the browser properly redirects to https://local.website.dev/ but I get no response from the api, just the chrome local.website.dev refused to connect. ERR_CONNECTION_REFUSED. I get the same response when to go to https://local.website.dev/api/blog.
此外,这是 docker-compose up 的输出:
Also, this is the output from docker-compose up:
Starting blog_postgres_image_1 ... done
Starting blog_blogapi_1 ... done
Starting nginx-proxy ... done
Attaching to blog_postgres_image_1, blog_blogapi_1, nginx-proxy
blogapi_1 | Hosting environment: development
blogapi_1 | Content root path: /app
blogapi_1 | Now listening on: http://[::]:80
blogapi_1 | Application started. Press Ctrl+C to shut down.
postgres_image_1 | 2019-06-27 11:20:49.441 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_image_1 | 2019-06-27 11:20:49.441 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_image_1 | 2019-06-27 11:20:49.577 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_image_1 | 2019-06-27 11:20:49.826 UTC [25] LOG: database system was shut down at 2019-06-27 10:26:12 UTC
postgres_image_1 | 2019-06-27 11:20:49.893 UTC [1] LOG: database system is ready to accept connections
推荐答案
我搞定了.有几个问题.首先,我在 nginx.conf 文件的顶部缺少一些样板文件.其次,我需要将 proxy_pass 设置为包含我想要路由到的服务的 docker 容器的名称,在我的例子中是 http://blogapi/,而不是本地主机.
I got it working. There were a couple of issues. First, I was missing some boilerplate at the top of the nginx.conf file. Second, I needed to set the proxy_pass to the name of the docker container housing the service that I wanted to route to, in my case http://blogapi/, instead of localhost.
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
proxy_set_header Host $host;
proxy_pass_request_headers on;
gzip on;
gzip_proxied any;
map $sent_http_content_type $expires {
default off;
~image/ 1M;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
return 301 https://172.24.0.1$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate localhost.crt;
ssl_certificate_key localhost.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://blogapi/;
}
}
}
通过上面的配置,我可以访问webAPI在:https://172.24.0.1/api/blog/ 如果输入http://localhost/api/blog,浏览器会重定向到https://172.24.0.1/api/blog/ IP地址为blogapi的地址-dev 网桥网关如下图.
With the above configuration, I can access the webAPI at: https://172.24.0.1/api/blog/ If http://localhost/api/blog is entered, the browser will redirect to https://172.24.0.1/api/blog/ The IP address is the address of the blogapi-dev bridge network gateway as shown below.
docker 检查 20b
docker inspect 20b
"Networks": {
"blog_blogapi-dev": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"20bd90d1a80a",
"blogapi"
],
"NetworkID": "1edd39000ac3545f9a738a5df33b4ea90e082a2be86752e7aa6cd9744b72d6f0",
"EndpointID": "9201d8a1131a4179c7e0198701db2835e3a15f4cbfdac2a4a4af18804573fea9",
"Gateway": "172.24.0.1",
"IPAddress": "172.24.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:18:00:03",
"DriverOpts": null
}
}
这篇关于NGINX 反向代理不适用于在 Docker 中运行的 .NET 核心 webAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!