Let’s learn how to expose a Django demo app to the internet. That, without deploying it in a hosting service.
Configuring a staging deployment environment just to show a demo of your Django app is awful. Even more, if you only need a URL for a couple of minutes, to show it up to a client or teammate.
The best option is to use a tool to expose your current local server. Exactly! People all around the world will be able to see what’s happening on your localhost.
Before starting all the code worked on this tutorial, will be available in this Github repository.
- Python 3.6 installed in your system
- A little experience with Command-line interfaces
- Basic knowledge of Django
- Understanding of the Django-admin and manage.py scripts
It’s recommended to know all these basic things. Although it’s probable you can follow along with this tutorial, without further problems.
Creating a Django app
In order to create a step-by-step tutorial, I’ll explain the process of creating a Django project. If you already have one, you can skip this section.
First of all, let’s create a Python virtual environment.
- So open up your system terminal (or shell).
- If you find it too complicated to open your system terminal, try to use the built-in terminal of the code editor.
- Click on Terminal>New terminal, and a shell should appear at the bottom of your screen.
- Type the following command to create a virtual environment, with the built-in Python tool.
python -m venv .venv
It basically means:
Hey Python, create a virtual environment (-m venv) command with the name of .venv
- Now if you list the files of your current directory, you should see a .venv folder.
$ ls -l drwxr-xr-x - daniel 30 abr 23:12 .venv # Other files ...
- To activate the virtual environment, we call the source command.
- If you find any trouble, please refer to the following table extracted from the official python documentation.
|Platform||Shell||Command to activate virtual environment|
|POSIX||bash/zsh||$ source /bin/activate|
|fish||$ source /bin/activate.fish|
|csh/tcsh||$ source /bin/activate.csh|
|PowerShell Core||$ /bin/Activate.ps1|
|PowerShell||PS C:> ScriptsActivate.ps1|
Now if you have run the correct command, your shell should have the name of the virtual environment in it.
$ source .venv/bin/activate.fish (.venv) $
After activating your virtual environment, now you are able to install whatever Django version you want. In this case, it’s a good choice to install the latest.
$ pip install django Collecting django Using cached Django-3.2-py3-none-any.whl (7.9 MB) Collecting pytz Using cached pytz-2021.1-py2.py3-none-any.whl (510 kB) Collecting asgiref=3.3.2 Using cached asgiref-3.3.4-py3-none-any.whl (22 kB) Collecting sqlparse>=0.2.2 Using cached sqlparse-0.4.1-py3-none-any.whl (42 kB) Installing collected packages: pytz, asgiref, sqlparse, django Successfully installed asgiref-3.3.4 django-3.2 pytz-2021.1 sqlparse-0.4.1
Now it’s time to create the basic project structure of the Django app you want to expose.
$ django-admin startproject mytestingproject
This will create a Django project with the name of mytestingproject. After creating it we want you will want to enter the directory where the project structure is located. So let’s cd into it and run the Django server.
# Enter to the project directory (.venv)$ cd mytestingproject/ # Listing the files inside the project (.venv) $ ls mytestingproject manage.py
Now that you are in, let’s run the Django server to see how it looks.
(.venv) $python manage.py runserver Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. May 01, 2021 - 04:34:25 Django version 3.2, using settings 'mytestingproject.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
Basically, Django is telling us that a local server is running at our localhost (127.0.0.1 always points to it), on the default port, 8000.
Don’t worry about the error message. First, let’s check all is working fine on our local server. To do that, go to your web browser and paste this direction:
http://localhost:8000/ # Do you note that localhost and 127.0.0.1 are the same?
If everything is working fine, you should see a Django beautiful template.
That’s all about our Django installation.
Now let’s get into exposing this Django project. If you are working on a more complex project, the following methods of exposing Django apps also will work.
Exposing a Django app with Ngrok
As I said before Ngrok is one of the tools that will let us land our local server on the internet. So first of all Download Ngrok from the official website.
Once you have installed it, let’s proceed with the needed commands.
Open another shell, keeping the terminal your Django server is currently running, and type.
$ ngrok help NAME: ngrok - tunnel local ports to public URLs and inspect traffic More commands ....
This will give you a quick look at the available commands that Ngrok offers, and also will grant that the installation process went correctly.
In order to create a URL where people can access our server, let’s run.
$ ngrok http 8000
# secure public URL for port 8000 web server
We are running the http argument, to create an URL that will connect to port 8000 of our localhost.
Here is the result you’ll probably get.
ngrok by @inconshreveable (Ctrl C to quit) Session Status online Session Expires 1 hour, 59 minutes Update update available (version 2.3.39, Ctrl-U to update) Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://cac2165aa7f8.ngrok.io -> http://localhost:8000 Forwarding https://cac2165aa7f8.ngrok.io -> http://localhost:8000 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00
As it says, Ngrok is forwarding that weird and ugly URL, to our
localhost. But the magic happens, when you hit the browser with the URL Ngrok gave you.
Wow, what just happened 😱?
It seems Django is throwing an error because of a DisallowedHost setting. If you check the shell you are running the Django server in, and the one with the Ngrok session, you’ll get some debug messages.
# Django messages Invalid HTTP_HOST header: 'cac2165aa7f8.ngrok.io'. You may need to add 'cac2165aa7f8.ngrok.io' to ALLOWED_HOSTS. Bad Request: / [01/May/2021 05:07:46] "GET / HTTP/1.1" 400 65196 Invalid HTTP_HOST header: 'cac2165aa7f8.ngrok.io'. You may need to add 'cac2165aa7f8.ngrok.io' to ALLOWED_HOSTS. # Ngrok messages HTTP Requests ------------- GET /favicon.ico 400 Bad Request GET / 400 Bad Request
As Django is telling us, we must add the domain we are connecting to the ALLOWED_HOSTS config variable. But we have a problem, and it is that the domain name is too large and confusing.
So let’s change a little bit the Django settings, to solve this error. Open the settings.py file located in the project folder.
# mytestingproject/settings.py # Line 28 # Change from ALLOWED_HOSTS =  # To ALLOWED_HOSTS = ["*"]
If you know some regex, you can appreciate that we’re setting a wildcard, where all the hosts will be allowed.
Now reload the site, and see the result.
All is working perfectly now! And if you start to create applications for the project and setting URLs and views, all will be reflected on that public URL.
Note: Don’t forget to change
ALLOWED_HOSTS in production, since it would produce a huge security hole.
In this tutorial, you learned how to create a demo URL for your Django project, without the need of deploying it.
You practiced how to start a Django project and work with the
settings.py file in Django.
Finally, you learned how to use Ngrok, and how to expose any local server with it.
Next, explore some of the popular Python frameworks to build API.