Resources about deploying Django app on VPS or local VM

Hi everyone,

I’m searching for resources in order to learn how to deploy a Django app either on a VPS or a local VM.

I found this article :

And tried it on a Debian 10 local VM, but when I go back on Windows and search for “localhost:8000” I get nothing.

Thank you in advance for your help

When you say “local VM”, do you mean using something like VirtualBox or VMWare? Or are you talking about Windows WSL? There’s a difference between the two.

If you’re talking about a full VM (VB or VMWare), then that VM is not localhost relative to your host system. Depending upon how you’ve got networking configured, it’s going to get one or more different IP addresses assigned to it.

Hi @KenWhitesell, yes it is a local VirtualBox Machine.

So how can I proceed ?

Because when I configure my settings.py with “localhost” the server starts at 127.0.0.1 (Port 8000)

But how can I access it through my local network with other devices ?

That’s fine for your app - it shouldn’t be visible to the outside world.

You want to configure nginx to listen on all addresses. You’re going to point your browser to nginx, and it’s nginx that is going to forward the requests to your app. (That connection is through localhost.)

After you’ve got nginx configured, the ifconfig command will show you what IP address(es) are assigned to your VM. It’s that address you will use in your browser. And since nginx is typically listening on port 80, you won’t need to specify the port in the address bar.

For example, one of my VB networks uses the subnet 192.168.56.0/24. My host is 192.168.56.1. My runtime image is 192.168.56.101. When I want to connect to my runtime image, that’s what I use.

Hi @KenWhitesell,

Thank you for your answer.

Well I did configure everything, when I use :

    curl --unix-socket /run/gunicorn.sock localhost

I do get my html site output

So it works

BUT

When I entered :

> ip a
enp0s3: 
inet 10.0.2.15/24 brd 10.0.2.255

I got two IP addresses so I chose 10.0.2.255 and added it in my Django’s settings :

ALLOWED_HOSTS = ["10.0.2.255", "localhost"]

Yet, when I go back in Windows and enter 10.0.2.255 I get nothing, why ?

You don’t have two ip addresses in that output.

You have one IP address - 10.0.2.15 (subnet 10.0.2.0), and a subnet broadcast (brd) address - 10.0.2.255.

Also, since you have gunicorn listening on a unix socket, it’s not going to respond to an ip address request.

Again, in this configuration, based upon what you’re showing here, your host system will not be talking to your Django app directly. It’s communicating to nginx, which forwards the HTTP request to Django, and returns the reply.

Hmm I don’t really understand why it is not working then ? Because when I hit “10.0.2.15” I should trigger nginx which will then talk to Django and then return a reply right ?

I’m kinda lost ahah

That’s correct - assuming you have nginx listening on port 80, and all the routing and network configurations between your host and VM are right.

Have you tested any network connectivity between your host and VM?
(Can you ping from the host to the VM?)
Do you have any firewalls that might need to be opened?
Have you verified that nginx is configured to listen on that interface?
Have you tried running curl from within the VM to talk to nginx instead of gunicorn?

There are a lot of variables here, and unfortunately, it’s not going to be something easily diagnosed remotely. I can only suggest that you break this larger issue down into the smaller component issues and follow what’s happening from end to end.

The bigger picture is that this probably isn’t a Django issue, especially if you can curl from within the VM to nginx and get the appropriate reply. Being able to do so would indicate that this is more of a “SysAdmin” type issue, and perhaps more appropriately discussed in a different forum.

1 Like

You were right.

I did a ping in windows and no result for the IP adresses I gave you previously.

The solution was to configure the VM in Virtualbox as a Bridge Connection

Then I did :

ip a

and found a new adress which works 192.168.1.68 !

I now have “Welcome to Nginx !”, I have yet to find how to redirect towards my Django app ?

That depends upon your nginx configuration. Somewhere you would have a location directive that tells nginx to forward your requests to gunicorn. Step 8 in the tutorial you referenced in your original post covers it.

Hi @KenWhitesell,

According to the link above :

If Nginx displays the default page instead of proxying to your application, it usually means that you need to adjust the server_name within the /etc/nginx/sites-available/myproject file to point to your server’s IP address or domain name.

But everything is set up perfectly (the VM’s IP adress changed because I reinstalled Debian) :

theo@debianvps:~$ cat /etc/nginx/sites-available/mywebsite

server {
    listen 80;
    server_name 192.168.1.69;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/theo/mywebsite;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

Yet I still have Nginx default page instead of my Django app :frowning:

Do you have the symlink created from sites-enabled to sites-available for the mywebsite file?

Yes I already did :

sudo ln -s /etc/nginx/sites-available/mywebsite /etc/nginx/sites-enabled

And both

/etc/nginx/sites-available/mywebsite
/etc/nginx/sites-enabled/mywebsite

Have the same output (as sites-enabled is the result of the previous linking command)

Would you mind posting the output of an nginx -T command? (You’ll probably have to capture it to a file and then copy/paste the file into a post.)

Sure :

> sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

That’s weird because I now have Django that is targetted and I’m landing on “Disallowed host”

Whereas I did add 192.168.1.69 to settings.py :

ALLOWED_HOSTS = ["192.168.1.69", "localhost"]

EDIT :

It now works perfectly, I have just restarted gunicorn and nginx and then reloaded systemd daemons

sudo systemctl restart gunicorn
sudo systemctl restart nginx
sudo systemctl daemon-reload

Fantastic! Glad to see you’ve got it working.