Architecture Advice for Research Portal (DRF + Next.js)

I’m currently developing a research portal locally on my Mac using Django REST Framework (DRF) for the backend and Next.js for the frontend. We’re now preparing to move the project to a Test server environment.
Our university’s IT Services team has asked for deployment specifications, including whether we need two separate servers for the frontend and backend. The database will be hosted on a dedicated server, and everything will be placed behind a load balancer and firewall.

Given that this portal will host research data (real-time Data entry forms, real-time reports, etc), I’m trying to understand the best practices for security and performance:

  1. Is it recommended to host the frontend and backend on separate servers?
  2. What are the pros and cons of separating them vs. hosting both on a single server?
  3. What web servers are commonly used in this kind of setup?
  4. Are there any other security or architectural considerations I should be aware of?

You don’t separate front and back for security reasons so much as performance ones. A server that handles static files is doing a very different job from one that handles dynamic responses, so there are optimisations for both that are typically suited to different servers.

A typical self-hosted environment for example might have one server running Nginx for the static files, and another one running your application server (gunicorn, uwsgi, whatever) for handling your REST server. While you can have your application server serve your static files, it’s not a great idea, since you end up busying the server with users downloading large static files on a slow connection.

Keeping them together or apart really has no bearing on security because you should never trust the client anyway. From the application server perspective, you always have to assume that the requestor can’t be trusted and act accordingly.

There are projects like WhiteNoise that allow you to host the two projects together, but I don’t recommend it for the above reasons.

As for the kinds of services that host this stuff, your static files can live anywhere, even with a cloud-based CDN if you want. For a simple self-hosted situation, you typically see something like this:

request --> nginx -- /media  --> /some/local/folder/media
                  -- /static --> /some/local/folder/static
                  -- other   --> forward to your app server (gunicorn/uwysgi/etc.)

That’s one Nginx instance sitting between your application and the client that checks if the request includes a path to a known-to-be-static file. If yes, then it just serves the file, and if no, then it relays the request to your application server. This is crude, but for small to medium-size projects, it’s often enough.

If you’re working with a cloud provider, you can get more creative and start hosting your static files in an entirely different place like an S3 bucket. Then, with a combination of other cloud configurations I can’t remember, you can say “handle static requests with S3 and app requests should be handled by this Kubernetes pod / lambda / some rando service running on an EC2 instance / whatever”.

When considering security, I wouldn’t spend too much time worrying about the front end. As I said earlier, you have to assume that it’s been compromised anyway, so building your app with that in mind protects you in that way. Make sure that no decisions are made client side that aren’t independently validated by the server side, and you should be ok.

There are a host of security concerns for the back-end though, many of which I don’t think I have space for here. Stuff like restricting cookies to HTTPS, and other things you see in Django’s SecurityMiddleware are a good place to start (Django’s official docs are really helpful here). Over and above that, rate limiting is good for reducing brute force attacks, locking accounts with suspicious activity, etc. etc. All important stuff, and all entirely back-end related.

1 Like

Thanks a lot for the clear explanation, really helpful. Will start with a single server using Nginx to serve static files and proxy API requests to the backend, as you suggested. Appreciate the security tips as well!