Part 1. Preparing Your App for Dash Enterprise

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.

Migrating from Local Development to Dash Enterprise

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.

Quickstart Checklist

Consider the following items to ensure that your app will be successfully deployed on Dash Enterprise:

  1. Procfile - Ensure that your project folder has a Procfile. See Application Structure for details. This is often:
    web: gunicorn app:server --workers 2
  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.
  3. server = app.server - Declare the underlying server variable to be referenced by the web command in your Procfile. See Application Structure Documentation for details.
  4. Remove secrets & passwords - Remove sensitive passwords and API keys from your code and replace them with Environment Variables.
  5. System-Level dependencies - If your project requires system level dependencies like database drivers, then install those dependencies with a predeploy script and an Aptfile file. See Application Structure Documentation.
  6. Self-contained - Ensure that all files and datasets that the app code references or saves are within the same project folder.
  7. Initialize your app in the Dash Enterprise App Manager UI. See Part 2. Initialize Dash Apps on Dash Enterprise.
  8. Deploy your app by running the git instructions generated by the App Manager. See Part 3. Deploy Dash Apps on Dash Enterprise.

Additional Considerations

Dash Enterprise Workspaces

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:

  1. Deploying the app and creating a Workspace from that deployed app.
    This can only be done if the deployment succeeds.
  2. Copying or uploading the files from your local environment to a new Dash Enterprise Workspace.

Networking Differences: Local vs Deployed

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:

  1. Reduce the size of the inputs, outputs and state of a callback. This can be done with strategies like:

    • Aggregating or binning your data in Python before displaying it a dcc.Graph or dash_table.DataTable.
    • Using an alternative visualization routine that displays an aggregate or summary of data instead of every individual data point.
    • Visualizing aggregated data via Dash with Datashader.
    • 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:

    • Clientside callbacks

    • Changing the UI to update less frequently from user interaction. For example, instead of updating on every keypress of a dcc.Input, update the UI when the user clicks a button and pass the value of the dcc.Input via State.
    • Replacing dcc.Store or hidden divs with a server-side cache via the “Caching and Signaling” method.
    • Combining multiple callbacks into a single callback with multiple outputs.

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:

  1. The VMs that are running Dash Enterprise apps need to have network access to your data store. You can verify this by using a Dash Enterprise Workspace.
  2. The network speed may be different when deploying your app. Usually, the network transfer speed is faster as the Dash Enterprise VMs are frequently “closer” to the underlying datastore in your organization’s VPC.

Working with Large Data Files

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:

Working with Redis or Postgres

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:

Private Packages

If your app depends on private dependencies, see our
Private Packages Doc
for details.

Ephemeral File Systems

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:

  1. Save the data to an external data store.
  2. Save the data to a Redis or Postgres database in Dash Enterprise.
  3. Use Dash Enterprise’s persistent filesystem.

Authentication and Authorization

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:

import dash_enterprise_auth

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.

Request Timeouts

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:

  1. Speed up your app code so that callbacks take less than 30 seconds to run.
  2. Split up long-running callbacks into multiple chained callbacks, storing intermediate data in a dcc.Store or
    in a server-side cache (see “Caching and Signaling”)
  3. Use background callbacks to run callbacks in a job queue.
  4. Increase two timeouts:
    a. The built-in proxy timeout in the Dash Enterprise Server Manager. Your admin will need to adjust this setting.
    b. The default gunicorn timeout with, e.g. gunicorn 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.

Startup Timeouts

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

URL Routing

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

Python Version

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.

Package Versions

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 Application Capabilities

Dash Enterprise includes access to several commercial packages that you can use in your Dash app.
For example:

3rd Party Proxy Servers

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.