Обратный прокси-сервер NGINX не работает для web-интерфейса ядра .NET, работающего в Docker - PullRequest
1 голос
/ 27 июня 2019

У меня есть простой пример webAPI в ядре .NET, работающий в контейнере Docker.Я запускаю Nginx также в Docker-контейнере в качестве обратного прокси для перенаправления httpsWebAPI доступен по http, но при доступе к URL-адресу https API не отвечает.

Я пробовал много разных конфигураций в файле nginx.conf.Я пытался использовать localhost, 0.0.0.0 и 127.0.0.1.Я попытался использовать несколько разных портов, таких как 5000, 8000 и 80. Я попытался использовать upstream, а также указать URL-адрес в строке proxy_pass.

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:

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:

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,, браузер возвращает ответ json из моего API,Это говорит мне о том, что приложение используется и работает на порту 8000, хотя к нему не должно быть доступа через 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.

Кроме того, это вывод из 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

1 Ответ

0 голосов
/ 28 июня 2019

Я получил это работает. Было несколько проблем. Во-первых, мне не хватало шаблона в верхней части файла nginx.conf. Во-вторых, мне нужно было задать для proxy_pass имя контейнера-докера, в котором находится служба, к которой я хотел направить, в моем случае http://blogapi/, вместо 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, как показано ниже.

Докер проверяет 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
        }
    }
...