Help with Python Bot Deployment on Google Cloud Run
I’m trying to get my Python-based Discord bot working on Google Cloud Run but running into problems. The container builds fine and works locally, but fails when deployed.
My Docker Setup
Here’s my container configuration:
FROM python:3.10-slim
WORKDIR /bot
COPY deps.txt .
RUN pip install -r deps.txt
COPY src/ .
EXPOSE 8080
CMD ["python", "main.py"]
import os
import discord
from discord.ext import commands
TOKEN = os.getenv('BOT_TOKEN')
bot = commands.Bot(command_prefix='!')
@bot.event
async def on_ready():
print(f'Bot {bot.user} is now online!')
@bot.event
async def on_message(msg):
if msg.author == bot.user:
return
if msg.content.startswith('hi'):
await msg.channel.send(f'Hey there {msg.author.name}!')
if msg.content.startswith('goodbye'):
await msg.channel.send(f'Catch you later {msg.author.name}!')
await bot.process_commands(msg)
bot.run(TOKEN)
The Problem
Cloud Run shows this error: “Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable.”
The weird part is that I can see the bot actually connects to Discord successfully in the logs before it crashes. The container works perfectly when I test it locally with Docker.
I’ve set the BOT_TOKEN environment variable in the Cloud Run console already. Anyone know what might be causing this startup failure?
yeah your bot needs to listen on an http port or cloud run thinks it’s dead. quick fix - add from http.server import HTTPServer, BaseHTTPRequestHandler then start a basic server on the PORT env variable before bot.run(). works every time
Cloud Run kills containers that don’t bind to HTTP ports within the startup timeout. Your Discord bot connects fine via websocket, but Cloud Run still wants an HTTP listener on the PORT variable.
I fixed this by running a minimal HTTP server alongside my Discord bot using asyncio. Set up a simple aiohttp server for health checks on the required port while keeping the Discord connection active in the same event loop. No threading headaches and it works reliably.
Start your HTTP server before the Discord bot connects - otherwise Cloud Run might kill the container during Discord’s handshake. Also handle graceful shutdowns so both services stop cleanly when Cloud Run sends termination signals.
Cloud Run expects stateless HTTP services, not persistent connections. I hit this exact issue with my first Discord bot - the container would connect to Discord fine but then get killed by Cloud Run’s health checks. Here’s what fixed it: I added a basic HTTP endpoint alongside my bot code. In main.py, I threw in a simple HTTP server using Python’s built-in http.server module on the PORT environment variable, then ran the Discord bot in a separate thread. This keeps Cloud Run happy since it gets HTTP responses, while your Discord connection stays alive. The HTTP server doesn’t need to do much - just respond to health checks and prevent container termination.
same thing happened 2 me. cloud run thinks ur container crashed since discord bots dont handle http traffic. just add PORT = int(os.environ.get('PORT', 8080)) and spin up a simple web server with ur bot code - keeps cloud run from complainin.
Cloud Run expects HTTP servers, not long-running processes like Discord bots. Your bot connects to Discord fine, but Cloud Run kills the container because it’s not listening on the HTTP port.
Two ways to fix this: Add a simple HTTP server (Flask works great) that responds on the PORT environment variable for health checks. Or switch to Google Compute Engine or Kubernetes - they’re built for persistent apps like Discord bots. I had this exact issue and fixed it by adding a Flask server for health checks. Bot’s been running smoothly since.
Cloud Run kills your Discord bot because it expects HTTP requests, not persistent connections. Your bot connects to Discord fine, but Cloud Run can’t reach it on the HTTP port it’s looking for.
I’ve been there. You could hack together a Flask server for health checks, but there’s a better way that cuts out all the deployment mess.
Turn your Discord bot into an automated workflow instead. You’ll get proper error handling, logging, monitoring, and scaling without fighting Cloud Run’s HTTP demands. Same bot logic, rock-solid deployment.
Connect Discord webhooks straight to your workflow, process messages there, and respond through Discord’s API. No more container crashes or health check hacks.
My team switched all our Discord integrations this way - never going back. Way more reliable than cramming a persistent bot into Cloud Run’s HTTP box.
Latenode handles Discord bot deployments without the Cloud Run pain: https://latenode.com