Deploy a python web application to production offline server
The python application is hosted using Gunicorn webserver. Since the production server does not have internet, so along with python application we also need to export python pip dependencies from dev server. Ensure that OS version on dev server (having internet connectivity) and production server (offline) are having same OS version and python version installed.
Here, we are having RHEL 8.10 on production server (offline) and RHEL 8.10 on development server (online).
Steps are as follows.
i) Generate the list of dependencies of your application on dev server
$ cd <your project folder>
$ pip freeze > /tmp/requirements.txt
ii) Create local pip repo for the list of dependencies dev server
$ mkdir /tmp/myrepo
$ cd /tmp/myrepo
$ pip download -r /tmp/requirements.txt
iii) Copy the application folder, repo folder and requirements.txt from dev server to production server
4. Deployment of Application
Execute following commands on production server:
i) Create a separate user and group for the application
# useradd -m -s /bin/bash appuser
# groupadd appgroup
# usermod -aG appgroup appuser
ii) Copy the application folder to /var/www folder
# mkdir -p /var/www/myapp
# cp -r /tmp/<application folder>/* /var/www/myapp
# chown -R appuser:appgroup /var/www/myapp
iii) create a new directory for the logs
# mkdir -p /var/log/myapp
iv) Install the dependencies
login using application user ie appuser and install the dependencies.
$ pip install — no-index — find-links=/path/to/packages *.whl
Note: Ensue gunicorn dependency is installed using root user since it will be used to host the Application
v) Create a systemd Service File
# vim /etc/systemd/system/myapp.service
[Unit]
Description=myapp
After=network.target
[Service]
User=appuser
Group=appgroup
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/gunicorn -w 8 -b 192.168.1.10:5000 app:app
Restart=always
[Install]
WantedBy=multi-user.target
vi) Reload systemd and start the service
# systemctl daemon-reload
# systemctl start myapp
# systemctl status myapp
# systemctl enable myapp
vii) Allow incoming traffic on port 5000
# firewall-cmd — zone=public — add-port=5000/tcp — permanent
# firewall-cmd — reload
viii) Test the application
Thats it!