Nginx作为Nexus的反向代理服务器 - 无法在docker环境中连接

时间:2017-10-24 10:26:06

标签: docker nginx nexus

我在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。这返回我的nexus登录网站的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日志,错误,访问但这些日志是空的。有人可以帮我解决这个问题吗?它应该只是一个代理请求的简单例子,但也许我误解了一些概念?

3 个答案:

答案 0 :(得分:2)

您的nodeIp:nodePort upstream中是否有nginx指令(位于conf指令内)?

http

只有upstream nexus { server <Nexus_IP>:<Nexus_Port>; } 才能正确解析它。 nginx服务名称docker-compose未在运行时注入nexus容器。

您可以在docker-compose中尝试nginx

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

这为您links中的关联容器提供alias但您仍然需要/etc/hosts 更新:如果可以解析,您也可以直接在upstream directive nginx directives中使用这些名称

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

答案 1 :(得分:1)

正如@ arnold的回答,你错过了nginx中的上游配置。我看到你正在使用stefanprodan nexus图像,请参阅his blog了解完整配置。下面你可以找到我的(记得打开端口8081和5000的nexus甚至入口点是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

答案 2 :(得分:0)

您的由docker-compose组成的5000端口是一个动态端口(因为尚未公开),因此您无法连接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