Deploying a slack_bolt app with gunicorn

We recently wanted to deploy a small Slack bot built with slack_bolt to production with gunicorn.

However, the slack_bolt example doesn't really show how to do this, so we wanted to share here in case anyone else is stuck.

💡
Note that you want to be looking at the Python version of the slack_bolt docs.

The sample code from the slack_bolt python docs is as follows:

import os
# Use the package we installed
from slack_bolt import App

# Initializes your app with your bot token and signing secret
app = App(
    token=os.environ.get("SLACK_BOT_TOKEN"),
    signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)

# Add functionality here
# @app.event("app_home_opened") etc


# Start your app
if __name__ == "__main__":
    app.start(port=int(os.environ.get("PORT", 3000)))

However, if you just point your gunicorn command to the app object here directly, for example gunicorn app:app, you're going to get an App failed to load error.

Instead, according to the examples in the bolt_python repo, you need to add the following lines to your code:

from flask import Flask, request

flask_app = Flask(__name__)
handler = SlackRequestHandler(app)

@flask_app.route("/slack/events", methods=["POST"])
def slack_events():
    return handler.handle(request)

You can add them right below the event handling code like this:

import os
# Use the package we installed
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler

# Initializes your app with your bot token and signing secret
app = App(
    token=os.environ.get("SLACK_BOT_TOKEN"),
    signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)

# Add functionality here
# @app.event("app_home_opened") etc

# Attach the slack_bolt app to a flask app handler
from flask import Flask, request

flask_app = Flask(__name__)
handler = SlackRequestHandler(app)

@flask_app.route("/slack/events", methods=["POST"])
def slack_events():
    return handler.handle(request)


# Start your app
if __name__ == "__main__":
    app.start(port=int(os.environ.get("PORT", 3000)))

You will then able to start your app with gunicorn using the following command:

gunicorn --workers=2 app:flask_app

Subscribe to Frindle Blog

Sign up now to get access to the library of members-only issues.
Jamie Larson
Subscribe