Назад | Перейти на главную страницу

Сопоставление hudson с поддоменом через проксирование nginx

Теперь я пытаюсь настроить nginx в качестве обратного прокси для Hudson, чтобы он мог получить доступ на

http://build.example.com
directly. I've already installed Hudson on Tomcat and verified that I can access Hudson on
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;
    }
}

Может кто-нибудь пролить свет на это? Это должно быть очень просто настроить, но я не могу найти решение где-нибудь в сети.

Обновить

Искренне благодарю всех, кто нашел время ответить на этот вопрос. Попробовав различные решения, я думаю, что наиболее простой способ справиться с этой конкретной проблемой - это либо ...

А) Оставьте его в покое. Как предложил @VonC, пусть он останется в подкаталоге. Это просто, и мы уверены, что ничего не сломается. Или...

Б) Разверните приложение в ROOT каталога веб-приложений tomcat Возможно, это не Лучший способ сделать что-то, если вы хотите разместить несколько веб-приложений с установкой tomcat. Но администратор может захотеть установить отдельную установку tomcat, чтобы в любом случае запускать Hudson / Jenkins. Tomcat не может запускать разные размещенные приложения от имени разных пользователей, и что любой, кто настраивает Hudson / Jenkins для CI, вероятно, захочет запустить его от имени конкретного пользователя (например, «сборка»). В этом случае наиболее целесообразным является развертывание в ROOT, которое очень просто можно сопоставить с build.example.com.

Вот мой файл конфигурации nginx, хотя я обращаюсь к Hudson через https (порт 443):

Уловка с обратным прокси (Apache или Nginx) заключается в том, чтобы всегда держи тот же путь:
Если вы хотите перенаправить на a_long_and_complex_address/hudson, оставьте часть / hudson: myserver/hudson.
Не пытайтесь перенаправить myserver к a_long_and_complex_address/hudson: всевозможные скрипты и картинки с абсолютными путями ('/') будет сломано.
Перенаправить myserver/hudson к a_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/;
        }
    }
}

Судя по опыту, который я имел с 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;
}

или добавьте перенаправление, рекомендованное Алазом:

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

К сожалению, если вы не переписываете источник для hudson для извлечения файлов ресурсов по относительному пути, это ваш единственный обходной путь, если только у nginx нет плагина для модификации HTTP-потока, о котором я не знаю, например mod_proxy_html для apache ...

Скорее всего, Hudson возвращает HTML-страницу, которая ссылается на ресурсы с использованием абсолютных путей. И он вычисляет эти пути, используя «contextPath» веб-приложения (в вашем случае равный «/ hudson»).

Nginx просто передает HTML в браузер, он не изменяет содержимое страницы. Следовательно, ваш браузер запрашивает URL-адреса "/ hudson / ...".

Попробуйте добавить еще одно место в вашу конфигурацию Nginx (я не тестировал, вы должны уловить идею):

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

Если вы не хотите, чтобы ваши пользователи видели префикс "/ hudson", выполните перенаправление 301/302 для таких запросов:

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

redirect приводит к 302; permanent приводит к 301