Django Raspberry Pi
EDIT FROM THE FUTURE!
Some of the troubleshooting attempts in this post only seemed to work. In other words, they got me to a better error message (yay!) but then when I tried to progress, I had to go back and to re-work (boo!). Please see my next post in the series for details.
We’re trying to deploy a django app to a Raspberry Pi this week!
There are a few things we need to wire up to make this work:
- Get our python code onto the Pi.
- Get the dependencies installed on the Pi.
- Configure apache webserver to forward requests to django.
- Set up a database
- Probably other things I haven’t thought of yet.
Step 1: Get our code onto the Pi
For this, we just used rsync
. Here’s the specific command:
rsync -r . pi@raspberrypi:/home/pi/pidjango
Eventually, I might rather use some automation here, or go through git
. But
to just get it working, rsync
is a reasonable start.
Step 2: Install dependencies
I tried creating a virtual env and running python3 -m pip install .
, in order
to get the dependencies from my pyproject.toml
installed, but this failed
with an error:
$ python3 -m pip install .
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Processing /home/pi/pidjango
Installing build dependencies ... done
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.7/tokenize.py", line 447, in open
buffer = _builtin_open(filename, 'rb')
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-req-build-izgt0lqo/setup.py'
I’ve tried searching online for this error, but there’s not much of a
stacktrace, and there are literally a million things that will give you
FileNotFoundError
, so it’s really not the most helpful error. The only
surprising thing in the output is that python3.7
, which makes me think that
we’re dealing with a super old python3 install. Sure enough:
$ python3 --version
Python 3.7.3
So now let’s try to install a modern python3, on the assumption that the reason dependencies are missing files is that some module was added after Python 3.7.3 that we need.
Step 2A: Install recent Python3
EDIT FROM THE FUTURE!
This is the part that didn’t work. Instead of adding a new python, I should have done a full upgrade of the Pi, since Apache2’s mod_wsgi links against libpython. More on that in the next post in the series.
I tried just using the package manager:
$ sudo apt-get install python3
Reading package lists... Done
Building dependency tree
Reading state information... Done
python3 is already the newest version (3.7.3-1).
So that’s no help. Let’s google “install newer python on raspberry pi”. This leads me to a site that suggests I should build from source.
Here’s what that looked like:
$ wget https://www.python.org/ftp/python/3.11.4/Python-3.11.4.tgz
$ tar -zxvf Python-3.11.4.tgz
$ cd Python-3.11.4
$ ./configure
$ sudo make altinstall
This hit a snag. Because I have a dependency that’s from github directly, and
not from PyPi
, the python I build needs to be linked against openssl to
download the dependency. It turns out that what ./configure
is doing is
inspecting the system and setting a bunch of build options. This configuration
correctly detected that I didn’t have libssl-dev
installed, meaning that when
the python interpreter was being compiled, it didn’t have the opportunity to
link against C code for making https connections, but I need those to install
one of my dependencies. So I had to run sudo apt-get install libssl-dev
, then
run ./configure
and ./sudo make altinstall
again. Building Python on a
Raspberry Pi takes forever, and now I’ve done it twice, so I think one lesson might be
to pay attention to the output of ./configure
and see whehter it’s
compalining about missing libraries.
Anyway, now that I’ve built Python 3.11 on the Pi (twice!) I can go back to trying to install dependencies.
Step 2B: Keep installing dependencies
Now I can try python3.11 -m pip install .
, which hits one more snag: it fails
because there’s no README.md
in my project. This seems really silly to me,
but I added a README.md
at the root of the project, ran the install command
again, and now the dependencies are installed!
After that detour, I can go back to following pieces of the tutorial on this that I found.
Step 3: Configure Webserver
So now we’ve gotten our code and its dependencies onto the Pi. Now we need a
process that will live on the Pi and serve requests. This kind of process is
called a “server”. We’ll be using the apache2
webserver, which is a really
common one.
Basically, the goal of that exercise is to write the XML config files for the
apache2 webserver so that, when an http request comes in for the Pi, apache2
invokes our python code. The XML from the tutorial linked above doesn’t “just
work,” so I need to dig in a bit into why it isn’t working. But I’ve never
configured apach2 before. It seems like there are a bunch of XML files under
/etc/apahc2
that need to agree on things like what files should be served
and, if they’re interpreted files like python or php, how to invoke the
interpreter. I think getting that set up correctly is a bit of a deeper dive,
so I’ll work through it in the next post in the
series.
Till then, happy learning!
– Will
Love this post? Hate it? Is someone wrong on the internet? Is it me? Please feel free to @me on mastodon
I used to host comments on the blog, but have recently stopped. Previously posted comments will still appear, but for new ones please use the mastodon link above.
Discussion