a minimal tln setup

back in 2019, i broke my desktop environment. badly. had to rebuild it up from the ground up. i wrote some fancy documentation in order to make future incidents less time-consuming.

fast forward two years, debian 11 has gone into production, i have some spare time between medical appointments while in paris (ugh), let's dist-upgrade my server. the one hosting this very web page. i call it tln. and of course it went horribly wrong. otherwise we wouldn't be here, would we?

i ran out of space during the upgrade. things got tangled, abruptly suffocating. unfathomable folders blurted out mossy data. the state of affairs went awry. and maybe i could still put it back together at this point. what tipped it over were some partitions which, for some reason, were still called after my deadname. i couldn't bother learning how to rename this trash. i burned it all.

pumping fresh blood in the machine, i took notes. it's time for a tln setup cheat sheet.

[i wrote this in 2021 and it came in really handy in 2025. i took some time to update it since there'd been hefty changes, e.g. moving from vmware to proxmox, and ditching the virtualenvwrapper mess in favour of pipenv.]

virtualware


define proxmox machine specs

  • name oriane-tln
  • check start at boot in advanced settings
  • 1 socket, 2 virtual cores
  • 3gb memory
  • 30gb storage on ssd
  • default bios, display & machine
  • scsi controller virtio scsi single
  • cd/dvd use debian 12 netinst disc image
  • start at boot set to yes (
  • network adapter
    • bridge vmbr1
    • use firewall
    • tag 10 (as if it was on vlan 10)
    • mac address automatic

restore ip address

map the new mac address to 10.10.0.15 in pfsense's dhcp server.

install operating system

follow the graphical install for debian 12. keep partitioning simple. no desktop environment needed, but get the ssh server and the standard utilities. from now on, the setup may be done over ssh.

moving in


configure sudo

su
apt install sudo
/sbin/adduser ria sudo

install utilities

sudo apt install vim git nginx rsync sqlite3 memcached python3-pip pipenv uwsgi uwsgi-plugin-python3

configure git

git config --global user.name ria4
git config --global user.email "16877076+ria4@users.noreply.github.com"

get quick access to backup server

# enable instant ssh via sudo by putting our public key on the backup server
scp -P 1992 /etc/ssh/ssh_host_ecdsa_key.pub root@10.10.0.92:/tmp/tln_oriane.pub
ssh -p 1992 root@10.10.0.92
cat /tmp/tln_oriane.pub >> /root/.ssh/authorized_keys && exit

restore configuration files

cd
sudo scp backup:/data/oriane_bak/configs/ssh_config /etc/ssh/ssh_config
sudo scp backup:/data/oriane_bak/configs/vimrc /etc/vim/vimrc
sudo scp backup:/data/oriane_bak/configs/.bash* .
sudo chown ria:ria .bashrc .bash_aliases .bash_secrets

restore web applications (see here for a devlog of tln, and here for more info about lajujabot)

# set up tln web server
sudo scp -r backup:/data/oriane_bak/tln .
sudo chown -R ria:ria tln
cd /home/ria/tln && pipenv sync

# set up lajujabot telegram bot
sudo scp -r backup:/data/oriane_bak/lajujabot /opt/lajujabot
sudo chown -R ria:ria /opt/lajujabot
cd /opt/lajujabot && pipenv sync

store passwords

# get a fresh bitwarden export from desktop
scp bitwarden_encrypted_export_202xxxxxxxxxx.json tln:

additional web server libraries


install zinnia blog engine

# pip provides django-blog-zinnia==0.20 but it is not compatible with django 3.x
# we need to import the 'develop' branch from the github repo
cd /home/ria/.virtualenvs/tln/lib/python3.9/site-packages
git clone -b develop https://github.com/Fantomas42/django-blog-zinnia
mv django-blog-zinnia/zinnia . && rm -rf django-blog-zinnia

# remove zinnia error templates in favor of nginx ones
rm zinnia/templates/{400,403,404,500}.html

install sqip placeholder creator

# v1-alpha does not seem to work anymore on debian 11; falling back to v0-legacy
# if need be, check https://github.com/axe312ger/sqip
sudo apt install npm
cd /home/ria/.local/lib
npm install sqip

web server deployment


check django project

# try running the development server
cd /home/ria/tln && pipenv shell
(vtln) python manage.py runserver 0.0.0.0:8000

interface django with nginx

# allow nginx to use tln.sock
sudo adduser www-data ria
chmod 710 /home/ria

# set up uwsgi vassals
sudo mkdir -p /etc/uwsgi/vassals
sudo ln -s /home/ria/tln/net/uwsgi.ini /etc/uwsgi/vassals/

# enable the django app
sudo ln -s /home/ria/tln/net/oriane.ink.conf /etc/nginx/sites-available/
sudo rm /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/oriane.ink.conf /etc/nginx/sites-enabled

# if things don't work (as it often happens here),
# check each step at https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html

get a certificate from let's encrypt

# the debian-packaged certbot is not guaranteed to be fresh, it's better to get the snap version
# if need be, check https://certbot.eff.org/lets-encrypt/debiantesting-nginx
sudo apt install snapd
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot

# the certbot command may modify oriane.ink.conf
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx

# remember that this cert is only used on the local network, between haproxy (via pfsense) and tln
# the actual certificate being served to web browsers is managed by the acme service running on pfsense

ensure resilience

finally, there are cronjobs to be added both via crontab -e (relaunch django & lajujabot at startup) and sudo crontab -e (run daily backups). check tln/docs/crontabs.md for instructions.