seratch / ChatGPT-in-Slack

Swift demonstration of how to build a Slack app that enables end-users to interact with a ChatGPT bot
MIT License
437 stars 162 forks source link

How to deploy the app onto render.com #4

Closed abhinavsharma closed 1 year ago

abhinavsharma commented 1 year ago

Hi, first, thank you for building this, really appreciate it and would be happy to help! I'm trying to use it and it actually works perfectly for a few minutes then the deploy fails in Render.com with the following error

CleanShot 2023-03-04 at 15 03 25@2x

Do you have suggestions for fixing or a suggested method for deploying elsewhere? Thanks

seratch commented 1 year ago

Hi @abhinavsharma, thank you for trying our app!

I noticed that the render.com platform requires a deployed app to have an HTTP endpoint returning 200 OK for health check requests, with GET /healthz as the default path. Since this app establishes a WebSocket connection to Slack's WS server and does not serve any HTTP endpoints, some code modifications are needed to make it compatible with the platform.

To help with this, I'd recommend adding the Flask (if you prefer others like FastAPI, it's totally fine too!) dependency for serving the /healthz endpoint. Check the following diff to learn how to modify the code.

I haven't deployed the app onto the platform myself, so some details may still need to be adjusted. If you have any further questions, feel free to ask them in their community forum (https://community.render.com/). We hope this was helpful to you!

diff --git a/Dockerfile b/Dockerfile
index 41af2c1..b3c2916 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,6 +8,7 @@ WORKDIR /app/
 COPY *.py /app/
 COPY --from=builder /usr/local/bin/ /usr/local/bin/
 COPY --from=builder /usr/local/lib/ /usr/local/lib/
+# If you want to use flask command instead, changing the following line is necessary
 ENTRYPOINT python app.py

 # docker build . -t your-repo/chat-gpt-in-slack
diff --git a/app.py b/app.py
index ce7310f..1b9e868 100644
--- a/app.py
+++ b/app.py
@@ -249,4 +249,21 @@ if __name__ == "__main__":
         next_()

     handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
-    handler.start()
+    # The `connect()` method does not block the current thread, unlike `start()`
+    handler.connect()
+
+    # Set up a health check endpoint for render.com deployments
+    # https://render.com/docs/deploys#zero-downtime-deploys
+    from flask import Flask
+    web = Flask(__name__)
+    @web.route("/healthz", methods=["GET"])
+    def hello_world():
+        if handler.client.is_connected():
+            return "OK"
+        return "Something is wrong!", 500
+
+    # For python app.py, having the following code is a good way to go
+    # If you prefer using flask command instead, it works too.
+    # Redner works with any open port, so Flask's default 5000 should work
+    # https://community.render.com/t/how-ports-and-https-are-handled-for-docker-deploy/363
+    web.run()
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index c91ac23..4a52bf5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
 slack-bolt>=1.16,<2
 openai>=0.27,<0.28
-tiktoken>=0.3.0,<0.4
\ No newline at end of file
+tiktoken>=0.3.0,<0.4
+flask>=2.2.3,<3
\ No newline at end of file
abhinavsharma commented 1 year ago

thank you for offering a patch, really appreciate it!

seratch commented 1 year ago

Thanks for your reply! Since I've provided an answer to your question here, let me close this issue now. Please feel free to write in whenever you have follow-up questions!

abhinavsharma commented 1 year ago

Just to leave this here for the future, it turns out that if there's no web requests (I suspect this means http) for 15 minutes on the free tier, then it shuts down the service. https://render.com/docs/free