Docker – haproxy forward uri to root of another server

dockerhaproxy

I use a HAPROXY container as an entry point for a virtual HPC cluster. Depending
on a prefix the request is forwarded to different containers.

:80/foswiki/ -> :80/foswiki/
:80/kibana/ -> :80/kibana/
:80/graphite-api/ -> :80/graphite-api/
...

The config I use is pretty simple:

frontend http-in
    bind *:80
    acl uri_foswiki path_beg /foswiki
    use_backend srv_foswiki if uri_foswiki
    # gitlab
    default_backend srv_gitlab

backend srv_foswiki
    balance roundrobin
    cookie SERVERID insert
    option httpclose
    option forwardfor
    server foswiki 172.17.0.3:80 cookie

The thing is that there are webserver that serve the website directly as root, without a prefix. 'Graphite-web', e.g. or the gitlab image.

I try to cut the prefix and forward it further, but what I really want, is that the haproxy keeps the prefix in the path and that it is transparent to the backends server.
If I click on 'gitlab_server:80/dashboard/' it shoult come out as 'frontend_ip:80/gitlab/dashboard'.

backend srv_gitlab
    balance roundrobin
    #cookie SERVERID insert
    mode http
    reqrep ^([^\ ]*)\ /gitlab/(.*)     \1\ /\2
    balance roundrobin
    option forwardfor
    server gitlab 172.17.0.18:80 cookie

I don't think it is a hard thing to do, but it seems to me, that my google skills are somewhat crippled. Every time I end up with rewrite rules that do not keep the prefix.

Anyone?
Christian

EDIT: The internal IP addresses are not reachable by the user…

Best Answer

To get rid of leading parts of the URI, try

reqrep ^(GET|POST)\ /gitlab/(.*) \1\ /\2

i.e., extract the HTTP method into \1 and the path following the gitlab root into \2, then catenate them to a full request.

Note that this may not cut it for many applications, because the appserver doesn't know that clients are supposed to request everything from inside a virtual gitlab/ root directory. Therefor, redirects will apparently "strip" the important root directory.

Such scenarios are solved more easily e.g. with nginx and its mod_proxy or even Apache.

Related Topic