通过 nginx 代理将 hudson 映射到子域

通过 nginx 代理将 hudson 映射到子域

我现在正尝试将 nginx 设置为 Hudson 的反向代理,以便可以访问

http://build.example.com
直接。我已经在 Tomcat 上安装了 Hudson,并验证我可以在
http://127.0.0.1:8080/hudson

很容易就能找到可以访问 Hudson 的地方http://build.example.com/hudson。但是当我尝试设置代理来重新映射 /hudson 目录时,事情开始出错。没有加载任何 css 或图像文件。

快速查看 nginx 访问日志后,我发现有大量请求正在向 /hudson 或 /hudson/static 上的资源发出。这些请求未正确转发(或重写)到 Tomcat。但经过几个小时的钻研,我还是不知道如何解决这个简单的问题。

我使用的 nginx 设置如下

server {
    listen          80;
    server_name     build.example.com;
    location / {
        proxy_pass        http://127.0.0.1:8080/hudson;
        proxy_set_header  Host             $http_host;
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}

有人能解释一下吗?设置起来应该很简单,但我似乎在网上找不到解决方案。

更新

我衷心感谢所有花时间回答这个问题的人。在尝试了各种解决方案后,我认为解决这个特定问题最直接的方法是...

A)别管它 就像@VonC 建议的那样,让它留在子目录中。这很简单,我们确信不会有什么问题。或者...

B)将应用程序部署到 tomcat webapp 目录的根目录下也许这不是最好的如果您想使用 tomcat 安装托管多个 webapp,可以采用这种方法。但管理员可能希望设置单独的 tomcat 安装以运行 Hudson/Jenkins。Tomcat 无法以不同的用户身份运行不同的托管应用程序,并且任何为 CI 设置 Hudson/Jenkins 的人都可能希望以特定用户身份运行它(例如“build”)。在这种情况下,在 ROOT 中部署最有意义,可以非常简单地映射到 build.example.com。

答案1

下面是我的 nginx 配置文件,尽管我通过 https(端口 443)访问 Hudson:

使用反向代理(Apache 或 Nginx)的技巧是始终保持相同的路径
如果您想重定向到a_long_and_complex_address/hudson保留 /hudson 部分: myserver/hudson
不要尝试重定向myservera_long_and_complex_address/hudson:各种脚本和图片,使用绝对路径(' /')会损坏。
重定向myserver/hudsona_long_and_complex_address/hudson

另外,您也可以重定向myserver/other_services到;)a_long_and_complex_address/other_services

worker_processes  1;

error_log  logs/error.log  debug;
pid        logs/nginx.pid;

events {
    worker_connections  250;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  150;
    #gzip  on;

    port_in_redirect   on;
    proxy_redirect     off;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    server {
        listen       443;
        server_name  (some alias);
        # default max client body size was 1m! => Error code is 413
        # here: max 10Go
        client_max_body_size 10000m;

        ssl                  on;
        ssl_certificate      /home/xxx/.ssl/my.crt;
        ssl_certificate_key  /home/xxx/.ssl/my.key;
        ssl_session_timeout  5m;
        #ssl_protocols SSLv2 SSLv3 TLSv1; # NO: SSLv2 prohibited
        ssl_protocols  SSLv3 TLSv1;
        ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers   on;

        rewrite ^/hudson$ https://myserver/hudson/ redirect;
        location /hudson/ {
          proxy_pass https://complex_address:8xx3/hudson/;
        }
    }
}

答案2

根据我使用 nginx 的经验,指定代理 URL 的方式有点奇怪(因为您必须指定完整的 URL,而不仅仅是目录)。我相信您的配置可以像这样:

upstream 127.0.0.1:8080 {
  ip_hash;
  server 127.0.0.1:8080;
}

location ~* ^/(.*) {
  proxy_pass http://127.0.0.1:8080/hudson/$1;
  proxy_set_header  Host             $http_host;
  proxy_set_header  X-Real-IP        $remote_addr;
  proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
}

请让我知道这对你有没有用。

编辑:要解决绝对请求,您必须添加第二个位置定义

location ~* ^/hudson/(.*) {
  proxy_pass http://127.0.0.1:8080/hudson/$1;
  proxy_set_header  Host             $http_host;
  proxy_set_header  X-Real-IP        $remote_addr;
  proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
}

或者添加 Alaz 推荐的重定向:

location /hudson {
  rewrite ^/hudson(.*)$ $1 redirect;
}

不幸的是,除非您重写 hudson 的源代码以通过相对路径检索资源文​​件,否则这是您唯一的解决方法,除非 nginx 有一个我不知道的 http 流修改插件,例如 apache 的 mod_proxy_html...

答案3

Hudson 很可能返回一个使用绝对路径引用资源的 HTML 页面。它使用 Web 应用程序的“contextPath”(在您的情况下等于“/hudson”)计算这些路径。

Nginx 只是将 HTML 传递给浏览器,它不会改变页面内容。因此您的浏览器请求“/hudson/...”URL。

尝试在您的 Nginx 配置中添加一个位置(我没有测试过,您应该明白这个想法):

location /hudson {
  rewrite ^/hudson(.*)$ $1 break;
}

如果您不希望用户看到“/hudson”前缀,请对此类请求发出 301/302 重定向:

location /hudson {
  rewrite ^/hudson(.*)$ $1 redirect;
}

redirect结果为 302;permanent结果为 301

相关内容