【问题标题】:Nginx as reverse proxy server for Nexus - can't connect in docker environmentNginx 作为 Nexus 的反向代理服务器 - 无法在 docker 环境中连接
【发布时间】:2018-04-05 02:35:13
【问题描述】:

我的环境建立在 docker 容器上(在 boot2docker 中)。我有以下 docker-compose.yml 文件来快速设置 nginx 和 nexus 服务器:

version: '3.2'

services:
  nexus:
    image: stefanprodan/nexus
    container_name: nexus
    ports:
      - 8081:8081
      - 5000:5000

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - 5043:443
    volumes:
      - /opt/dm/nginx2/nginx.conf:/etc/nginx/nginx.conf:ro

Nginx 有如下配置(nginx.conf)

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    proxy_send_timeout 120;
    proxy_read_timeout 300;
    proxy_buffering    off;
    keepalive_timeout  5 5;
    tcp_nodelay        on;

    server {
        listen         80;
        server_name    demo.com;

    return         301 https://$server_name$request_uri;
    }

    server {
        listen   443 ssl;
        server_name  demo.com;

        # allow large uploads of files - refer to nginx documentation
        client_max_body_size 1024m;

        # optimize downloading files larger than 1G - refer to nginx doc before adjusting
        #proxy_max_temp_file_size 2048m

        #ssl on;
        #ssl_certificate      /etc/nginx/ssl.crt;
        #ssl_certificate_key  /etc/nginx/ssl.key;

        location / {
            proxy_pass http://nexus:8081/;
            proxy_set_header Host $host;
            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 "https";
        }
    }
}

Nexus 似乎运作良好。我在 docker 主机上成功调用了curl http://localhost:8081。这将返回我连接登录站点的 html。现在我想试试 nginx 服务器。它被配置为侦听 443 端口,但 SSL 现在被禁用(我想在深入研究 SSL 配置之前对其进行测试)。如您所见,我的 ngix 容器将端口 443 映射到端口 5043。因此,我尝试使用以下 curl 命令:curl -v http://localhost:5043/。现在我希望我的 http 请求将被发送到 nginx 并代理到proxy_pass http://nexus:8081/; nexus。 Nexus 主机名在 docker 容器网络中可见,并且可以从 nginx 容器中访问。不幸的是,我收到了:

*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5043 (#0)
> GET / HTTP/1.1
> Host: localhost:5043
> User-Agent: curl/7.49.1
> Accept: */*
>
* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server

我正在检查 nginx 日志、错误、访问但这些日志是空的。有人可以帮我解决这个问题吗?它应该只是代理请求的一个简单示例,但也许我误解了一些概念?

【问题讨论】:

  • 日志必须存储在某个地方...试试docker-compose logs 并请显示输出。
  • 挂载目录工作正常。我猜安装不适用于这个容器。使用 $ docker logs CONTAINER_ID 检查 nginx 容器日志
  • 什么都没有,日志是空的,似乎没有什么东西在访问代理服务器
  • 你可以尝试在没有卷的情况下运行 nginx
  • 为什么?感谢音量,我有 nginx.conf 文件。没有它,我的测试将毫无意义。

标签: docker nginx nexus


【解决方案1】:

你的 5000 端口的 docker-compose 是一个动态端口(因为它没有被暴露),所以你不能连接 5000 端口,因为

ports:
      - 8081:8081
      - 5000:5000

效率不高。

你可以这样使用:

  1. 新建一个 Dockerfile 并暴露 5000 端口(我的名字是 )

    FROM sonatype/nexus3:3.16.2
    EXPOSE 5000```
    
    
  2. 使用新镜像启动容器并发布端口。

version: "3.7"
    services:
      nexus:
        image: 'feibor/nexus:3.16.2-1'
        deploy:
          placement:
            constraints:
              - node.hostname == node1
          restart_policy:
            condition: on-failure
        ports:
          - 8081:8081/tcp
          - 5000:5000/tcp
        volumes:
          - /mnt/home/opt/nexus/nexus-data:/nexus-data:z

【讨论】:

    【解决方案2】:

    您的nginx conf 中是否有upstream 指令(位于http 指令中)?

    upstream nexus {
        server <Nexus_IP>:<Nexus_Port>;
    }
    

    只有nginx 才能正确解决它。 docker-compose 服务名称 nexus 不会在运行时注入到 nginx 容器中。

    您可以在 docker-compose 中尝试links

    https://docs.docker.com/compose/compose-file/#links

    这会为您的/etc/hosts 中的链接容器提供alias但你仍然需要一个upstream directive 更新:如果可以解决,你也可以直接使用nginx directives中的名称,如location

    https://serverfault.com/questions/577370/how-can-i-use-environment-variables-in-nginx-conf

    【讨论】:

    • 实际上上游指令不是强制性的。就我而言,导致错误的原因是listen 443 ssl。没有 ssl 一切正常
    • @ArturSkrzydło true(如果名称已经可解析,upstream directive强制性的)...我更正了答案。
    【解决方案3】:

    作为@arnold 的回答,您缺少 nginx 中的上游配置。我看到您使用的是 stefanprodan nexus 映像,请参阅 his blog 了解完整配置。你可以在下面找到我的(记得打开 nexus 的 8081 和 5000 端口,即使入口点是 443)。此外,您还需要包含证书,因为 docker 客户端需要 ssl 工作:

    worker_processes 2;
    
    events {
        worker_connections 1024;
    }
    
    http {
        error_log /var/log/nginx/error.log warn;
        access_log  /dev/null;
        proxy_intercept_errors off;
        proxy_send_timeout 120;
        proxy_read_timeout 300;
    
        upstream nexus {
            server nexus:8081;
        }
    
        upstream registry {
            server nexus:5000;
        }
    
        server {
            listen 80;
            listen 443 ssl default_server;
            server_name <yourdomain>;
    
            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
            ssl_certificate /etc/letsencrypt/live/<yourdomain>/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/<yourdomain>/privkey.pem;
            ssl_session_cache shared:SSL:10m;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            ssl_dhparam /etc/ssl/certs/dhparam.pem;
            ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    
            keepalive_timeout  5 5;
            proxy_buffering    off;
    
            # allow large uploads
            client_max_body_size 1G;
    
            location / {
                # redirect to docker registry
                if ($http_user_agent ~ docker ) {
                        proxy_pass http://registry;
                }
                proxy_pass http://nexus;
                proxy_set_header Host $host;
                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 "https";
            }
        }
    }
    

    证书是使用letsencrypt 或certbot 生成的。其余的配置是在ssllabs analysis 中有一个A+,正如here 所解释的那样

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 2020-08-11
      • 2017-09-26
      • 2017-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多