Recently, I had the opportunity to build and deploy a data visualization dashboard for the diversity office of the School of Architecture, Civil and Environmental Engineering (ENAC – of which I am a member).
I needed a relatively simple framework, that could be maintained by future users without much hassle, or cost, and therefore I settled on Plotly Dash. Building the application was not too difficult, but unfortunately Plotly doesn’t provide great documentation when it comes to deploying an application on your own self-hosted server.
So, this tutorial will take you on the very basic steps it takes to deploy a Plotly Dash application, written in Python, on a self-hosted Ubuntu-based server using Apache.
1. Install the required packages
Assuming your starting with a fresh server, and are logged in as sudo or as a user with sudo-equivalent rights, we will install apache2, python pip and other necessary packages (if not, run sudo apt upgrade etc).
apt upgrade
apt install apache2 python3-pip apache2-dev libapache2-mod-wsgi-py3 pipenv
2. Create a project directory
First we will create the directory of the website, which here is called websitename.
cd /var/www
mkdir websitename && websitename
3. Create a virtual environment
Then we will use pipenv to create the virtual environment in the website directory. First we need to add a line to the .bashrc file for pipenv to function. Open the file with nano.
nano ~/.bashrc
Then add the following line to the bottom of the file.
export PIPENV_VENV_IN_PROJECT=true
Press Ctrl x and then press y to save (note that the ^ symbol stands for Ctrl in nano). Then read and execute the file with source.
source ~/.bashrc
Create the virtual environment in your directory with pipenv (you should be in /var/www/websitename if not cd to your project directory).
pipenv install
ls -la
Now you should see that you have a .venv folder in your project directory but if you don’t, it may be a permission problem. So make sure the user you are using has permissions over the folder. Run the following to assign the right permissions for “your_user_name”.
sudo chown -R your_user_name:your_user_name/var/www/websitename
Then try pipenv install and check if the .venv folder is produced.
4. Use pipenv to install your required python libraries
For example, if your app uses dash, numpy, plotly, and pandas, you would run. This will create a Pipfile for your virtual environment.
pipenv install dash
pipenv install numpy
pipenv install pandas
pipenv install plotly
If you have many requirements, or are not sure which ones are required, you can use another program called pipreqs.
On your desktop run:
pip install pipreqs
#Then run the following in your project directory on your desktop
python -m pipreqs.pipreqs
This will create a requirements.txt file in your project directory on your desktop that will look like:
dash==X.XX.X
numpy==X.XX.X
pandas==X.XX.X
plotly==X.XX.X
5. Prepare your app.py file
Essentially the same thing as any plotly dash app file except for one special line of code:
server = app.server
So an example app.py would look like, with the key line being line 7:
from dash import Dash, html
app = Dash()
app.layout = [html.Div(children='Hello World')]
server = app.server ### This is what makes this work.
if __name__ == '__main__':
app.run(debug=True)
Place the app.py file in your project directory so that the path is:
/www/var/websitename/app.py
Then run pipenv:
pipenv --venv
# Which should show /var/www/websitename/.venv
6. Prepare your app.wsgi file
Create the app.wsgi file in your project directory:
sudo nano app.wsgi
Then input the following as it’s contents.
import sys
sys.path.insert(0, '/var/www/websitename')
activate_this = '/var/www/websitename/.venv/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
from app import server as application
Ctrl-x and y to save.
7. Configure Apache
Navigate to sites-available:
cd /etc/apache2/sites-available
Create a conf file:
sudo nano Websitename.conf
Then input the following, with the following notes:
- ServerName on line 2 refers to the ip of your server
- if you have a domain name, you can put it here instead
- The following are both correct:
- ServerName: 152.424.12.242
- ServerName: websitename.com
- WSGIDaemonProcess websitenamealias is an alias for the WSGIDaemon, name it what you like, but make sure that the WSGIProcessGroup uses the same name.
the ServerName on line 2 refers to the ip of your server:
<VirtualHost *:80>
ServerName 123.123.12.234
WSGIDaemonProcess websitenamealias user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/websitename/app.wsgi
<Directory /var/www/websitename>
WSGIProcessGroup websitenamealias
WSGIApplicationGroup %{GLOBAL}
Require all granted
Options ExecCGI
</Directory>
ErrorLog /var/www/websitename/error.log
CustomLog /var/www/websitename/access.log combined
</VirtualHost>
Then Ctrl x and y to save.
8. Enable the changes and launch the site
Enable the site with:
a2ensite Websitename.conf
Check the syntax with:
apachectl configtest
#Syntax OK means it worked
Then simply restart Apache for the changes to take place. If you make any changes to the wsgi file or the python app, run the following command.
service apache2 restart
Now your site should be accessible through your server’s ip or domain name!
9. What if it didn’t work?
One word.
Permissions
It’s nearly always a problem with permissions. Ensure that — typically the apache user named “www-data” — has the right permissions to read, execute files in your website’s directory.
Otherwise, check the error logs in the project directory.
Leave a Reply