A personal website built with Django, deployed on PythonAnywhere, and secured via Cloudflare.
- Markdown-rendered blog posts
- Searchable blog and archive with keyword- and tag-based filtering
- Math rendering with LaTeX
- Clean, responsive layout (Tokyo Night-inspired)
- Static pages (About, Olympiads, Pet Peeves, etc.)
- Sitemap + robots.txt for SEO
- HTTPS with HSTS via Cloudflare
- Error logging with email alerts
| Component | Tech |
|---|---|
| Backend | Django |
| Frontend | HTML, CSS, JS (Vanilla) |
| Deployment | PythonAnywhere |
| DNS & HTTPS | Cloudflare |
| Email Alerts | Gmail (SMTP + App Password) |
| Version Control | Git + GitHub |
- TLS via Cloudflare + Full HTTPS mode
- HSTS preloading with subdomain support
- Secure headers: X-Content-Type-Options, X-Frame-Options, etc.
- Django admin only accessible via superuser
- Custom error logging and rotation
Visit: https://www.bubudroid.me
git clone https://github.com/Bubu-Droid/website.git
cd website
mkdir -p cache logs
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
touch website/config.pySet up config.py with:
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "<your-secret-key>"To generate a new secret key, you may use this website.
Then run the deployment server:
python3 manage.py runserverTo enable error emails (e.g., for 500 Internal Server Errors),
add the following lines into config.py.
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = "<sender-email@gmail.com>"
EMAIL_HOST_PASSWORD = "<app-password>"
SERVER_EMAIL = EMAIL_HOST_USERAlso make sure settings.py contains:
DEBUG = False
ADMINS = [("<your-name>", "<receiver-email@gmail.com>")]Important
To generate an app password
for your <sender-email@gmail.com account,
follow this video and then
use the generated password as your <app-password>.