Forum: NGINX nginx + fossil configuration problem

Posted by Monthadar Al Jaberi (Guest)
on 2012-11-20 22:29
(Received via mailing list)
Hi,

I am new to nginx. My issue is with nginx configuration that should
proxy a connection to a fossil server I am running in the background.
This fossil server is serving a folder of fossils.

I found example configuration on the net and I ended up having this:

   ....
    server {
        listen       80;
        server_name locahost;

        location / {
            proxy_pass http://localhost:8080/;
            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;
        }
    }
    ....

I started from the original nginx.conf file in /etc/nginx. I am
running nginx in ArchLinux with minimum packages installed (no X). I
am starting nginx with systemd. And for now I am starting fossil
manually: fossil server /path/to/fossils/

From my host PC I seem to be able to visit my different fossil
projects 192.168.0.101/aaa and 192.168.0.101/bbb.

But this seems to be accidental, because if I move this server block
under the default server blocks it stops working. If I have it above I
cant seems to access the php location block in the default server
block that I added, 192.169.0.101/index.php don't work.

Testing from withing the archlinux running nginx:
localhost/
localhost/index.html
localhost/index.php

All of these works. But localhost/aaa don't work.  If I run the
following it works:

lynx localhost:8080/aaa

It seems I am missing some last touch. I want to be able to do
something like 192.168.0.101/fossil/aaa.

Thank you for any advice!

