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 http://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
./whatsmyip.py
Then create a systemd startup script to run your web server:
A simpler variant involves using crontab:
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.
Notes
In a previous version of this blog post, I used python’s virtualenvwrapper (pacman -S python-virtualenvwrapper
) instead of pyvenv.
Resources
- 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