0

Stuck with a problem involving Pyramid's request urls, where request.static_url and request.application_url are 2 identifiable suspects.

The generated request urls in Pyramid somehow includes the view url when I put it on the web host, but works fine locally using pserve.

For instance:

config.add_route('signin','/view/signin')

Inside the Mako template

I have:

href="${request.static_url('project:static/blueprint/css/screen.css')}" 

which should show (using pserve):

href="http://www.site.com/static/blueprint/css/screen.css"

but instead it shows:

href="http://www.site.com/view/signin/static/blueprint/css/screen.css"

Another example is on the front page urls should show :

src = "http://www.site.com/static/img/foo.jpg"

And instead it shows:

src = "http://www.site.com//static/img/foo.jpg"

I'm currently running Pyramid 1.3 + Mako templates using nginx 0.8.53 + Phusion passenger 2.2.15 on a VPS server.

This is the same with request.application_url. In the view code I sent a dict (url = request.application_url + '/view/signin')

The url for the form should display:

action="http://www.site.com/view/signin"

Instead it shows:

action="http://www.site.com/view/signin/view/signin"

I've copied some of the nginx settings on http://wiki.pylonshq.com/display/pylonscookbook/Running+Pylons+with+NGINX.

in particular:

    #site runs on Pylons 
    location / {
        include /usr/local/nginx/conf/proxy.conf;
        proxy_pass  http://127.0.0.1:8080;
        proxy_redirect  default; 
    }

and proxy.conf:

    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;
    client_max_body_size    10m;
    client_body_buffer_size 128k;
    proxy_connect_timeout   90;
    proxy_send_timeout      90;
    proxy_read_timeout      90;
    proxy_buffer_size       4k;
    proxy_buffers           4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;

The others I've left alone as its something I didn't want to touch.

The nginx.conf on the server looks something like this. (I don't use PHP but thats the stuff I didn't want to touch).

Someone suggested to have the application served/mounted at /, but I don't know how to do that.

    server {
            listen <ip>:80;

            server_name site.com www.site.com;

            access_log /<path>/access.log combined;
            error_log /<path>/error.log error;

            root /home/<path>/public;

            index index.html index.htm index.php index.php5;
            include /home/<path>/nginx/site.com/*;

            # No mirrors - using strict redirects
            #if ($http_host != site.com) {
            rewrite ^(.*)$ http://site.com$1 permanent;
            #}

            autoindex on;

            passenger_enabled on;
            passenger_base_uri /;

            # Disallow access to config / VCS data
            location ~* /\.(ht|svn) {
                deny all;
            }

            #site runs on Pylons 
            location / {
                include /<path to conf file>/proxy.conf;
                proxy_pass  http://127.0.0.1:8080;
                proxy_redirect  default; 
            }

            # Statistics
            location /stats/ {
                alias /home/<path>/html/;
                auth_basic "Statistics Area";
                auth_basic_user_file /home/<path>/html/.htpasswd;
            }

            location /doc/analog/ {
                alias /usr/share/analog/;
            }

            # PHPMyAdmin
            rewrite ^/dh_phpmyadmin/([^/]*)/(.*)$ /dh_phpmyadmin/$2;

            location /dh_phpmyadmin/ {
                alias /dh/web/phpmyadmin/;
            }

            location ~ /dh_phpmyadmin/(.+)\.php {
                alias /dh/web/phpmyadmin/;
                fastcgi_param SERVER_PORT 80;
                fastcgi_split_path_info ^(.+\.php)(/.*)$;
                include /dh/nginx/etc/fastcgi_params;
                set $relpath "index.php";
                if ($uri ~ ^/dh_phpmyadmin/(.+)$) {
                    set $relpath $1;
                }
                fastcgi_param SCRIPT_FILENAME /dh/web/phpmyadmin/$relpath;
                fastcgi_pass unix:/home/<path>/.php.sock;
            }

            # PHP
            location ~* \.(php|php5|php4)($|/) {
                fastcgi_param SERVER_PORT 80;
                fastcgi_split_path_info ^(.+\.(?:php|php5|php4))(/.*)$;
                if (!-e $document_root$fastcgi_script_name) {
                    return 404;
                }
                include /dh/nginx/etc/fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass unix:/home/<path>/.php.sock;
                #pragma php_launch <path>
            }

        }
tshepang
  • 12,111
  • 21
  • 91
  • 136
Juan Bill
  • 11
  • 2

2 Answers2

1

It seems like your web server (passenger? I haven't used this) is not setting the environ (request.environ) correctly. This is likely a configuration option, but if you look at the environ's SCRIPT_NAME and PATH_INFO keys when visiting /view/signin you should see SCRIPT_NAME='' and PATH_INFO='/view/signin'. If this isn't the case, your application prefix may be wrong in passenger.

Michael Merickel
  • 23,153
  • 3
  • 54
  • 70
0

Your site isn't using passenger for serving pyramid. It does use a reverse_proxy instead. Unless there is a way to run passenger on the port 8080 then the passenger part in your nginx config is useless.

That said, you can have a look there:

http://kbeezie.com/view/using-python-nginx-passenger/5/

You'd have to remove this block to get it to work with passenger:

        location / {
            include /<path to conf file>/proxy.conf;
            proxy_pass  http://127.0.0.1:8080;
            proxy_redirect  default; 
        }

then you'll have to create your callable wsgi function which will call pyramid.

You'll have to define a root path for passenger to:

root /path/to/app/public/;

and put in /path/to/app/

a file called passenger_wsgi.py that has a similar content to this file

import sys
import os

def application(environ, start_response):
    start_response("200 OK", [])
    ret = ["%s: %s\n" % (key, value)
        for key, value in environ.iteritems()]
    return ret

But instead of that you'll have to call pyramid, its the entry point for your app.

That said, is there any reason why you're using passenger. Wouldn't it be easier to use something like uwsgi to deploy your app. It makes sense to deploy a ruby app with passenger but I don't see what you're getting from using passenger.

here is a good tutorial, you can skip most of the part since here there is only the nginx-uwsgi part that would make sense to you.

http://liangsun.org/2012/02/pyramid-nginx-uwsgi-mysql/

Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99