This is the first deployment chapter of the Dash Enterprise Documentation.
The next chapter covers initializing a Dash App on Dash Enterprise.
This page applies to Dash Enterprise 5. If your organization uses Dash Enterprise 4, view information about preparing your app for Dash Enterprise at
https://<your-dash-enterprise-server>/Docs/dash-enterprise/preparing
.
The first step in deploying your Dash app to Dash Enterprise is to prepare your app’s code with the necessary files required to deploy your Dash app.
This guide is aimed at users who already have Dash apps running locally. If you haven’t already created a Dash app yet, we recommend choosing an app from the App Catalog. All apps in the App Catalog are deploy-ready and are a great starting point for your first Dash app.
Consider the following items to ensure that your app will be successfully deployed on Dash Enterprise:
Procfile
- Ensure that your project folder has a Procfile
. See Application Structure for details. This is often:web: gunicorn app:server --workers 2
requirements.txt
- Ensure that your project folder has a requirements.txt
file with the Python dependencies and versions. Don’t forget gunicorn
! See Application Structure Documentation for details.server = app.server
- Declare the underlying server
variable to be referenced by the web
command in your Procfile
. See Application Structure Documentation for details.predeploy
script and an Aptfile
file. See Application Structure Documentation.git
instructions generated by the App Manager. See Part 3. Deploy Dash Apps on Dash Enterprise.There are often differences between your local environment and
the containerized environment Dash Enterprise runs your app in.
These differences may include:
Workspaces run on the Dash Enterprise server with a build system that is nearly identical to
how Dash apps are built and deployed. This means that the differences listed above do not
apply between Workspaces and deployed apps.
The easiest way to troubleshoot your app is to run it within a Dash Enterprise Workspace.
This can be done in two ways:
After deploying your app to Dash Enterprise, you may notice your app feels slower than when running it locally.
Dash apps deployed on Dash Enterprise are on a different network than Dash apps running locally.
This can affect the performance of callbacks and the performance of any data fetching being done within your callback.
Callback Performance
The input, output, and state of a callback are transferred over the network.
When working locally, this data transfer is very fast.
When the app is deployed on a server, it takes longer to
transfer the data from the user’s browser to your callback and from your
callback to the user’s browser.
This is usually not noticeable unless your callbacks have large data structures as inputs (e.g. a dataframe stored in dcc.Store
or the contents of a dcc.Upload
component) or as outputs (e.g. large figure
properties of dcc.Graph
or large data
properties of DataTable
).
Diagnosing Callback Network Performance Issues
To investigate whether the performance issues are related to the network, we recommend:
- Viewing the data transfer (avg bytes)
and time - network
of callbacks via the Dash Dev Tools Callback Graph. You can turn this on for your deployed app with:
python
app.enable_dev_tools(
dev_tools_ui=True,
dev_tools_serve_dev_bundles=True,
)
- Using the Network Panel of your browser’s Development Tools to view the network transfer speed of the requests. Each callback will correspond to a POST /_dash-update-component
. The contents of the request will indicate the inputs and, therefore which callback the request is associated with.
Improving Callback Network Transfer Performance
There are two ways to improve callback network transfer performance:
Reduce the size of the inputs, outputs and state of a callback. This can be done with strategies like:
dcc.Graph
or dash_table.DataTable
.Replacing dcc.Store
or hidden divs with a server-side cache via the “Caching and Signaling” method.
2. Reduce the number of times a callback is fired. This can be done with strategies like:
dcc.Input
, update the UI when the user clicks a button and pass the value of the dcc.Input
via State
.dcc.Store
or hidden divs with a server-side cache via the “Caching and Signaling” method.Data Fetching to External Datastores
Data from an external datastore like a database or object store like S3 is transferred over the network.
Unless you are using Dash Enterprise Workspaces, the network path from your workstation’s
environment to your datastore is different than the network path from Dash Enterprise to the datastore.
This has a few implications:
If your app can read directly from data files (rather than a database or an API), then you have three options for reading these files in a deployed app:
postdeploy
command, or in a background schedule with Celery
while mapping the directories between containers (see “Ephemeral File Systems” below).Dash Enterprise enables you to create and link Redis and Postgres databases to your app.
via the App Manager user interface.
Once linked, these databases are accessible within your code via:
REDIS_URL
environment variable for the Redis databaseDATABASE_URL
environment variable for the Postgres databaseIf your app depends on private dependencies, see our
Private Packages Doc
for details.
Each command listed in your Procfile is executed in a separate Docker
container and Docker containers have isolated file systems.
When you deploy a Dash app, it is run in a set of new containers.
So, data that is written to the file system won’t necessarily be available
during the next deployment, nor will it be available between processes (like between the web
process and the worker
process).
To work around this limitation, you have three options:
Apps deployed on Dash Enterprise can access the username of the currently logged-in visitor of the Dash app
via the dash-enterprise-auth
package:
```python
import dash_enterprise_auth
@app.callback(…)
def update(…):
username = dash_enterprise_auth.get_username() # only available within callbacks
user_data = dash_enterprise_auth.get_user_data() # only available within callbacks
```
This data can be used to create row-level-security logic where the username is used within the Python logic
or the database query to display data associated with that particular user.
Apps deployed to Dash Enterprise have a 30-second request timeout by default.
This is to prevent long-running or stuck requests from preventing further requests.
If you have callbacks that take longer than 30 seconds to complete, your app users will encounter request timeouts.
To avoid this, you have a few options:
dcc.Store
orgunicorn app:server --timeout 120
.Be aware of this method’s performance limitations: more CPU processes and workers will be utilized while
handling long-running requests, and it will be more likely that your app will “run out” of the
available CPU processes and workers while multiple users interact with your app. You will likely need to increase
the number of workers with gunicorn’s --workers
argument.
gunicorn
is used to run your app on deployments. gunicorn
has a default worker startup timeout of 30 seconds.
If your app takes longer than 30 seconds to boot-up (that is, to be ready to handle new requests), then the workers will timeout and restart.
To get around this, increase the boot-up timeout with the --timeout
argument in your Procfile
:
web: gunicorn app:server --timeout 60
Dash Enterprise apps are accessible under a separate URL path.
That is, instead of accessing the app at, e.g. http://localhost:8050
, you access the app at https://<your-dash-enterprise>.com/<your-dash-app-name>
.
The /<your-dash-app-name>
is the path that we are referring to.
When dealing with anything to do with URL paths, we recommend using built-in functions instead of constructing these URLs manually.
These functions account for the differences between path-less URLs in local environments vs path-aware URLs in deployed environments.
These functions include:
- app.get_relative_path('/page-two')
for creating URL paths used in links (dcc.Link('Home', href=app.get_relative_path('/')
or html.A('Home', href=app.get_relative_path('/')
) or image or video assets (html.Img(src=app.get_relative_path('/assets/logo.png')
)
- app.strip_relative_path(pathname)
for stripping the relative path out of the pathname. Used multi-page app callbacks that respond to dcc.Location
The Python version that you use locally may be different from the Python version used by Dash Enterprise.
See the default Python version in your version of Dash Enterprise
and how to customize this with project.toml
in the App Structure documentation.
Ensure that your local environment is using the same Python package versions as the deployed app by
providing version numbers in your requirements.txt
file. See App Structure
for details.
Dash Enterprise includes access to several commercial packages that you can use in your Dash app.
For example:
dash-design-kit
for theming and building the layout of your Dash app.dash-snapshots
for saving point-in-time views of your app’s state and generating structured reports.dash-embedded
for embedding Dash apps in 3rd party websites without Iframes.dash-notes
for allowing end-users to add annotations and comments to your app.In some cases, Dash Enterprise is configured by administrators with unsupported, untested, or misconfigured proxy servers.
Sometimes these servers can cause issues forwarding requests to Dash Enterprise.
This can cause issues when installing packages over the network during deployment or while transferring callback data.