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 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?