Skip to content

paulzuradzki/dash-multiapp-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dash Multi-App Demo

This application demonstrates the capabilities of Dash, a Python library for making analytic web apps.

  • This is a multi-page application with URL routing (docs).
  • Written on top of Plotly.js and React.js, Dash is a Python library for building data apps with customized user interfaces in pure Python, R, or Julia. It's particularly suited for anyone who works with data. Dash apps are rendered in the web browser. You can read more about Dash from its publisher, Plotly, here.

Demo

Instructons (Development)

These are instructions for dev purposes. For a production environment, see the detailed guide below.

$ git clone git@github.com:paulzuradzki/dash-multiapp-demo.git
$ cd dash-multiapp-demo
$ python -m venv venv

# Mac/Linux
$ source venv/bin/activate

# for Windows
$ venv\Scripts\activate.bat

$ pip install -r requirements.txt

# run application
$ python index.py

# type localhost:8000 into your browser

Python Web Application Server Setup for Production

Contents

Terms

  • supervisor enables processes to run as background services and restart when the server reboots
  • gunicorn is a Python WSGI (web server gateway interface) server which interfaces between our web app and the web server
    • a WSGI container is a separate running process that runs on a different port than your web server
    • your web server is configured to pass requests to the WSGI container which runs your web application, then it passes the response (in the form of HTML) back to the requester
  • nginx (alternative to Apache HTTP server) is a web server that responds directly to client requests

References

Assumptions


Steps

Initial user setup for server

  • Create a user and grant admin rights
  • Setup SSH for super user
  • I use the username pz-dev throughout the ReadMe demo. Modify the name to your own choosing.
    • Note: if you use a different username, make sure that you are using the correct username in config files and terminal commands throughout

Create a user and grant admin rights

$ ssh root@your_server_ip       # connect to host; you may need to replace "root" with "ubuntu"
$ adduser pz-dev                # add user
$ usermod -aG sudo pz-dev       # grant admin rights
$ su pz-dev                     # switch to new user
$ mkdir ~/.ssh                  # make this directory in USER home (not root) if it does not exists
$ touch ~/.ssh/authorized_keys                                  # make this file
$ echo {YOUR CLIENT HOST PUBLIC KEY} >> ~/.ssh/authorized_keys  # append public key info to file 
$ chmod 600 ~/.ssh/authorized_keys                              # restrict permissions to file

Secure the server

  • Disable root login
  • Disable password authentication
  • Set up firewall and rules

Modify the sshd_config file (e.g., using vim)

# /etc/ssh/sshd_config
PermitRootLogin no              # Disable root logins
PasswordAuthentication no       # Disable password logins

Restart the SSH service so that sshd_config file changes take effect. You should no longer be able to login as root nor via password after this step.

$ sudo systemctl restart ssh

For the firewall, enable SSH, HTTPS, and HTTP

$ sudo apt-get install -y ufw
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow 443/tcp
$ sudo ufw --force enable
$ sudo ufw status

Install server dependencies

$ sudo apt-get -y update
$ sudo apt-get -y install python3 python3-venv python3-dev
$ sudo apt-get -y install supervisor nginx git

Install your web application and Python dependencies

$ cd ~
$ mkdir repos
$ cd repos
# get application from GitHub
$ git clone https://github.com/paulzuradzki/dash-multiapp-demo.git

# create a virtual environment and install Python dependencies specified in requirements.txt
$ cd dash-multiapp-demo
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install --upgrade pip
(venv) $ pip install -r requirements.txt

# also install gunicorn (WSGI server)
$ pip install gunicorn