attaching the whole nginx.conf:
#user html;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    server_names_hash_bucket_size 64;

    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  65;

    #gzip  on;

    server {
        listen       80;
  server_name locahost;

  location / {
            proxy_pass http://localhost:8080/;
            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       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

  #location /fossil/ {
        #    proxy_pass http://localhost:8080/;
        #    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;
        #}

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 
127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME 
/scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

  location ~ \.php$ {
      fastcgi_pass  unix:/var/run/php-fpm/php-fpm.sock;
      fastcgi_index index.php;
      root          /usr/share/nginx/html;
      include       fastcgi.conf;
  }


    # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based 
configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers   on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

--
Monthadar Al Jaberi
Posted by Francis Daly (Guest)
on 2012-11-21 00:25
(Received via mailing list)
On Tue, Nov 20, 2012 at 10:29:04PM +0100, Monthadar Al Jaberi wrote:

Hi there,

This isn't a full answer, but hopefully will point you in the right
direction.

>     server {
>         listen       80;
>         server_name locahost;

That is "locahost", not "localhost". That is the reason that the order
of server{} blocks matters.

>         location / {
>             proxy_pass http://localhost:8080/;
...

> From my host PC I seem to be able to visit my different fossil
> projects 192.168.0.101/aaa and 192.168.0.101/bbb.

If that much works, then you've got a good start.

> But this seems to be accidental, because if I move this server block
> under the default server blocks it stops working.

Not quite: because you have the same "listen" directive in each block,
whichever is first in the file *is* the default.

(http://nginx.org/en/docs/http/server_names.html probably includes more
than you want to know.)

So: when this is the default server block, your fossil access works;
when it isn't, it doesn't. That is down to how nginx chooses which one
server block to use for this request.

> If I have it above I
> cant seems to access the php location block in the default server
> block that I added, 192.169.0.101/index.php don't work.

One request is handled in one server block (usually chosen by comparing
the Host: header with the server_name value), and then in one location
within that server.

Your configuration either uses too many server blocks, or ones with
incorrect server_names.

> Testing from withing the archlinux running nginx:
> localhost/
> localhost/index.html
> localhost/index.php

Those will all use the one server block that has "server_name localhost"
which, below, says "php goes to php-fpm.sock, all else goes to the
filesystem".

> All of these works. But localhost/aaa don't work.

That will also use that same server block. So it will serve files from
/usr/local/nginx/html/aaa.

> If I run the
> following it works:
>
> lynx localhost:8080/aaa

That will use the fossil service directly, avoiding nginx.

> It seems I am missing some last touch. I want to be able to do
> something like 192.168.0.101/fossil/aaa.

Decide exactly what url hierarchy you want to use to access nginx to
reverse proxy to fossil.

That means: which hostname and which /location prefix or prefixes.

Then in the correct server{} block, add the location{} block with the
proxy_pass stuff that you have that already works.

If you want to use *different* hostnames to access fossil and 
not-fossil,
then you will need to configure location{} blocks in different server{}
blocks.

If you want to use the *same* hostname to access fossil and not-fossil,
then you will need to configure different location{} blocks in the same
server{} block to tell nginx which urls should go to fossil and which
ones should not.

Briefly: move your (working) "location /" block into the "server_name
localhost" server block, and change it to be (perhaps) "location /aaa".

That might show whether you are moving in the right direction.

Good luck,

  f
--
Francis Daly        francis@daoine.org
Posted by Monthadar Al Jaberi (Guest)
on 2012-11-21 19:17
(Received via mailing list)
Thank you for your explanations!

The "locahost" error is from my side, I was testing different things
and didn't notice. Sorry.

Okej now I understand, I guess I want one server block, no sense in
having fossil.localhost.

So I want localhost/fossil/aaa.

I moved the working location block inside the default server block:

server {
        listen       80;
        server_name  localhost;
  location /fossil/ {
            proxy_pass http://localhost:8080/;
            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;
        }
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
  location ~ \.php$ {
      fastcgi_pass  unix:/var/run/php-fpm/php-fpm.sock;
      fastcgi_index index.php;
      root          /usr/share/nginx/html;
      include       fastcgi.conf;
  }
    }

Now all my other cases work except the fossil one.

When I browse to localhost/fossil/aaa I see that the link changes to:

 http://localhost//aaa/index

An extra '/' is added somehow. The page I get is from nginx 404, which
I suppose means nginx did not proxy the request??

best regards,

On Wed, Nov 21, 2012 at 12:24 AM, Francis Daly <francis@daoine.org> 
wrote:
>
> If that much works, then you've got a good start.
> So: when this is the default server block, your fossil access works;
>
> filesystem".
>
> Then in the correct server{} block, add the location{} block with the
>
>
> _______________________________________________
> nginx mailing list
> nginx@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx



--
Monthadar Al Jaberi
Posted by Monthadar Al Jaberi (Guest)
on 2012-11-21 19:33
(Received via mailing list)
On Wed, Nov 21, 2012 at 7:16 PM, Monthadar Al Jaberi
<monthadar@gmail.com> wrote:
> I moved the working location block inside the default server block:
>
> server {
>         listen       80;
>         server_name  localhost;
my bad remove the last slash after fossil below:
>         }
>     }
> best regards,
>>>         listen       80;
>>> projects 192.168.0.101/aaa and 192.168.0.101/bbb.
>> than you want to know.)
>> the Host: header with the server_name value), and then in one location
>> Those will all use the one server block that has "server_name localhost"
>>>
>> That means: which hostname and which /location prefix or prefixes.
>> server{} block to tell nginx which urls should go to fossil and which
>> --
> Monthadar Al Jaberi
--
Monthadar Al Jaberi
Posted by Francis Daly (Guest)
on 2012-11-21 19:54
(Received via mailing list)
On Wed, Nov 21, 2012 at 07:16:41PM +0100, Monthadar Al Jaberi wrote:

Hi there,

> So I want localhost/fossil/aaa.
>
> I moved the working location block inside the default server block:
>

>   location /fossil/ {
>             proxy_pass http://localhost:8080/;

>   }

> Now all my other cases work except the fossil one.
>
> When I browse to localhost/fossil/aaa I see that the link changes to:
>
>  http://localhost//aaa/index
>
> An extra '/' is added somehow. The page I get is from nginx 404, which
> I suppose means nginx did not proxy the request??

No, nginx sent the request to fossil, which responded with a http 
redirect
to this url. Then your browser asks nginx for //aaa/index, which does
not exist as a file in the right place, hence 404.

  curl -i http://localhost/fossil/aaa

to see exactly what comes back.

What you (probably) want is for that redirect to be to 
/fossil/aaa/index,
which is (ideally) down to the fossil configuration.

Newer versions of fossil tend to handle things a bit better; possibly
setting baseurl to http://localhost/fossil (or maybe just /fossil)
when you start the fossil service will allow things to work for you.

Good luck with it,

  f
--
Francis Daly        francis@daoine.org
Posted by Monthadar Al Jaberi (Guest)
on 2012-11-21 22:26
(Received via mailing list)
On Wed, Nov 21, 2012 at 7:53 PM, Francis Daly <francis@daoine.org> 
wrote:
>>             proxy_pass http://localhost:8080/;
>> I suppose means nginx did not proxy the request??
>
> No, nginx sent the request to fossil, which responded with a http redirect
> to this url. Then your browser asks nginx for //aaa/index, which does
> not exist as a file in the right place, hence 404.
>
>   curl -i http://localhost/fossil/aaa

I changed this line:

proxy_set_header Host $host;

to:

proxy_set_header Host $host:$proxy_port;

And curl -i http://localhost/fossil/aaa returns:

HTTP/1.1 302 Moved Temporarily
Server: nginx/1.2.5
Date: Wed, 21 Nov 2012 21:22:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 79
Connection: keep-alive
Location: http://localhost:8080//aaa/index
X-Frame-Options: SAMEORIGIN
Cache-control: no-cache

<html>
<p>Redirect to Location: http://localhost:8080//aaa/index
</p>
</html>

So this redirection is just before calling fossil? Where do the extra
'/' come from? I read a litte more and found a directive called
rewrite, should I use it somehow to remove the xtra slash added?

thnx

> Good luck with it,
>
>         f
> --
> Francis Daly        francis@daoine.org
>
> _______________________________________________
> nginx mailing list
> nginx@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx



--
Monthadar Al Jaberi
Posted by Monthadar Al Jaberi (Guest)
on 2012-11-21 22:44
(Received via mailing list)
I think I got it to work using rewrite.

location /fossil {
            rewrite /fossil/(.*) /$1 break;
            proxy_pass http://localhost:8080;
            proxy_redirect off;
            proxy_set_header Host $host:$proxy_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }


I hope this is a sane solution :)

