Error: '$PORT' is Not a Valid Port Number During Deployment

I am encountering an issue while deploying my application on Koyeb. The application fails to start and the logs show the following error:

vbnet

Copy code

Error: '$PORT' is not a valid port number.
Application exited with code 1. This usually indicates an application failure. Check that the command used to launch your application is correct.

What I’ve Done So Far:

  1. Checked the Environment Variables: I have confirmed that the PORT variable is set correctly in the Koyeb environment settings. It is defined as a valid number (5000 or 8000), depending on the configuration.
  2. Reviewed Application Code:
  • The application is designed to retrieve the PORT environment variable as shown below:

python

if __name__ == '__main__':
    port = os.environ.get("PORT", "5000")
    if not port.isdigit():
        raise ValueError("The port value is not a valid number.")
    app.run(host="0.0.0.0", port=int(port))
  • The Procfile is configured as follows:

plaintext

web: gunicorn run:app --bind 0.0.0.0:$PORT
  1. Local Testing:
  • I have tested this setup locally, and it works as expected without any issues when I manually set the PORT variable to 5000.

Issue:

Despite these configurations, the deployment process on Koyeb consistently fails with the error “$PORT is not a valid port number.” I suspect there might be an issue with how the environment variable is being interpreted or passed within the Koyeb environment.

Could you please assist in diagnosing and resolving this issue? If there’s a specific configuration or a known issue that I might be missing, I would appreciate your guidance.

Additional Information:

  • Application Framework: Flask
  • Web Server: Gunicorn
  • Deployment Method: GitHub push

Thank you for your help in resolving this issue promptly.

Hello,

Where is defined your “plaintext” with the gunicorn command, what is it?

I suspect it’s that component that transform the PORT environment variables to $PORT and override what you defined in Koyeb’s deployment definition.

Have a nice day.

PS: Could you give me the deployment ID so I can double-check that the PORT environment variable is correctly defined in your deployment definition? Thank you.

Thanks for your fast reply.

web: gunicorn run --bind 0.0.0.0:$PORT

When the application runs locally, it works fine using Flask’s development server, and the PORT environment variable is correctly set to 5000. However, when deploying on Koyeb, it seems that the $PORT environment variable isn’t being interpreted as expected, which might be causing the issue.

Could you clarify if there’s something in the deployment process that could be altering how the PORT environment variable is passed or processed? Additionally, is there anything specific in the deployment definition that might be overriding this variable?

My settings in Koyeb have the same port 5000

Here is the deployment ID for your reference: ID: c6eeed4a-1b35-49db-9371-eea50cbcf759.

Thanks!

Without accessing your source code it’s a bit problematic to help you troubleshoot the situation properly.

But, you have properly defined the PORT to 5000 in the deployment definition. So I suspect something is modifying that value between the moment we start the container in a microVM and when your Python application is started. Could it be something in your Dockerfile?

Since I’m no expert with Flask and the Python ecosystem in general, I’ll ask internally if someone has an idea, and how we could fix it.

I’m sorry for this inconvenience.

Thomas,

Hi, thanks.

I can use 8000, only changed it because of the problem.
I’m not expert to, but i’m making a complete trouble shoot with ChatGPT and everything seems OK.

My docker file is this, you see anything wrong?

Use an official Python runtime as a parent image

FROM python:3.12-slim

Install system dependencies

RUN apt-get update && apt-get install -y
libpq-dev
build-essential
unixodbc-dev
&& rm -rf /var/lib/apt/lists/*

Set the working directory

WORKDIR /app

Copy the current directory contents into the container at /app

COPY . /app

Install any needed packages specified in requirements.txt

RUN pip install --no-cache-dir -r requirements.txt

Expose the port that will be used by the app

EXPOSE 8000

Run the application using Gunicorn, bind to the port provided by Koyeb

CMD [“gunicorn”, “run:app”, “–bind”, “0.0.0.0:$PORT”]

Thanks,

The issue is from the CMD you are using on your Dockerfile. If I explain it badly, CMD doesn’t run the command you’re giving in a shell, and thus, doesn’t interpret the $PORT variable.

For that, you need /bin/bash (or any other shell that match your preference) to execute the command gunicorn run:app –bind 0.0.0.0:$PORT. There are several solutions for that:

Solution 1

The one I recommend the most.

Create a new file in your repository that will be responsible for launching your application. For the sake of the demonstration, I will call it scripts/docker-cmd

The content of this file should be:

#!/bin/bash

gunicorn run:app –bind 0.0.0.0:$PORT

Be mindful that this file must be executable. Otherwise, it will fail!

Then, change the CMD operation in your Dockerfile to this:

CMD ["/app/scripts/docker-cmd"]

Solution 2

Change the CMD operation to this:

CMD ["/bin/bash", "-c", "gunicorn run:app –bind 0.0.0.0:$PORT"]

Solution 3

Easier, but it could break in the future if you’re not careful.

Replace the CMD operation by the following block:

ENTRYPOINT ["/bin/bash", "-c"]

CMD ["gunicorn run:app –bind 0.0.0.0:$PORT"]

Hope that helps,

1 Like

Thanks Thomas, I tested solution 2 and worked perfectly. I have new erros now, that’s good! :slight_smile:

1 Like