gunicorn - set up the Python WSGI (Web Service Gateway Interface) server

  • This command manually runs the app from the gunicorn WSGI server
  • The FLASK_APP environment variable is for using flask run commands; however, the Flask built-in server is not meant for production
  • gunicorn WSGI server is one step closer to production. WSGI server is an interface between our Python app and the web server that handles requests (nginx or Apache HTTP)
  • If the server were to reboot, we don't want to have to do this manually, so we will automate the restart using supervisor in a later step
  • -b localhost:8000 tells WSGI on what port we will run the app
  • The app will run on 8000. A web server (nginx) will directly receive HTTPS/HTTP requests on 443/80 and forward them to gunicorn WSGI server and the Python application
  • for index:server, index is the name of the Python module file containing the server variable. This may differ from app to app depending on how where you've created the server variable. E.g., some tutorials online may show something like app:app or app:app.server.
  • gunicorn must be called from applicaton project directory; else, provide the full path
echo "export FLASK_APP=index.py" >> ~/.profile
(venv) $ gunicorn -b localhost:8000 -w 4 index:server

# or
(venv) /home/pz-dev/repos/dash-multiapp-demo/venv/bin/gunicorn -b localhost:8000 -w 4 index:server

supervisor - set up process control

  • supervisor makes the app/gunicorn restart in case the server is rebooted; this avoids manual intervention
  • note program name ([program:index]) if you change the app structure in Flask/Dash
  • the command line is what we would
# /etc/supervisor/conf.d/dash-app.conf
[program:index]
command=/home/pz-dev/repos/dash-multiapp-demo/venv/bin/gunicorn -b localhost:8000 -w 4 index:server
directory=/home/pz-dev/repos/dash-multiapp-demo
user=pz-dev
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true

Reload supervisor after creating supervisor configuration file. You must re-run this to reload any updates to the config.

$ sudo supervisorctl reload

nginx - set up the web server

Make self-signed cert for testing

# run this command from the application directory
# ex: /home/pz-dev/repos/dash-multiapp-demo
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
  -keyout certs/key.pem -out certs/cert.pem

Remove default nginx site

$ sudo rm /etc/nginx/sites-enabled/default

Create an nginx web server configuration file for the application

# /etc/nginx/sites-enabled/dash-app

server {
    # listen on port 80 (http)
    listen 80;
    server_name _;
    location / {
        # redirect any requests to the same URL but on https
        return 301 https://$host$request_uri;
    }
}
server {
    # listen on port 443 (https)
    listen 443 ssl;
    server_name _;

    # location of the self-signed SSL certificate
    ssl_certificate /home/pz-dev/repos/dash-multiapp-demo/certs/cert.pem;
    ssl_certificate_key /home/pz-dev/repos/dash-multiapp-demo/certs/key.pem;

    # write access and error logs to /var/log
    access_log /var/log/dash_app_access.log;
    error_log /var/log/dash_app_error.log;

    location / {
        # forward application requests to the gunicorn server
        proxy_pass http://localhost:8000;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /static {
        # handle static files directly, without forwarding to the application
        alias /home/pz-dev/repos/dash-multiapp-demo/app/static;
        expires 30d;
    }
}

Restart Nginx webserver after creating

sudo service nginx reload

HTTPS and SSL Cert Setup

  • See instructions via Digital Ocean for how to set up signed SSL certificates using LetsEncrypt
  • This enables HTTPS for production deployment
  • Without HTTPS, the browser will show a warning and may prevent the user from accessing the site
  • For corporate deployments, a networking or system admin may have to provide the certificates
  • You will have to modify the nginx configuration above to re-point the ssl_certificate and ssl_certificate_key file paths
  • Link: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04

Offline Deployment Resources

Deploying Application Updates

After pulling new application code, the server must be stopped and restarted like so. Additional steps may be necessary for updating a more complicated Python app (ex: $ flask db upgrade to upgrade a database, $ flask translate compile for translations).

(venv) $ git pull                                       # download the new version
(venv) $ sudo supervisorctl stop dash-multiapp-demo     # stop the current server
(venv) $ sudo supervisorctl start dash-multiapp-demo    # start a new server

About

Demo of Dash web analytic apps with a multi-page app. Examples from Dash tutorials.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages