Nginx + fossil configuration problem

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

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 D. [email protected]
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
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx


Monthadar Al Jaberi

On Wed, Nov 21, 2012 at 7:16 PM, Monthadar Al Jaberi
[email protected] 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

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 D. [email protected]

On Wed, Nov 21, 2012 at 7:53 PM, Francis D. [email protected]
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

Redirect to Location: http://localhost:8080//aaa/index

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 D. [email protected]


nginx mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx


Monthadar Al Jaberi

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 D. [email protected]

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 :slight_smile:

thank you for your help!
br,

On Wed, Nov 21, 2012 at 10:25 PM, Monthadar Al Jaberi
[email protected] 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
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx


Monthadar Al Jaberi


Monthadar Al Jaberi

On Wed, Nov 21, 2012 at 10:25:11PM +0100, Monthadar Al Jaberi wrote:

On Wed, Nov 21, 2012 at 7:53 PM, Francis D. [email protected] 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 D. [email protected]

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 :slight_smile:

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 D. [email protected]