thank you for your help!
br,

On Wed, Nov 21, 2012 at 10:25 PM, Monthadar Al Jaberi
<monthadar@gmail.com> wrote:
>>>       location /fossil/ {
>>> An extra '/' is added somehow. The page I get is from nginx 404, which
> proxy_set_header Host $host;
> Content-Type: text/html; charset=utf-8
>
>> which is (ideally) down to the fossil configuration.
>>
>> _______________________________________________
>> nginx mailing list
>> nginx@nginx.org
>> http://mailman.nginx.org/mailman/listinfo/nginx
>
>
>
> --
> Monthadar Al Jaberi



--
Monthadar Al Jaberi
Posted by Francis Daly (Guest)
on 2012-11-21 23:19
(Received via mailing list)
On Wed, Nov 21, 2012 at 10:25:11PM +0100, Monthadar Al Jaberi wrote:
> On Wed, Nov 21, 2012 at 7:53 PM, Francis Daly <francis@daoine.org> wrote:

Hi there,

> I changed this line:
>
> proxy_set_header Host $host;
>
> to:
>
> proxy_set_header Host $host:$proxy_port;

I'd undo that change. It effectively means that you are bypassing nginx
and going to fossil directly, which is probably not what you want.

> So this redirection is just before calling fossil?

No. The redirection is what the fossil server returned.

Your nginx configuration was (almost) correct. I suggest to put it back
the way it was, and then start configuring fossil to be reverse-proxied.

> Where do the extra '/' come from?

You changed "location /fossil/" to "location /fossil". The difference
there is the extra / here.

> I read a litte more and found a directive called
> rewrite, should I use it somehow to remove the xtra slash added?

No.

  f
--
Francis Daly        francis@daoine.org
Posted by Francis Daly (Guest)
on 2012-11-21 23:43
(Received via mailing list)
On Wed, Nov 21, 2012 at 10:44:11PM +0100, Monthadar Al Jaberi wrote:

Hi there,

> I think I got it to work using rewrite.

I think you are bypassing nginx. That's fine if you want to; but in that
case you could have just gone to fossil directly in the first place.

Try http://192.168.0.101/fossil/aaa

If you see "8080" in your browser bar, you're not using nginx.

> location /fossil {

Change that to "location /fossil/ {" or (better) "location ^~ /fossil/ 
{"

>             rewrite /fossil/(.*) /$1 break;

Remove that.

>             proxy_pass http://localhost:8080;
>             proxy_redirect off;
>             proxy_set_header Host $host:$proxy_port;

Change that back to "proxy_set_header Host $host;"

>             proxy_set_header X-Real-IP $remote_addr;
>             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

I don't think those lines make any difference to fossil. It's clearer
to remove them, too.

>         }
>
>
> I hope this is a sane solution :)

I don't think that it will work from off your own server.

If it does what you want, then it is good enough. But I think that when
you test from another machine, you will see a problem.

Even after you put it back the way it was, you still will not see it 
work
cleanly, because your fossil is not configured to be reverse proxied at
a different url. By that, I mean: you request http://server/fossil/aaa,
but fossil returns links and redirections assuming that you requested
http://server/aaa (which, as far as fossil is concerned, you did).

The current way to adjust fossil to be reverse proxied at a different
place in the url hierarchy seems to be to start it like

  SCRIPT_NAME=/fossil fossil server /path/to/fossils/

(and that means that you won't be able to access it directly at
http://localhost:8080/aaa).

  f
--
Francis Daly        francis@daoine.org
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.