Installing a Python web application in an Incus container¶
Note: Incus is a community-fork of LXD
Step 1: minimal viable¶
-
Enter the container with
sudo /etc/cncz/bin/incusexec x
-
Install the Apache web server:
sudo apt-get install apache2
, and activate the option to forward incoming requests:sudo a2enmod proxy_http
. Installing Apache should make Apache's default page visible at x.cls.ru.nl (or in some cases x.rich.ru.nl). -
Install Git and Python pip
sudo apt-get install git python3-pip
: -
Install virtualenv and create an environment in
/var/www/
:pip3 install virtualenv; virtualenv -p python3 /var/www/env
-
In
/var/www/
,git clone
your code into arepo
folder, and get it running. You most likely want to install all dependencies withpip install -r requirements.txt
. Before installing any dependencies, make sure you are inside your environment (which you can enter withsource /var/www/env/bin/activate
) -
Run your application inside a GNU screen (if you don't know how to use GNU screen, this it the time to learn :) ). In the example below we will be assume you are using the Django default port 8000, but this can of course be your favorite integer.
-
Tell Apache to forward all incoming requests to you application process, by adding this line to the config file
/etc/apache2/sites-available/000-default.conf
(inside the VirtualHost): - Restart Apache:
/etc/init.d/apache2 restart
Step 2: stable with uwsgi¶
- Create a
writable
folder and alogs
folder within it, and make sure they are writable by theubuntu
user: -
Install uwgsi:
pip3 install uwsgi
-
Activate the option to forward incoming requests to uwsgi:
sudo a2enmod proxy_uwsgi
-
Tell Apache to forward all incoming requests to you application process, by adding this line to the config file
/etc/apache2/sites-available/000-default.conf
(replaces the previous proxy pass line from step 1): -
Restart Apache:
/etc/init.d/apache2 restart
-
Create a UWSGI config file named
x.ini
with content similar to this, where x is the name of your project:You can then run the web application with[uwsgi] socket = 127.0.0.1:8000 chmod-socket = 775 chdir = /var/www/repo/x master = true binary-path = /usr/bin/uwsgi virtualenv = /var/www/env module = x.wsgi:application uid = ubuntu gid = www-data processes = 1 threads = 1 plugins-dir = /usr/lib/uwsgi/plugins logger = file:/var/www/writable/logs/x.uwsgi.log wsgi-file = /var/www/repo/x/wsgi.py env = DJANGO_SETTINGS_MODULE=x.settings static-map = /static=/var/www/repo/x/static
uwsgi x.ini
.
It's normal that it takes some time to get all the path set up correctly. The first step is to get the logging working, so uwsgi can tell you what is the next problem it encountered. As you can see in the config file, logs are written to the writable folder.
Step 3: reliable with rc.local¶
Now we want the uwsgi process to run automatically. There are two ways to do this:
Option 1: Start a screen session in a cronjob¶
-
Install GNU screen with
apt-get install screen
-
Do
crontab -e
and add this to your cron file
Option 2: Start an independent process with rc.local¶
- Create a
/etc/rc.local
file: -
Make the file executable:
chmod a+x /etc/rc.local
-
Test it by simpling running
sudo /etc/rc.local
in your terminal. -
Now test it by restarting your container. To achieve this, leave the container, so you are in Lightning again, and go
sudo /etc/bin/cncnz/bin/incusstop x; sudo /etc/bin/cncnz/bin/incusstart x;
Although rc.local is run as root, not the same environment variables are set. Therefore, you have to set them in rc.local explicitly, e.g.
Next time the container reboots, the application should be available automatically.