Deploy a python web application to production offline server

Himanshu Pratap
2 min readJan 27, 2025

--

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

http://192.168.1.10:5000

Thats it!

--

--

Himanshu Pratap
Himanshu Pratap

Written by Himanshu Pratap

System Administrator and Full stack web developer.

No responses yet