Deploying a web app written in Python is not always easy. Here are a couple of easy steps to get it done on Arch Linux. These steps are not a perfect tutorial if you want to go for high traffic sites. It is more about automating the start-up of the web app when you boot up the system.
The part describing how to set up a virtual environment for Python packages is only useful if your web app depends on external Python modules. You could also install them system-wide but this way allows you to keep different versions for different software.
Here are the steps:
# Update the system pacman -Syyu # Install git pacman -S git python3 # Create a new group (if it doesn't exist) and a user account groupadd whatsmyip useradd -m -g whatsmyip -s /bin/bash whatsmyip # Log in as that user su whatsmyip cd ~/ git clone git://github.com/pklaus/WhatsMyIP.git # Set up a virtual python environment # see https://blog.philippklaus.de/2014/08/setting-up-python-venvs-on-arch-linux-arm/ python3 -m venv ~/.pyvenv/whatsmyip-3.4 source ~/.pyvenv/whatsmyip-3.4/bin/activate # Test run the python app: cd ~/WhatsMyIP/ ./whatsmyip.py
Then create a systemd startup script to run your web server:
A simpler variant involves using crontab:
su pacman -S cronie systemctl enable cronie systemctl start cronie su whatsmyip cat << "EOF" > /home/whatsmyip/start_server.sh #!/bin/bash sleep 20 source ~/.pyvenv/whatsmyip-3.4/bin/activate /home/whatsmyip/WhatsMyIP/whatsmyip.py EOF chmod +x /home/whatsmyip/start_server.sh crontab -e # -- there add: # m h dom mon dow user command @reboot /home/whatsmyip/start_server.sh
If you need the script to run on a port like 80, create the file
~whatsmyip/app/run.py like start-and-drop-privs.py and start that as root. It will start the server listening on port 80 and then drop the root privileges:
cd ~whatsmyip/app/ chmod +x run.py ./run.py
Instead, you can also run it as a local user and set up Firewall rules to forward incoming traffic directed at port 8080 to port 80:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 ip6tables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
You can read more here on how to store these firewall rules permanently. The important steps are:
cat << "EOF" > /etc/iptables/iptables.rules # Generated by iptables-save v1.4.21 on Thu Aug 3 03:16:44 2014 *nat :PREROUTING ACCEPT [93:10977] :INPUT ACCEPT [42:3823] :OUTPUT ACCEPT [16:1155] :POSTROUTING ACCEPT [16:1155] -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 COMMIT # Completed on Thu Aug 3 03:16:44 2014 EOF cat << "EOF" > /etc/iptables/ip6tables.rules # Generated by ip6tables-save v1.4.21 on Thu Aug 3 03:17:12 2014 *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [2:160] :POSTROUTING ACCEPT [2:160] -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 COMMIT # Completed on Thu Aug 3 03:17:12 2014 EOF systemctl enable iptables systemctl enable ip6tables
The nat target is available on Linux kernel 3.8+ and ip6tables v1.4.18+ according to IPV6 nat pre-routing with iptables.
In a previous version of this blog post, I used python's virtualenvwrapper (
pacman -S python-virtualenvwrapper) instead of pyvenv.
- I also wrote another blog post describing how to use systemd to run a Python (web) app. It is called: Start a Python Tool or Web App that uses Virtualenv on system startup using Systemd