Created a Dash app with impressive visualizations and ready to share it with others? GitHub Pages is an excellent platform for hosting your app! Follow these steps to deploy your Dash app using GitHub Actions:
Set up a public GitHub repository (similar to this one) and add a file app.py
to store the code for your Dash app. In order to deploy your Dash app from Github Actions you need to update your repository's setting: go to settings -> Pages
and set Source
to GitHub Actions
(under Build and deployment
).
DISCLAIMER: Since Github Pages can only store static files, you need to use clientside callbacks. In order to turn a callback into a clientside callback, you need to rewrite it with JavaScript (example clientside callback has been put in app.py
). More info on clientside callbacks can be found here.
To make working with the files easier, create a Makefile. Add a file named Makefile to the root directory of your repository and include the following code (be sure to replace all instances of dash-actions-tutorial with your repository's name):
run_app:
python3 app.py & sleep 30
wget -r http://127.0.0.1:8050/
wget -r http://127.0.0.1:8050/_dash-layout
wget -r http://127.0.0.1:8050/_dash-dependencies
wget -r http://127.0.0.1:8050/_dash-component-suites/dash/dcc/async-graph.js
wget -r http://127.0.0.1:8050/_dash-component-suites/dash/dcc/async-highlight.js
wget -r http://127.0.0.1:8050/_dash-component-suites/dash/dcc/async-markdown.js
wget -r http://127.0.0.1:8050/_dash-component-suites/dash/dcc/async-datepicker.js
wget -r http://127.0.0.1:8050/_dash-component-suites/dash/dash_table/async-table.js
wget -r http://127.0.0.1:8050/_dash-component-suites/dash/dash_table/async-highlight.js
wget -r http://127.0.0.1:8050/_dash-component-suites/plotly/package_data/plotly.min.js
mv 127.0.0.1:8050 pages_files
ls -a pages_files
ls -a pages_files/assets
find pages_files -exec sed -i.bak 's|_dash-component-suites|dash-actions-tutorial\\/_dash-component-suites|g' {} \;
find pages_files -exec sed -i.bak 's|_dash-layout|dash-actions-tutorial/_dash-layout.json|g' {} \;
find pages_files -exec sed -i.bak 's|_dash-dependencies|dash-actions-tutorial/_dash-dependencies.json|g' {} \;
find pages_files -exec sed -i.bak 's|_reload-hash|dash-actions-tutorial/_reload-hash|g' {} \;
find pages_files -exec sed -i.bak 's|_dash-update-component|dash-actions-tutorial/_dash-update-component|g' {} \;
find pages_files -exec sed -i.bak 's|assets|dash-actions-tutorial/assets|g' {} \;
mv pages_files/_dash-layout pages_files/_dash-layout.json
mv pages_files/_dash-dependencies pages_files/_dash-dependencies.json
mv assets/* pages_files/assets/
ps -C python -o pid= | xargs kill -9
clean_dirs:
ls
rm -rf 127.0.0.1:8050/
rm -rf pages_files/
rm -rf joblib
Let's quickly go over what the file does:
-
We run our app with
python3 app.py
and give it 30 seconds to fully load and generate all files, -
We need to extract all necessary files from our app to be able to run it on Github Pages. We can do this with
wget
command since Dash hosts our app onhttp://127.0.0.1:8050/
. -
We create a new folder named
pages_files
where we will store all necessary files to run the app. Now we just need to move all downloaded files topages_files
directory. -
(IMPORTANT!) We are going to host this app using GitHub Pages. If the repository name doesn’t match the author's GitHub username (as in this case, where dash-actions-tutorial ≠ dec0dedd), GitHub won’t shorten the URL, so the app will be hosted at 'https://dec0dedd.github.io/dash-actions-tutorial/'. This can lead to issues, as Dash might search for files in incorrect directories. For example, Dash could try to access _dash-component-suites/plotly/package_data/plotly.min.js, but this file won't exist at https://dec0dedd.github.io/dash-actions-tutorial/_dash-component-suites/plotly/package_data/plotly.min.js. Instead, we need Dash to look for the file under dash-actions-tutorial/_dash-component-suites/plotly/package_data/plotly.min.js, so it will search https://dec0dedd.github.io/dash-actions-tutorial/dash-actions-tutorial/_dash-component-suites/plotly/package_data/plotly.min.js and find it. To fix this, we’ll use the find and sed commands to update all file paths by replacing instances of _dash-component-suites with dash-actions-tutorial/_dash-component-suites, and do the same for _dash-layout, _dash-dependencies, _reload-hash, _dash-update-component, and assets directories.
-
Now we just need to move remaining (modified files) to
pages_files
folder to add them to the artifact we'll create later.
Create directories .github
and .github/workflows
. Create a file example-workflow.yml
in .github/workflows
with the following code:
name: Deploy app
run-name: Deploy HTML pages generated from Dash app
on: [push]
jobs:
run_app:
name: Run app
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@main
- name: Setup Pages
if: github.ref == 'refs/heads/main'
uses: actions/configure-pages@main
- name: Setup python
uses: actions/setup-python@main
with:
python-version: '3.12'
architecture: 'x64'
- name: Install project and dependencies
shell: bash
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
export
- name: Run Makefile files
run: |
make clean_dirs
make run_app
- name: Upload Artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@main
with:
path: "./pages_files"
deploy-pages:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
needs: run_app
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@main
Here is a quick description of what every part of the file does:
-
First we have to get access to repository code (to run the app). We can do this with checkout action.
-
Then we need to set up necessary tools with actions:
- Github Pages using configure-pages action,
- and Python using setup-python action,
-
Now we need to install all dependencies of our app.
-
Next we run Makefile commands (which will be described later) to generate all HTML/CSS/Js files required for the app to work.
-
We create and upload pages artifact with upload-pages-artifact action.
-
Using previously created artifact we upload all generated files to Github Pages with deploy-pages.
If you've followed the steps correctly, your Dash app should now be live at https://{username}.github.io/{repo-name}/. As proof that these instructions work, I've created a sample Dash app in this repository. You can view it here: https://dec0dedd.github.io/dash-actions-tutorial/. For more advanced projects hosted on GitHub Pages and more ideas for what you can do with Dash, check out my other project, Alcompare, where I compare and visualize different time series models using financial data. You can explore the hosted pages here.
If you have any questions feel free to email me or make an issue/pull request. Thanks for reading!