Getting the Site to the Launch Site

Part 2 of ?

As the rather tongue-in-cheek title above states, this is the second post in a series where I build a website ‘from scratch’. I was going to use Flask, but the more I read about Django, the more I realized that’s more in line with what I want. So I’m using Python Django and Nginx, and plan to just keep it a simple web app. If I really start to fail at this and just want to get it over with, I’ll pivot to Pelican and call it good.

The point of this is to build a firm understanding of all pieces involved with building, deploying, and hosting a web app. The intent will be to detail EVERY piece, all the way to basics. It will be incredibly remedial, so don’t come to this series if you have ANY knowledge about website creation.

Setting Up The Environment

I need a Linux box that I can deploy the Django app on. Normally, I’d use my Raspberry Pi for this sort of project, but I have mOode Player on it right now and am using it as my media player, so don’t want to format it.

I have another large PC running Ubuntu that I use for my Docker host (currently only running Paperless.ngx and a Unifi controller) and a file server. (I’m not proud of the file server setup because it’s basically just an external drive with a symbolic link to a Dropbox folder, but I needed somewhere to download a TB of photos.) I thought about just spinning up another Docker container on that server and running it there, but that’s more difficult than it needs to be.

So, my website server will be an old form factor desktop running Ubuntu. I’ll set that up in a bit, but initially, I’ll be running my tests and development on my personal laptop.

So, step one is configuring Visual Studio Code. I thought about using PyCharm for this, but I want to get comfortable with using Python in VSC.

So, to start, I booted up VSC and installed the Python extension from the extension library.

Then I created a folder to host the project, and built a venv in that folder by hitting “CTRL + SHIFT + P”, then typing in ‘vir’, and selecting “Python: Create Environment”:

And created a file called ‘Initial.py’ to test that I’ve done it all correctly by running a good old fashioned “Hello World.”

Why a Virtual Environment?

As part of my intentional push to understand every piece of this process, I’ll occasionally be putting in these collapsible text boxes that will let me explore some pieces of the project more fully without cluttering up the post.

One of the features of Python is the ability to install packages1, usually using a package manager like pip. You can call pip from the command line and tell it “pip install <packagename>” and it will install it into your Python environment, ready to use.

The problem is that if you’re using Python even somewhat seriously, you can quickly start to have hundreds of packages in your base environment. Also, since I’m using the preinstalled version of Python on my Linux machine, there’s a chance that when my OS updates its version of Python, it also wipes out or replaces my installed packages if I put them in my base environment. So, spinning up a virtual environment for each project means you can install just the packages you need in each project, and they’ll stay there until you remove them.

For a MUCH deeper dive, check out Real Python’s writeup.

Now I need to verify Pip is installed. So, I call “pip3 list”, and verify that, yes, Python3 installed it as part of the package:

Now I run the command to install Django:

python3 -m pip install django~=4.0

And now I make sure it’s installed with “python3 -m django –version”:

And now we run a test site:

django-admin startproject website2023
cd website2023
python3 manage.py runserver

And look! We have a website!

Since we are breezing along so quickly, I figured it was time to take a quick break to set up the Ubuntu server. I installed Ubuntu Server 22.04.2 LTS on a that small form factor desktop. I do not recommend using a small PC like this if you’re planning on this being your permanent website, as this thing cannot handle much of a load at all. But for this project, it’s fine.

I’m not going to detail the whole basic Ubuntu server installation process as it’s incredibly well written on the Ubuntu site itself. Just follow these instructions and you’ll be ready to start running the same commands I’m running.

So, now we have a development environment for our site (on my laptop) and a server ready to host the site. It’s probably time to figure out what I want the site to show.

What Are We Building?

So, this is not intended to be a permanent site, so I’m not worried about making it exactly what I want. Instead, I want to build a bunch of different features into it to learn how they work and have some experience with them. Stuff like:

  • Some sort of web form
  • Some sort of home page
  • Some sort of dynamic picture that changes each day
  • Embedding live content
  • Updating the information on a page based on some sort of feedback
  • An Uptime Display

I don’t think that’s a complete list, but definitely a good starting spot.

Uptime

I want to take a quick aside and talk about why I never went into a full programming role or app creation role. I know how unstable all computer systems are, and the thought of trying to program something that stays up for 99% of the time was and is terrifying. You think about apps like Instagram (at least partially written in Django), and realize that it is just a bunch of python code running on a bunch of servers, and you wonder how in the world it actually works as consistently as it does. I can’t even keep my Unifi network here running consistently, and I have one switch, one router, and a modem.

So, I decided to add an uptime display onto the website to show how long it’s been up, and how often it goes down. How will I accomplish that? No idea. But it’ll be a big piece of this project.

Back to Django

Ok – Let’s step over to the Ubuntu server and set up the Django environment there. We follow the same steps as above with installing a virtual environment and all that fun stuff, including installing Django and setting up a site called ‘website2023_site’.

Some big differences include the fact that we’re going to be creating the virtual environment manually:

python3 -m venv website2023_site
source website2023_site/bin/activate
pip3 install django

We’re also going to create a superuser by using:

python manage.py createsuperuser

Follow the prompts, and we now have a superuser that can be used on the Django admin portal.

And we are going to set up the IP to be accessible outside of the server by entering:

vim ~/website2023_site/settings.py
#Edit this line: ALLOWED_HOSTS = []
#to be this:
#ALLOWED_HOSTS = ['172.xx.xx.xx']
#open port 8000
sudo ufw allow 8000
#And run the server: 
#python manage.py runserver website2023_site:8000

And hey! It’s accessible from my laptop!

And now go to http://serverip:8000/admin:

And log in with that superuser created earlier:

This allows you to manage user access and groups/permissions, and will allow app management later.

So, now, let’s make a simple home page for the app on my test PC (not the server).

I’m going to go to my terminal on my laptop, and type in “python manage.py startapp uptimemonitor”. And low and behold, we have an app:

I go ahead and add it to our settings.py file:

While we’re at it, might as well make a blog page as well with the same steps.

Now, for the blog, we’re going to create a template where we can load some html and have a nice little page. So, let’s do the following steps (putting this as a list format here because it took a heckuva lot of trial and error to get to this point, and boy howdy did I not take notes at the time):

  1. Create a folder called “templates” at the root of the website folder (website2023) in the same location as manage.py.
  2. Under the blog folder, opened the views.py file, and entered the following:
def homepage_view(request, *args, **kwargs):
    return render(request, "blog.html", {})
  1. Under the website2023 folder, add the following lines to settings.py.
import os
...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
  1. Created a file under templates called “blog.html” and made a basic webpage with an embedded weather widget. Then reloaded the home page:

And that’s where we’ll leave it for now. We have a live (test) page. Next, we will work on building the uptime widget and fleshing out the blog.


1Trying to nail down an exact definition of what a Python package is difficult. Both Real Python and Geeks for Geeks have pages of descriptions and caveats about what is and isn’t a package. But essentially, a Python package is just a folder that contains Python modules (blocks of code) that you can install onto your machine and run in your code using import statements.

Leave a comment

Design a site like this with WordPress.com
Get started