Running a Flask App on a Raspberry Pi in kiosk mode

Got a Flask app you want to run on a Raspberry Pi in kiosk mode? Here’s how.

Setup

Set up your Raspberry Pi to work in kiosk mode - I usually set it to go to Google or the BBC News, something I know is unlikely to fall over while I’m testing. Once you know it is working rename .xsession to xsession so that it doesn’t run automatically. This allows you to boot your pi normally and check that your app is working before you setup all the auto-booting magic.

Transfer your Flask App on to your pi. Personally I favour packaging apps as a tarball (using setuptools) and pip installing later but you don’t have to. The simplest way to get the files from your computer to your pi is probably via sftp, just set up as a normal connection using the ip of the pi and shunt files as usual. I’ve tried a variety of ftp clients and recommend Transmit (Mac), however if you’d prefer an open source alternative Cyberduck (Windows/Mac) is also very good.

Virtualenv and flask app installation

While Virtualenv isn’t strictly necessary it’s still good practice so lets grab that and set up a venv for our app

  1. Install Virtualenv using either sudo apt-get install virtualenv or pip install virtualenv.
  2. Jump into your project folder cd my/project/folder and create a Virtualenv:

    virtualenv -p python3 venv If you want a python2.* environment then you can miss out the -p python3.

  3. Activate your Virtualenv:

    cd venv source ./bin/activate

  4. Install your Flask app either using pip install your_flask_app or by installing it and it’s dependencies. NOTE: If you’re using bcrypt you will first need tosudo apt-get install python3-dev otherwise it will fail. If it still fails you may also need sudo apt-get install libffi-dev.

Uploads

If you are using uploads in your app you may need to do the following: 1. auto-mount a usb stick if present. You can skip this step if you’re using full Raspbian.

  1. identify your drive using sudo blkid
  2. create a directory for it to be mounted at, if you’re creating an app to be used by non-technical users you may want this to be somewhere obvious. I chose to put it on the Desktop for this reason: mkdir /home/pi/Desktop/usb
  3. chown it sudo chown -R pi:pi /home/pi/Desktop/usb
  4. open fstab (vim /etc/fstab) and add an entry for your drive (this should all be on one line): /dev/sda1 /home/pi/Desktop/usb vfat defaults,nofail 0 2
  5. create a symbolic link between the actual upload location and the place that Flask thinks your uploads should be. This is a really simple thing to do:
  6. locate the uploads. In my case they were at: my_app/static/images
  7. locate the place Flask is looking for them. For me this was ~/my_app/my_app/static/images
  8. if the folder exists remove it using rm -r
  9. create a symbolic link between the two ln -s /my_app/static/images ~/my_app/my_app/static/images. The -s makes this a soft link as you can’t hard link folders only files.

Now your app should be able to see your uploaded files. Start your app to make sure everything’s working.

Auto-start Virtualenv and Flask

There are a variety of ways to do this: chron (Running A Python Script At Boot Using Cron), daemons (see Getting a Python script to run in the background (as a service) on boot and http://raspberrypi.stackexchange.com/questions/12580/run-python-flask-server-from-daemon), rc.local.

Partly because cron was failing me (and I couldn’t work out why) I went with the second simplest solution which was adding the following to /etc/rc.local before exit 0:

. /home/pi/PATH_TO_VENV]/bin/activate
python /home/pi/PATH_TO_FILE_THAT_STARTS_APP.py

Reboot your pi and navigate to http://127.0.0.1:5000/ to check that everything works (or just skip this step if you’re super confident).

Auto-start Chromium in Kiosk mode

Put your .xsession file back: mv xsession .xsession Then edit it so it’s hitting http://127.0.0.1:5000/ rather than whichever random site you told it to go to before. Reboot one more time just to prove to yourself that everything is absolutely working. Do a dance[1] and go make yourself a $beverage – mines a black coffee, ta :).

[1] this is optional

Disclosure

As an Amazon Associate I earn from qualifying purchases.