Boky
Boky

Reputation: 12064

How to set nginx to serve React and Django properly

I use Linux server to serve React app as frontend and Django as a backend.

The gunicorn config is as follows:

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=name
Group=www-data
WorkingDirectory=/var/www/backend/app
ExecStart=/var/www/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/name/backend.sock app.wsgi:application

[Install]
WantedBy=multi-user.target

And nginx config is as follows:

server {
    listen 80;
    root /var/www/frontend/build;
    server_name example.com;

    location = /favicon.ico { access_log off; log_not_found off; }

    location / {

    }

    location /graphql {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
        proxy_pass http://unix:/home/name/backend.sock;
    }
}

The Django app urls.py is as follows:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('reports/', include('reports.urls')),
    path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True)))
]

If I do a fetch request to www.example.com/graphql it works fine.

But if I want to access Django admin dashboard as follows www.example.com/admin/ it doesn't work.

If I understand it good, location /graphql {} means that Django apps runs on that url. Thus, If I want to access to some of the urls in urls.py file, i use www.example.com/graphql/url from urls.py

Should it not be then www.example.com/graphql/graphql

How to access admin dashboard? What I do not understand good?

Upvotes: 0

Views: 1186

Answers (1)

Flux
Flux

Reputation: 10920

Method 1

Change your urls.py to this:

from django.urls import include, path
# ... other imports ...

sub_patterns = [
    path('admin/', admin.site.urls),
    path('reports/', include('reports.urls')),
    path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True)))
]

urlpatterns = [
    path('graphql/', include(sub_patterns)),
]

Then you will be able to access the admin page at www.example.com/graphql/admin/.

Method 2

If I understand it good, location /graphql {} means that Django apps runs on that url.

Actually, no. Let's take a fictional URL as an example: www.example.com/graphql/a/b/c/. The Django URL dispatcher will see /graphql/a/b/c/ (and not just /a/b/c/ as you expected).

So to make Django see /a/b/c/ (while still ensuring that reverse() will still function correctly by reversing to /graphql/a/b/c/), you can edit your nginx configuration:

// ...
    location /graphql {
        // ...
        // Add this line:
        proxy_set_header SCRIPT_NAME /graphql;
        // ...
    }
// ...

Note: I've never used this method in production, and there could be could be some complications, so I advise you to do further research.

Upvotes: 1

Related Questions