I'm attempting to deploy a simple Discord bot written in python and containerized via Docker to Google Cloud Run.
The Dockerfile is very simple:
FROM python:3.9
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
ENV PORT 8080
ENV HOST 0.0.0.0
CMD [ "python3", "discord_bot.py"]
I can run the bot without issue locally in a Docker container and also pushed it up cleanly to Google Container registry via the cloudmigrate.yaml file below...
steps:
- id: "build image"
name: "gcr.io/cloud-builders/docker"
args: ["build", "-t", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}", "."]
- id: "push image"
name: "gcr.io/cloud-builders/docker"
args: ["push", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"]
substitutions:
_SERVICE_NAME: discord-bot
images:
- "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"
...but when I attempt to build a Cloud Run instance from the container, I get the issue below:
Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information
The only issue I have in the logs is the following:
We have successfully logged in as <username redacted>
Cloud Rundiscord-bot {@type: type.googleapis.com/google.cloud.audit.AuditLog, resourceName: namespaces/<project name redacted>/services/discord-bot, response: {…}, serviceName: run.googleapis.com, status: {…}}
{@type: type.googleapis.com/google.cloud.audit.AuditLog, resourceName: namespaces/<project name redacted>/services/discord-bot, response: {…}, serviceName: run.googleapis.com, status: {…}}
Oddly enough, as shown above, I actually get a message in the logs that the initial login completes successfully, but then it bombs out right after...the python script is a very simple placeholder right now...
import os
import discord
TOKEN = os.environ['DISCORD_BOT_LEVEL_TOKEN']
client = discord.Client()
@client.event
async def on_ready():
print('We have successfully logged in as {0.user}'.format(client))
@client.event
async def on_message(message):
#print(message)
#print(dir(message))
if message.author == client.user:
return
if message.content.lower() == 'hello':
await message.channel.send(f'Hello, {message.author.display_name}!')
return
if message.content.lower() == 'bye':
await message.channel.send(f'See you later, {message.author.display_name}!')
return
client.run(TOKEN)
Note: I added the environment variable directly on the Cloud Run setup so that's not an issue in this case.
I'm sure it's something simple, but I've been banging my head on this for a couple of hours now...
You cannot run discord on Cloud Run as your program does not start an HTTP server that listens on an HTTP port for connections. Your program creates a client that connects to Discord. The Cloud Run health check thinks your container has failed to successfully startup.
In summary, you have a client program connecting to a server (Discord) instead of a server program listening for connections from clients.
You could enable Cloud Run always-on CPU allocation and then start two processes. The HTTP Server and the Discord client. However, you will pay for an always running service.
Run more workloads on Cloud Run with new CPU allocation controls
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With