
Personal Website
Python Django SQL
I deployed my full-stack personal website to showcase hobbies and projects, fully containerised and self-hosted on a Linux machine using Python with Django, Gunicorn for the WSGI server, NGINX for the reverse proxy, PostgreSQL for the database and Cloudflare for DNS and security. Using automation, Docker and Git alongside local and development environments to efficiently test and deploy updates in real-time.
The website was originally pure HTML and CSS, but after using Django in a project at uni, I decided I would convert it to Django for more ease of use. Having Django as opposed to using modules like flask makes it a lot easier to manage a database. Each "Post" model has one-to-many relationships with "Tags" "Images" and "Videos" models. As well as the personal "Me" model has a one-to-many relationship with "Abilities", showcasing my coursework and certificate achievements.
I'm using Cloudflare to route my traffic through, this means that I don't need to expose ports on my network and use port forwarding/ static ips to host from my home network.
Another benefit of Cloudflare is their zero-trust settings, and this is how I use them to ensure my website is extra privacy-protected while deploying:
Disabling screen timeout (in settings)
Install Docker's apt repository
Install the latest docker packages
Download the latest DEB package from the website
Install the package using apt (need to be in the directory of the install .deb file)
Install Docker Compose
Start Docker
Build the image
Make a personal access token (PAT) to sign in with Github with read only permissions of contents
(this allowed me to pull the code pre-publishing) Git clone the repository (using the PAT as the password when prompted)
Run this to dockerise the tunnel with its given token
You can close and reopen the tunnel using this for a shorter command that ensures it stays connected even after a computer restart.
^ If all containers are showing green and no errors, then the setup is complete. If anything is not working, I recommend altering the .env.prod to change debug to true to help spot any issues.
(images of my lovely helpful website system administrator below) :>
The website was originally pure HTML and CSS, but after using Django in a project at uni, I decided I would convert it to Django for more ease of use. Having Django as opposed to using modules like flask makes it a lot easier to manage a database. Each "Post" model has one-to-many relationships with "Tags" "Images" and "Videos" models. As well as the personal "Me" model has a one-to-many relationship with "Abilities", showcasing my coursework and certificate achievements.
Development Log
Pre-requisites Before Deployment
Purchasing a domain
You will first need to purchase a domain to host on, I chose to use Porkbun for mine as as its cheap and easy to setup and has WHOIS privacy.I'm using Cloudflare to route my traffic through, this means that I don't need to expose ports on my network and use port forwarding/ static ips to host from my home network.
Another benefit of Cloudflare is their zero-trust settings, and this is how I use them to ensure my website is extra privacy-protected while deploying:
- Navigate to the Zero Trust dashboard
- Create a "self-hosted application" for your domain with your desired session duration time to manage access
- Add a policy to the application restricting it to your email address only
Hardware and OS setup
I opted for hosting locally as in future I want to be able to access my locally hosted services from my website. I'm using a spare Dell OptiPlex 3050 to deploy on using ethernet for the most reliable internet connection. For the OS, I opted for using Ubuntu for its stability and ease of use. I mounted the Ubuntu 24.04.2 LTS iso on a USB stick using Ventoy and set it up with my JetKVM to remote into from my main pc.Useful Initial Settings
Enable autosign in (in settings)
Settings > System > Users
unlock the panel with your password
toggle the "Automatic Login"
Disabling screen timeout (in settings)
Power>Screen Blank>Never
Installing Docker
Pre-requisite if not using gnome
sudo apt install gnome-terminal
Install Docker's apt repository
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Install the latest docker packages
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Download the latest DEB package from the website
Install the package using apt (need to be in the directory of the install .deb file)
sudo apt-get update
sudo apt-get install ./docker-desktop-amd64.deb
Install Docker Compose
sudo apt install docker-compose
Start Docker
systemctl --user start docker-desktop
Build the image
docker-compose -f docker-compose.prod.yml up --build
Pulling the code
Install git
sudo apt install git-all
Make a personal access token (PAT) to sign in with Github with read only permissions of contents
(this allowed me to pull the code pre-publishing) Git clone the repository (using the PAT as the password when prompted)
git clone https://github.com/loopymeow/website-portfolio.git
Modifying the code
Generate a secure key
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
Building the image
Configure the .env.prod settings:
#django settings
DEBUG=False
SECRET_KEY= <--(put generated key here !!)
ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0 <--(add yourdomain.your tld)
CSRF_TRUSTED_ORIGINS=http://localhost,http://127.0.0.1 <--(add https://yourdomain)
DATABASE_URL=postgres://postgres:password@db:5432/postgres
#database settings
DB_ENGINE = django.db.backends.postgresql_psycopg2
DB_NAME = postgres
DB_USERNAME = postgres
DB_PASSWORD = password
DATABASE_HOST = db
DATABASE_PORT = 5432
Connecting the webserver to the internet
- Download Cloudflared (Cloudflare daemon) and install it (for my pc using .deb amd64 version)
- Log into Cloudflare and navigate to the Zero Trust panel
- Navigate to Networks -> Tunnels -> Create a Tunnel
- Create the tunnel, giving it a custom name, and you will be given its token
Run this to dockerise the tunnel with its given token
docker run cloudflare/cloudflared:latest tunnel —no-autoupdate -run —token (token)
You can close and reopen the tunnel using this for a shorter command that ensures it stays connected even after a computer restart.
docker run -d —name cloudflared —restart unless-stopped cloudflare/cloudflared:latest tunnel run (tunnelname)

^ If all containers are showing green and no errors, then the setup is complete. If anything is not working, I recommend altering the .env.prod to change debug to true to help spot any issues.
(images of my lovely helpful website system administrator below) :>
Media:



