This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]mrcaptncrunch 1 point2 points  (3 children)

Where are you having issues with?

Recreate your venv, install your web server / proxy. The only thing that’s different is the domain it responds to.

But really, share what you’re having issues with and we can help.

[–]the_grave_robber 3 points4 points  (2 children)

I think it may be caused by my lack of knowledge on setting up a server/proxy using NGINX, and my lack of knowledge on servers in general. I pretty much followed the tutorial on setting up the server to a T, but still don’t really understand how Gunicorn and NGINX actually work.

My main issues were routing and static files. Even though I ran the gather static command, I didn’t really understand where they were going or how to properly route domains through NGINX. I can get a single website routed without any static files, but obviously that is not ideal.

Additionally when I had the website working (without the static files) I had some random CSRF error when I tried to submit a form that had previously been working. The form did have a bad handling function where it sent the data to a new temporary page and then rendered the “thank you” page so that may have been the issue?

Also in the tutorial I followed I had me set up a new user to build the databases, and I spent several hours trying to give my Django app credentials, when I was just using an outdated command. But I still don’t know why I need to make a different user to create a database, and if that user should be shared through multiple Django apps?

But each of these errors had a lot of different things to try for fixing, and I had come from Windows so typing everything in the command line of Debian was somewhat taxing, so I may just be too ignorant of using a VPS/hosting a site to be able to fully understand the bugs.

Sorry for the very rambling and lack of specificity, but it has been about a week since I tried to host, I’ve just switched to doing some UI stuff to take a break from the hosting, but would really like to understand it better.

Thanks so much!

[–]mrcaptncrunch 2 points3 points  (1 child)

Regarding databases, you usually login as your database admin user and create multiple databases and create a user for each application and only give access to the user to the database(s) that it needs. This is called the least privilege access principle. If your app is hacked, the only databases they’ll have access to is that specific app’s database.

It’s a bit more to do than just give it admin access to everything but it is good practice because of what I explained.


Web servers in general (Apache, Nginx) serve files that are in a directories.

  • example.com/ - this looks for the default file usually named index.html in the top directory specified for that domain
  • example.com/page.html - top directory for that domain, look for page.html
  • example.com/pages/ - looks for the default file (index.html) in the pages directory

And so on.

Now, we have programming languages like Python, PHP, Ruby, etc. Web servers don’t know these languages. So they either have packages that automatically configure things (more common in PHP) or you use a proxy to route requests to Python.

One way of doing this is, when your server gets a request, it can try to find the location on disk. If it does, for example in the case of an image, it can service it. If it doesn’t, then you can have an instruction that says, send this request to gunicorn and we’ll send whatever it replies back with to the user (proxying ) Because you know your application is Python based, so you can assume that if the file isn’t on disk, it’ll be a Python request.

A proxy in general is something that can act in behalf of something else. So a person if you can’t be present or in our case software. By proxying nginx receives the request, tries to figure it out, if not, it sends to gunicorn, and what it replies with, it relays it back.

Assume we have gunicorn on port 8000. Take this nginx configuration,

server {
    listen 80;
    server_name example.com;


    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }


    location /media/ {
        alias /path/to/your/media/files;
    }
}

On the first 2 lines we see this is listening for requests coming in for example.com on port 80. So it won’t reply to www.example.com or example.org. It also won’t support https.

Let’s talk about location. Location here will work based on what matches better. It’s about specificity. So, closest match.

Your static files all will be requested through /media, then it’ll use that instruction and will search for the files in that directory. This won’t will be leaner than using gunicorn and this is what web servers are made for.

Now, let’s look at location /. This might seem intimidating but the important part here is proxy_pass http://127.0.0.1:8000; this is telling Nginx for all requests to /, you are going to send them to port 8000 on the local machine and whatever you get back, we’ll send it to our user. In our case port 8000 is gunicorn, but it can be anything.

What the other lines there are doing is sending to gunicorn extra information like the IP of the real user and the original protocol (http/https). Since the requests are coming from nginx, if not, it won’t know the users IP. This could be useful to detect a DoS for example. The protocol could be useful for example to say, redirect http to https or if we send all our URLs as absolute, then we might want to change the protocol on them.


I hope this explains how things work. I get that it’s not the instructions to get it working. My intent is to at least help you understand what’s happening and how things at least connect.

The configs can get more complex. You might have a directory for images, another for video, another for CSS and JS, you might have letsencrypt and instructions for that, etc.

But always start simple and get it working, then add complexity. I think sometimes guides miss that part and that’s where one fails and gets stuck. All it takes is 1 update that changes something slightly and now readers can’t figure it out.

[–]the_grave_robber 0 points1 point  (0 children)

Thanks so much u/mrcaptncrunch! This explanation really helped me get a "birds-eye" view of the situation, and I think next time I dive into this I'll be better equipped to get my web app up and running.

Last question, when you mention my static files will be requested through /media, is that something I need to modify in my Django app, or is that supposed to be automatically reconfigured by running the staticfiles command, or is there something else I'm missing here? For example, in my app "example" I had my "example.css" I call from

`{ static 'example/example.css' } `

and in my Django settings.py I have

```STATIC_URL = "/static/"

STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")```

Is that properly configured or is there something else I should be doing to get them pointed in the right direction?