Search code examples
pythonherokugunicornkedro

using gunicorn for nested folders


I'm new to gunicorn and heroku so I would appreciate any help. I want to deploy my python Dash app on to heroku and I know I need a Procfile. The thing is that my project structure uses the Kedro structure and my structure looks like this:

myproject
    .... # Kedro-generated files
    src/
        package1/
            package2/
                __init__.py
                index.py
    Procfile

index.py is a Dash application like so

#imports up here

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

.......  # main code chunk

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

Currently, my Procfile looks like this:

web: gunicorn src frontend.index:app

My project uploads to heroku just fine but I'm getting this error in my log:

2020-08-21T06:46:46.433935+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 941, in _find_and_load_unlocked
2020-08-21T06:46:46.433935+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
2020-08-21T06:46:46.433936+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 994, in _gcd_import
2020-08-21T06:46:46.433936+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 971, in _find_and_load
2020-08-21T06:46:46.433936+00:00 app[web.1]: File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
2020-08-21T06:46:46.433962+00:00 app[web.1]: ModuleNotFoundError: No module named 'frontend'
2020-08-21T06:46:46.434082+00:00 app[web.1]: [2020-08-21 06:46:46 +0000] [11] [INFO] Worker exiting (pid: 11)
2020-08-21T06:46:46.464346+00:00 app[web.1]: Traceback (most recent call last):
2020-08-21T06:46:46.464367+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 202, in run
2020-08-21T06:46:46.464715+00:00 app[web.1]: self.manage_workers()
2020-08-21T06:46:46.464732+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 545, in manage_workers
2020-08-21T06:46:46.465049+00:00 app[web.1]: self.spawn_workers()
2020-08-21T06:46:46.465054+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 617, in spawn_workers
2020-08-21T06:46:46.465412+00:00 app[web.1]: time.sleep(0.1 * random.random())
2020-08-21T06:46:46.465417+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
2020-08-21T06:46:46.465617+00:00 app[web.1]: self.reap_workers()
2020-08-21T06:46:46.465622+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 525, in reap_workers
2020-08-21T06:46:46.465905+00:00 app[web.1]: raise HaltServer(reason, self.WORKER_BOOT_ERROR)
2020-08-21T06:46:46.465950+00:00 app[web.1]: gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
2020-08-21T06:46:46.465964+00:00 app[web.1]: 
2020-08-21T06:46:46.465965+00:00 app[web.1]: During handling of the above exception, another exception occurred:
2020-08-21T06:46:46.465965+00:00 app[web.1]: 
2020-08-21T06:46:46.465969+00:00 app[web.1]: Traceback (most recent call last):
2020-08-21T06:46:46.465969+00:00 app[web.1]: File "/app/.heroku/python/bin/gunicorn", line 8, in <module>
2020-08-21T06:46:46.466103+00:00 app[web.1]: sys.exit(run())
2020-08-21T06:46:46.466107+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 58, in run
2020-08-21T06:46:46.466254+00:00 app[web.1]: WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
2020-08-21T06:46:46.466258+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/base.py", line 228, in run
2020-08-21T06:46:46.466464+00:00 app[web.1]: super().run()
2020-08-21T06:46:46.466470+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/app/base.py", line 72, in run
2020-08-21T06:46:46.466601+00:00 app[web.1]: Arbiter(self).run()
2020-08-21T06:46:46.466606+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 229, in run
2020-08-21T06:46:46.466790+00:00 app[web.1]: self.halt(reason=inst.reason, exit_status=inst.exit_status)
2020-08-21T06:46:46.466794+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 342, in halt
2020-08-21T06:46:46.467031+00:00 app[web.1]: self.stop()
2020-08-21T06:46:46.467032+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 393, in stop
2020-08-21T06:46:46.467262+00:00 app[web.1]: time.sleep(0.1)
2020-08-21T06:46:46.467267+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
2020-08-21T06:46:46.467468+00:00 app[web.1]: self.reap_workers()
2020-08-21T06:46:46.467469+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/gunicorn/arbiter.py", line 525, in reap_workers
2020-08-21T06:46:46.467750+00:00 app[web.1]: raise HaltServer(reason, self.WORKER_BOOT_ERROR)
2020-08-21T06:46:46.467754+00:00 app[web.1]: gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
2020-08-21T06:46:46.559947+00:00 heroku[web.1]: Process exited with status 1
2020-08-21T06:46:46.610907+00:00 heroku[web.1]: State changed from starting to crashed
2020-08-21T06:47:03.000000+00:00 app[api]: Build succeeded
2020-08-21T06:49:12.915422+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=protected-coast-07061.herokuapp.com request_id=781ff03f-db0d-40ad-996f-1d25ff3fd026 fwd="115.66.91.134" dyno= connect= service= status=503 bytes= protocol=https
2020-08-21T06:49:13.357185+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=protected-coast-07061.herokuapp.com request_id=51bff951-d0fa-4e01-ba38-60f44cbe373b fwd="18.217.223.118" dyno= connect= service= status=503 bytes= protocol=http
2020-08-21T06:49:13.955353+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=protected-coast-07061.herokuapp.com request_id=632cc0a9-e052-43c9-a90c-62f99dfbba5c fwd="115.66.91.134" dyno= connect= service= status=503 bytes= protocol=https
2020-08-21T06:52:18.372623+00:00 heroku[web.1]: State changed from crashed to starting
2020-08-21T06:52:32.487313+00:00 heroku[web.1]: Starting process with command `gunicorn src frontend.index`
2020-08-21T06:52:34.595212+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-08-21T06:52:34.595933+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [4] [INFO] Listening at: http://0.0.0.0:17241 (4)
2020-08-21T06:52:34.596051+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [4] [INFO] Using worker: sync
2020-08-21T06:52:34.600183+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [10] [INFO] Booting worker with pid: 10
2020-08-21T06:52:34.603725+00:00 app[web.1]: Failed to find attribute 'application' in 'src'.
2020-08-21T06:52:34.603887+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-08-21T06:52:34.626625+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [11] [INFO] Booting worker with pid: 11
2020-08-21T06:52:34.629877+00:00 app[web.1]: Failed to find attribute 'application' in 'src'.
2020-08-21T06:52:34.629978+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [11] [INFO] Worker exiting (pid: 11)
2020-08-21T06:52:34.733270+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [4] [INFO] Shutting down: Master
2020-08-21T06:52:34.733356+00:00 app[web.1]: [2020-08-21 06:52:34 +0000] [4] [INFO] Reason: App failed to load.
2020-08-21T06:52:34.800675+00:00 heroku[web.1]: Process exited with status 4
2020-08-21T06:52:34.837697+00:00 heroku[web.1]: State changed from starting to crashed
2020-08-21T06:52:34.839731+00:00 heroku[web.1]: State changed from crashed to starting
2020-08-21T06:52:49.188229+00:00 heroku[web.1]: Starting process with command `gunicorn src frontend.index`
2020-08-21T06:52:50.000000+00:00 app[api]: Build succeeded
2020-08-21T06:52:51.154243+00:00 app[web.1]: [2020-08-21 06:52:51 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-08-21T06:52:51.154956+00:00 app[web.1]: [2020-08-21 06:52:51 +0000] [4] [INFO] Listening at: http://0.0.0.0:46031 (4)
2020-08-21T06:52:51.155075+00:00 app[web.1]: [2020-08-21 06:52:51 +0000] [4] [INFO] Using worker: sync
2020-08-21T06:52:51.158999+00:00 app[web.1]: [2020-08-21 06:52:51 +0000] [10] [INFO] Booting worker with pid: 10
2020-08-21T06:52:51.162147+00:00 app[web.1]: Failed to find attribute 'application' in 'src'.
2020-08-21T06:52:51.162261+00:00 app[web.1]: [2020-08-21 06:52:51 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-08-21T06:52:51.189291+00:00 app[web.1]: [2020-08-21 06:52:51 +0000] [4] [INFO] Shutting down: Master
2020-08-21T06:52:51.189375+00:00 app[web.1]: [2020-08-21 06:52:51 +0000] [4] [INFO] Reason: App failed to load.
2020-08-21T06:52:51.249579+00:00 heroku[web.1]: Process exited with status 4
2020-08-21T06:52:51.281288+00:00 heroku[web.1]: State changed from starting to crashed
2020-08-21T06:53:27.313026+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=protected-coast-07061.herokuapp.com request_id=67b1f83d-37a8-4ad1-b522-2e7cc0bd7b7d fwd="115.66.91.134" dyno= connect= service= status=503 bytes= protocol=https
2020-08-21T06:53:28.196639+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=protected-coast-07061.herokuapp.com request_id=0d13d80e-ca9b-4857-970e-47cfcf602017 fwd="115.66.91.134" dyno= connect= service= status=503 bytes= protocol=https
2020-08-21T06:57:12.000000+00:00 app[api]: Build started by user 
2020-08-21T06:58:51.667324+00:00 app[api]: Deploy 1f77e9e8 by user 
2020-08-21T06:58:51.667324+00:00 app[api]: Release v12 created by user 
2020-08-21T06:58:51.832220+00:00 heroku[web.1]: State changed from crashed to starting
2020-08-21T06:59:07.062252+00:00 heroku[web.1]: Starting process with command `gunicorn src frontend.index:app`
2020-08-21T06:59:10.383357+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-08-21T06:59:10.384213+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [4] [INFO] Listening at: http://0.0.0.0:54641 (4)
2020-08-21T06:59:10.384357+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [4] [INFO] Using worker: sync
2020-08-21T06:59:10.388913+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [10] [INFO] Booting worker with pid: 10
2020-08-21T06:59:10.392276+00:00 app[web.1]: Failed to find attribute 'application' in 'src'.
2020-08-21T06:59:10.392426+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-08-21T06:59:10.403239+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [11] [INFO] Booting worker with pid: 11
2020-08-21T06:59:10.407880+00:00 app[web.1]: Failed to find attribute 'application' in 'src'.
2020-08-21T06:59:10.408006+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [11] [INFO] Worker exiting (pid: 11)
2020-08-21T06:59:10.525402+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [4] [INFO] Shutting down: Master
2020-08-21T06:59:10.525558+00:00 app[web.1]: [2020-08-21 06:59:10 +0000] [4] [INFO] Reason: App failed to load.
2020-08-21T06:59:10.607473+00:00 heroku[web.1]: Process exited with status 4
2020-08-21T06:59:11.643239+00:00 heroku[web.1]: State changed from starting to crashed
2020-08-21T06:59:54.000000+00:00 app[api]: Build succeeded
2020-08-21T07:08:53.300472+00:00 heroku[web.1]: State changed from crashed to starting
2020-08-21T07:09:16.319403+00:00 heroku[web.1]: Starting process with command `gunicorn src frontend.index:app`
2020-08-21T07:09:19.182910+00:00 heroku[web.1]: Process exited with status 4
2020-08-21T07:09:19.228761+00:00 heroku[web.1]: State changed from starting to crashed
2020-08-21T07:09:19.057971+00:00 app[web.1]: [2020-08-21 07:09:19 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-08-21T07:09:19.058760+00:00 app[web.1]: [2020-08-21 07:09:19 +0000] [4] [INFO] Listening at: http://0.0.0.0:25408 (4)
2020-08-21T07:09:19.058888+00:00 app[web.1]: [2020-08-21 07:09:19 +0000] [4] [INFO] Using worker: sync
2020-08-21T07:09:19.063236+00:00 app[web.1]: [2020-08-21 07:09:19 +0000] [10] [INFO] Booting worker with pid: 10
2020-08-21T07:09:19.066629+00:00 app[web.1]: Failed to find attribute 'application' in 'src'.
2020-08-21T07:09:19.066758+00:00 app[web.1]: [2020-08-21 07:09:19 +0000] [10] [INFO] Worker exiting (pid: 10)
2020-08-21T07:09:19.102247+00:00 app[web.1]: [2020-08-21 07:09:19 +0000] [4] [INFO] Shutting down: Master
2020-08-21T07:09:19.102349+00:00 app[web.1]: [2020-08-21 07:09:19 +0000] [4] [INFO] Reason: App failed to load.

Apologies, I am new to this so I am not sure where to even start with the debugging as well. To summarise: I think my gunicorn is not firing as my line may be wrong; and I am not sure what is causing my app to not launch. How do I solve this issue?


Solution

  • The logic of gunicorn is the following: . (dot) for directories, : (column) for objects defined inside a file.

    Assuming the given structure, you should have something like this:

    $ cat Procfile
    web: gunicorn src.package1.package2.index:app
    

    [EDIT] If you get an error, you should consider using server instead of app. As an example, these files are from one of my old projects (also a Dash app):

    # app.py
    
    import flask
    from src import dashboard
    
    server = flask.Flask(__name__)
    server.secret_key = os.environ.get('secret_key', str(randint(0, 1000000)))
    app = dashboard.main(server)
    
    if __name__ == '__main__':
        app.server.run(debug=True, threaded=True)
    
    # Procfile
    web: gunicorn app:server --timeout 300
    
    $ ls *
    Procfile app.py
    
    src:
    config.py  dashboard.py ...