# Production and development enviroments

**URL:** <https://community.plotly.com/t/production-and-development-enviroments/21348>\
**Category:** Dash Python\
**Created:** [March 25, 2019, 5:45pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348 "2019-03-25T17:45:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mifabpre](https://avatars.discourse-cdn.com/v4/letter/m/6a8cbe/32.png) [@mifabpre](https://community.plotly.com/u/mifabpre)\
**Post date:** [March 25, 2019, 5:45pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/1 "2019-03-25T17:45:02Z")

</div>

Hi!  
I’m creating a dash that I need to run in 2 different computers. In one of them is working all fine, in the other computer I tried to copy everything to run it but a message pops up:

```
Serving Flask app "myDashApp" (lazy loading)
* Environment: production
 WARNING: Do not use the development server in a production environment.
 Use a production WSGI server instead.

```

I think I did exactly the same in both computers, but I don’t manage to run the code in the second computer at it does in the first. Do you have any idea of what I’m doing wrong?

Thank you!

---

<div class="post-metadata">

**Author:** ![Damian](https://avatars.discourse-cdn.com/v4/letter/d/34f0e0/32.png) [@Damian](https://community.plotly.com/u/Damian)\
**Post date:** [March 25, 2019, 5:58pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/2 "2019-03-25T17:58:09Z")

</div>

Any version of `app.run_server()` should produce this warning, Dash is using a library called [Flask](http://flask.pocoo.org/) and calling the `.run()` method on the Flask app which by default uses the [werkzeug development server](https://werkzeug.palletsprojects.com/en/0.15.x/serving/) which is similar to Python’s [`http.server`](https://docs.python.org/3/library/http.server.html). While the a great library for quickly running web-server in development it is not tested for security or performance.

So what do you use instead? Popular choices are [gunicorn](https://gunicorn.org/) and [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/).

I personally use gunicorn, so in my Dash `index.py` (which is the script that launches my Dash app, otherwise replace index with the name of your script) I have the following code:

```
if __name__ == ' __main__':
    # For Development only, otherwise use gunicorn or uwsgi to launch, e.g.
    # gunicorn -b 0.0.0.0:8050 index:app.server
    app.run_server(
        port=8050,
        host='0.0.0.0'
    )

```

And so I have gunicorn installed and when I want to launch via gunicorn I do the following:

```
gunicorn -b 0.0.0.0:8050 index:app.server

```

This, among other things, produces better performance.

Finally you may want to hook gunicorn/uWSGI to Apache, nginx, or IIS, these web servers lots of production stability options, directly serving and caching your resources, timeout options, and many other other things.

---

<div class="post-metadata">

**Author:** ![mifabpre](https://avatars.discourse-cdn.com/v4/letter/m/6a8cbe/32.png) [@mifabpre](https://community.plotly.com/u/mifabpre)\
**Post date:** [March 25, 2019, 7:04pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/3 "2019-03-25T19:04:12Z")

</div>

Hi Damian, thank you for the answer! I’m trying to do it, but I seem to have a problem with gunicorn. It warns me that he cannot import the module fcntl. I saw that might be related because I’m trying to run it on windows. I also tried with waitress but it’s still not working:

`waitress-serve dash_alphav6:app`

---

<div class="post-metadata">

**Author:** ![Damian](https://avatars.discourse-cdn.com/v4/letter/d/34f0e0/32.png) [@Damian](https://community.plotly.com/u/Damian)\
**Post date:** [March 25, 2019, 8:15pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/4 "2019-03-25T20:15:43Z")

</div>

> [@mifabpre](#):
>
> waitress-serve dash\_alphav6:app

I’ve never used `waitress-serve` but assuming `dash_alphav6` is your python file (i.e. `dash_alphav6.py`) and `app` is your `dash.Dash()` then you will probably need to use the command:

```
waitress-serve dash_alphav6:app.server

```

As `app.server` is the underlying Flask server these frameworks usually need.

---

<div class="post-metadata">

**Author:** ![mifabpre](https://avatars.discourse-cdn.com/v4/letter/m/6a8cbe/32.png) [@mifabpre](https://community.plotly.com/u/mifabpre)\
**Post date:** [March 25, 2019, 10:53pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/5 "2019-03-25T22:53:08Z")

</div>

It’s working! thank you soooo much!

---

<div class="post-metadata">

**Author:** ![UdayGuntupalli](https://avatars.discourse-cdn.com/v4/letter/u/a9adbd/32.png) [@UdayGuntupalli](https://community.plotly.com/u/UdayGuntupalli)\
**Post date:** [May 4, 2019, 12:20am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/6 "2019-05-04T00:20:49Z")

</div>

@Damian,  
I am new to Python and just installed Dash and plotly. I took the simplest app example from the user documentation and tried to run it in Spyder. Initially I was getting the same error/warning to not use Debug mode. I then installed gunicorn after I looked at this post. However, I am unable to follow where exactly the gunicorn call goes. Any help/guidance is greatly appreciated.

```
import dash
import dash_core_components as dcc
import dash_html_components as html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash( __name__ , external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(children='''
        Dash: A web application framework for Python.
    '''),

    dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
            ],
            'layout': {
                'title': 'Dash Data Visualization'
            }
        }
    )
])

if __name__ == ' __main__':
# app.run_server(debug=True)
    app.run_server(port=8050,host='0.0.0.0')
# gunicorn -b 0.0.0.0:8050 index:app.server

```

This results in the following:

> - Serving Flask app “ **main** ” (lazy loading)
> - Environment: production  
> WARNING: Do not use the development server in a production environment.  
> Use a production WSGI server instead.
> - Debug mode: off
> - Running on [http://0.0.0.0:8050/](http://0.0.0.0:8050/) (Press CTRL+C to quit)

---

<div class="post-metadata">

**Author:** ![nedned](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/nedned/32/8795_2.png) [@nedned](https://community.plotly.com/u/nedned)\
**Post date:** [May 4, 2019, 11:47am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/7 "2019-05-04T11:47:55Z")

</div>

If you’re not actually trying to deploy an app into production, then it’ll be easier to avoid gunicorn. Instead of running in Spyder, try running on the command line. ie:

```
$ python your_app.py
```

---

<div class="post-metadata">

**Author:** ![UdayGuntupalli](https://avatars.discourse-cdn.com/v4/letter/u/a9adbd/32.png) [@UdayGuntupalli](https://community.plotly.com/u/UdayGuntupalli)\
**Post date:** [May 4, 2019, 4:46pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/8 "2019-05-04T16:46:13Z")

</div>

@nedned,  
Thank you for your response. I tried to run the app in my Anaconda Prompt using the following command

> > python app.py

> [@nedned](#):
>
> If you’re not actually trying to deploy an app into production, then it’ll be easier to avoid gunicorn. Instead of running in Spyder, try running on the command line. ie:
> 
> ```
> $ python your_app.py
> 
> ```

[quote=“nedned, post:7, topic:21348, full:true”]  
If you’re not actually trying to deploy an app into production, then it’ll be easier to avoid gunicorn. Instead of running in Spyder, try running on the command line. ie:

```
$ python your_app.py

```

![5-4-2019%209-43-50%20AM](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/5/5d6812ff5b5fcc536dedc1fdaeb6f30807190f21.jpeg)

It does not really yield anything in my browser, so I am not sure what to expect.

---

<div class="post-metadata">

**Author:** ![nedned](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/nedned/32/8795_2.png) [@nedned](https://community.plotly.com/u/nedned)\
**Post date:** [May 5, 2019, 2:36am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/9 "2019-05-05T02:36:23Z")

</div>

Maybe turn debug mode back on to start with. Can you be more specific about what you’re seeing in the browser when you load [http://localhost:8050](http://localhost:8050)? Is anything displayed at all?

---

<div class="post-metadata">

**Author:** ![UdayGuntupalli](https://avatars.discourse-cdn.com/v4/letter/u/a9adbd/32.png) [@UdayGuntupalli](https://community.plotly.com/u/UdayGuntupalli)\
**Post date:** [May 5, 2019, 3:56am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/10 "2019-05-05T03:56:40Z")

</div>

@nedned,  
Nothing is displayed at all, it does not open a new browser window even

---

<div class="post-metadata">

**Author:** ![nedned](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/nedned/32/8795_2.png) [@nedned](https://community.plotly.com/u/nedned)\
**Post date:** [May 5, 2019, 6:54am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/11 "2019-05-05T06:54:17Z")

</div>

You need to open a browser yourself and load the URL: [http://localhost:8050/](http://localhost:8050/)

---

<div class="post-metadata">

**Author:** ![mifabpre](https://avatars.discourse-cdn.com/v4/letter/m/6a8cbe/32.png) [@mifabpre](https://community.plotly.com/u/mifabpre)\
**Post date:** [May 7, 2019, 12:21pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/12 "2019-05-07T12:21:47Z")

</div>

Hi guys! What @nedned is saying is true, you need to open [http://0.0.0.0:8050/](http://0.0.0.0:8050/) in the web browser. @UdayGuntupalli but instead of running in the CMD:`python main.py` I recommend you to install waitress and run `waitress-serve main:app.server`

---

<div class="post-metadata">

**Author:** ![nedned](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/nedned/32/8795_2.png) [@nedned](https://community.plotly.com/u/nedned)\
**Post date:** [May 7, 2019, 12:34pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/13 "2019-05-07T12:34:04Z")

</div>

But note that running with waitress (ie as a WSGI app) will turn result in debug mode being turned off (unless you set the relevant environment variable to turn it on) so you may want to do that in production, while sticking to the dev server approach when developing.

---

<div class="post-metadata">

**Author:** ![dayxx369](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@dayxx369](https://community.plotly.com/u/dayxx369)\
**Post date:** [June 10, 2019, 9:36pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/14 "2019-06-10T21:36:43Z")

</div>

@mifabpre @nedned

Hello,

I am trying to deploy my program in production mode with waitress, but I am getting an issue of not being able to load again. Basically, when I run it one, it works, then when I try to run it again, it doesn’t.

I think it’s because I am using waitress wrong in my python program. I basically import waitress and use serve(app). Is this wrong? How should I be using waitress? Any sample code would be greatly appreciated as well!

---

<div class="post-metadata">

**Author:** ![mifabpre](https://avatars.discourse-cdn.com/v4/letter/m/6a8cbe/32.png) [@mifabpre](https://community.plotly.com/u/mifabpre)\
**Post date:** [June 11, 2019, 5:31am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/15 "2019-06-11T05:31:55Z")

</div>

Hi!  
I don’t know how are you doing it. I guess that you are not clossing waitress once you launch it for the first time. In my case I’ve build a \*.bat file and I’m running the following code:

> ```
> start chrome http://localhost:8050
> waitress-serve --listen=*:8050 mydashapp:app.server
> 
> ```

And then it closes when you close the cmd window.

What I didn’t manage yet is to continue the development in other computer running the debug mode. As @nedned says, the it turns off. So waitress is just working to run your dash propperly, but I don’t think it’s good enough to do development.

---

<div class="post-metadata">

**Author:** ![dayxx369](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@dayxx369](https://community.plotly.com/u/dayxx369)\
**Post date:** [June 11, 2019, 10:57am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/16 "2019-06-11T10:57:24Z")

</div>

Thanks. So where do I type this in my python code?

```auto
start chrome http://localhost:8050
waitress-serve --listen=*:8050 mydashapp:app.server

```

Is waitress used wtihin the python code typically as a package? There’s little documentation explaining what waitress is and how to use it in python. Thanks

---

<div class="post-metadata">

**Author:** ![mifabpre](https://avatars.discourse-cdn.com/v4/letter/m/6a8cbe/32.png) [@mifabpre](https://community.plotly.com/u/mifabpre)\
**Post date:** [June 11, 2019, 11:47am UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/17 "2019-06-11T11:47:40Z")

</div>

That code must be in a \*.bat file. Or run it straight in the CMD of windows.

GIYF! [https://docs.pylonsproject.org/projects/waitress/en/stable/](https://docs.pylonsproject.org/projects/waitress/en/stable/)

---

<div class="post-metadata">

**Author:** ![dayxx369](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@dayxx369](https://community.plotly.com/u/dayxx369)\
**Post date:** [June 11, 2019, 3:38pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/18 "2019-06-11T15:38:22Z")

</div>

Thanks. Just to make sure that I’m clear, I run the program, first, then run this in the command lines?

---

<div class="post-metadata">

**Author:** ![dayxx369](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@dayxx369](https://community.plotly.com/u/dayxx369)\
**Post date:** [June 13, 2019, 12:37pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/19 "2019-06-13T12:37:19Z")

</div>

Also, when I use waitress.serve in the python program, it doesn’t automatically kill the connection when I stop running the program. To kill the connection, I manually go to the CMD and kill the connection. This is not a thing with Flask because Ctrl + C kills the connection. Do you know how I can go about this?

```auto
from waitress import serve
#program for python

serve(app.server,host=host,port=1001) #this connects with the server

```

I have also tried:

```auto
server = create_server(app)
server.run()

```

But this doesn’t work as well. Any help will be appreciated!

---

<div class="post-metadata">

**Author:** ![kkkarthik](https://avatars.discourse-cdn.com/v4/letter/k/b2d939/32.png) [@kkkarthik](https://community.plotly.com/u/kkkarthik)\
**Post date:** [April 16, 2021, 5:23pm UTC](https://community.plotly.com/t/production-and-development-enviroments/21348/20 "2021-04-16T17:23:18Z")

</div>

Hello Damian,

Could you please illustrate what should be our imports in the `index.py`.  
Should we be importing the “app” in the `app = dash.Dash(server=server)` or should we be importing “server” in the `server = flask.Flask( __name__ )`

I have done the below:

I am developing an application using dash and want to host it using Gunicorn on linux platform (RHEL).  
The following is how I have deployed it.

my dash application :

```auto
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import flask

<data_frame definitions>

server = flask.Flask( __name__ )
app = dash.Dash(server=server)

<app.layout>

<Call backs>

## at the end

if __name__ == ' __main__':
    app.run_server()

```

Created an index.py for Gunicorn

```auto
from MyPoC.Package import server as application

application

```

When I use the below command, I see no errors on the screen, but yet I can’t reach the application from the browser.

`[user1@myHost]$ gunicorn index:application -b:8000`

```auto
[2021-04-16 16:57:58 +0200] [8334] [INFO] Starting gunicorn 20.0.4
[2021-04-16 16:57:58 +0200] [8334] [INFO] Listening at: http://0.0.0.0:8000 (8334)
[2021-04-16 16:57:58 +0200] [8334] [INFO] Using worker: sync
[2021-04-16 16:57:58 +0200] [8345] [INFO] Booting worker with pid: 8345

```

I see that the port is listening, however, I am not able to open my dashboard on the server’s `public IP` and `0.0.0.0`  
The port 8000 is in listen mode

```auto
sudo lsof -i -P -n | grep LISTEN

gunicorn 13003 user1 5u IPv4 49878669 0t0 TCP *:8000 (LISTEN)
gunicorn 13015 user1 5u IPv4 49878669 0t0 TCP *:8000 (LISTEN)

```

I would really appreciate if you could kindly take out few minutes of your time and guide me on a path to a resolution.

Please forgive me if I am making a very basic mistake. I am new to the world of webservers and all.

Your help will go a long way to help my understanding get better. Thanks.

[Next page](https://community.plotly.com/t/production-and-development-enviroments/21348.md?page=2)
