Reputation: 143
I've written a Flask app that's being served with Gunicorn and running on Raspberry Pi OS (Buster). The app is supposed to run automatically as a service on system boot. The issue is, the app fails when run as a service... but only when run as a service...
It used to work until I introduced server hooks into my Gunicorn configuration file. There's a few of them, but the first to be called, and thus fail is:
gunicorn.conf.py:
def on_starting(server):
import wsgi
wsgi.on_starting(server)
wsgi.py:
def on_starting(server):
api_instance = server.app.wsgi()
shared_memory_manager = Manager()
api_instance.requestless_variables = shared_memory_manager.dict()
api_instance.log = server.log
server.log.info("Loading API...")
With the following traceback:
Traceback (most recent call last):
File "/home/pi/.local/bin/gunicorn", line 8, in <module>
sys.exit(run())
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 67, in run
WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/app/base.py", line 231, in run
super().run()
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/app/base.py", line 72, in run
Arbiter(self).run()
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 198, in run
self.start()
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 138, in start
self.cfg.on_starting(self)
File "/home/pi/nano/manager/src/api/gunicorn.conf.py", line 56, in on_starting
api_instance = server.app.wsgi()
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
self.callable = self.load()
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
return self.load_wsgiapp()
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
return util.import_app(self.app_uri)
File "/home/pi/.local/lib/python3.8/site-packages/gunicorn/util.py", line 430, in import_app
raise AppImportError("Application object must be callable.")
gunicorn.errors.AppImportError: Application object must be callable.
As you can see, the error seems to be with api_instance = server.app.wsgi()
, which appears in each of my server hooks and is likewise my point of failure in each.
The absolute weirdest thing about this is that the app/Gunicorn works perfectly if instantiated directly from the terminal:
/home/pi/.local/bin/gunicorn -c /home/pi/nano/manager/src/api/gunicorn.conf.py --bind unix:nano_api.sock --umask 007
But produces the above error if instantiated from the following service:
[Unit]
Description=Gunicorn instance serving the Nano API
After=network.target
[Service]
User=pi
Group=www-data
WorkingDirectory=/home/pi/nano/manager/src/api
ExecStart=/home/pi/.local/bin/gunicorn -c /home/pi/nano/manager/src/api/gunicorn.conf.py --bind unix:nano_api.sock --umask 007
[Install]
WantedBy=multi-user.target
Anyone have any ideas as to what might be causing this issue and how to fix it? Many thanks!
Upvotes: 1
Views: 2865
Reputation: 143
Well, after a solid 10 hours of debugging, I finally figured out the problem...
I'm ashamed to say it was just a naming conflict. I had a package named "api" containing a module named "api.py" that housed a Flask instance named, you guessed it, "api."
Since I've given these three items distinct names and fixed my references, everything's ran smoothly.
Upvotes: 7