1

I'm a bit stuck on how to accomplish the setup I want. Putting aside whether it's a good idea, I am trying to setup a development/test and production django application on the same server under the same domain. I am using nginx as the public-facing server, which then should send requests to the appropriate application server based on whether the url starts with the /dev/ prefix. However, I cannot get the nginx configuration quite right.

Ideally, requests to http://example.com/admin go to the production app, and http://example.com/dev/admin goes to the dev version. This way, the django urls.py is the same for both, such as:

urlpatterns = [
    path('admin/', admin.site.urls),
    ... other paths ...
]

The django apps are in docker containers, which communicate with the host machine via unix sockets. That is, I start the docker container with something like:

docker run -v /www:/host_dir me/mydocker

and in that container, the entrypoint command is:

gunicorn myapp.wsgi:application --bind=unix:/host_dir/xyz.sock

My nginx conf on the host machine looks like:

server {
    listen 80;
    listen [::]:80;
    server_name 35.231.70.176;

    location /dev {
        include proxy_params;
        proxy_pass http://unix:/www/dev.sock:;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/www/production.sock:;
    }
}

In this configuration, I get the following:

http://example.com/admin works as expected

http://example.com/dev/admin goes to the PRODUCTION admin site.

In addition to the location block above, I have tried several variants in the nginx conf (keeping the location / {...} block the same as above), including:

  1. Add slash to location:

    location /dev/ {
        include proxy_params;
        proxy_pass http://unix:/www/dev.sock:;
    } 
    
  2. Add slash to proxy_pass:

    location /dev {
        include proxy_params;
        proxy_pass http://unix:/www/dev.sock:/;
    } 
    
  3. Add slash to both location and proxy pass:

    location /dev/ {
        include proxy_params;
        proxy_pass http://unix:/www/dev.sock:/;
    } 
    

ALL of these variants end up sending http://example.com/dev/admin to the production application, so I'm confused. I thought that since it first matches the /dev block, it should send the request to the dev application, but clearly I'm not understanding.

blawney_dfci
  • 594
  • 5
  • 18
  • What happens if you kill the production gunicorn process, and try to reload the /dev/admin URL (preferably with Firefox's cache disabled)? – v25 Sep 21 '18 at 13:21
  • If I do that, I get the following reports from django's debug page (it's trying to match `admin/`): (Sorry about formatting in the comment box) case 0 (part of full nginx conf shown above): The current path, dev/admin/, didn't match any of these ---- case 1: The current path, dev/admin/, didn't match any of these. ---- case 2: The current path, /admin/, didn't match any of these. ---- case 3: 502 bad gateway, so attempting to get to production server, which is down – blawney_dfci Sep 21 '18 at 13:37
  • I'd try to add `try_files $uri /index.html`... also don't you need to `include uwsgi_params` I never used gunicorn. It could be that the proxy_params you have does that... – renno Sep 21 '18 at 13:45
  • Ok, I took a look on gunicorn and I feel like you have misconfigured the supervisor/conf.d. You have to create two separate applications and each of their paths there and create two *.conf files for each of them. Take a look here http://michal.karzynski.pl/blog/2013/10/29/serving-multiple-django-applications-with-nginx-gunicorn-supervisor/ – renno Sep 21 '18 at 13:51
  • I don't have supervisor managing any of my applications (I didn't install it in the containers). It seems like that article has a slightly different setup, which is not quite what I am after. I think the comment above about shutting down the production server was helpful in diagnosis. With the production server removed, my question reduces down to "how can requests to `http://example.com/dev/admin/` end up correctly at the `admin/` url in the django app?". The requests are clearly reaching gunicorn, but the url that django receives is always just a bit off. – blawney_dfci Sep 21 '18 at 14:05
  • [This answer](https://stackoverflow.com/a/12991235/2052575) may help you, which links to [This blog](http://archive.is/DJ9Hr) for more info. I think you need to set `proxy_set_header SCRIPT_NAME /dev;` in your `location /dev` block. – v25 Sep 21 '18 at 17:59

0 Answers0