my python app runs fine as a local docker container, but when trying to deploy on heroku, i get this error:
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
if __name__ == '__main__':
from os import environ
app.run(host='0.0.0.0', port=environ.get('PORT', 5000))
my dockerfile:
FROM python:3
# set a directory for the app
WORKDIR /usr/src/app
# copy all the files to the container
COPY . .
# install dependencies
RUN pip3 install --no-cache-dir -r requirements.txt
# heroku doesn't need this
# EXPOSE 5000
# run the command
CMD ["python3", "app.py"]
i thought it might have to do with the app being a bit too big for dyno=1 and that i'd have to pay to increase the dynos? but I'm not sure..
thanks in advance!!
The application cannot bind to the Heroku port, nothing to do with the Dyno. Try to cast to int the port before assigning it
port = int(os.environ.get("PORT", 5000))
Related
I am trying to run a flask app using a docker.
Operating system Windows 11, WSL image Ubuntu-20.04.
A simple reproducible example:
https://github.com/Konrad-H/stackoverflow-question
If I run (inside a venv)
$ python app/main.py
the following message appears in the console:
Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
And I can successfully connect to the app.
On the other hand, if I try to run the repo using:
$ docker build -t s-o-question:latest .
$ docker run -p 5000:5000 s-o-question
I get the exact same message on the console, but the webpage takes a long time loading and after a while a connection timeout appears.
The error appears both inside WSL2 and inside Windows.
Source Code:
main.py
import logging
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def index():
print("Hello World I am Sea")
return "Hello big world"
if __name__ == "__main__":
app.logger = logging.getLogger("audio-gui")
app.run( host='0.0.0.0',port=5000, debug=True)
Dockerfile
FROM python:3.8
# Working Directory
WORKDIR /app
# Copy source code to working directory
COPY . ./app /app/
# Install packages from requirements.txt
# hadolint ignore=DL3013
RUN pip install --no-cache-dir --upgrade pip &&\
pip install --no-cache-dir --trusted-host pypi.python.org -r requirements.txt
EXPOSE 5000
ENTRYPOINT [ "python" ]
CMD [ "app/main.py" ]
I had the same issue. The URL http/localhost:5000/ worked for me (5000 is my exposed port number). you can try and see if it works. Alternatively, you can also try http://<host-ip>:5000/. Note that the host-ip should be IP address of your local machine not the IP address of the docker container.
you can also check this answer
The issue is that you cannot use same port number for ex if your app runs on port 5000 it must be bind to another port like 8080 in docker .
try this docker run -p 8080:5000 s-o-question
I had the same issue on my win 11 device , i worked around this using the above solution.
I have docker running on my Windows 10 OS and I have a minimal flask app
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host ='0.0.0.0', port = 5001, debug = True)
And I am dockerizing it using the following file
FROM python:alpine3.7
COPY . /opt
WORKDIR /opt
RUN pip install -r requirements.txt
EXPOSE 5001
ENTRYPOINT [ "python" ]
CMD ["app.py", "run", "--host", "0.0.0.0"]
From what I am seeing on other posts and on Flask tutorials having a 0.0.0.0 should allow me to connect from the windows firefox browser when I type 0.0.0.0:5001 but it is not connecting, I keep getting a 'unable to connect' message. I remember using the 0.0.0.0:port to connect in localhost on a linux ubuntu machine but for whatever reason its not letting me connect on Windows. Is there a special setting to connect on windows ?
Inside the Docker container, the private port is 5001. This private port then needs to be mapped to a public port when running the container. For example, to set the public port to 8000, you could run:
$ docker run --publish 8000:5001 --name <docker-container> <docker-container>:<version-tag>
The Flask app would then be accessible at URL: http://127.0.0.1:8000
Dockerfile
In addition, since in app.py you are setting the host and port, there is no need to specify these values in the Dockerfile CMD. But the public port (in this example 8000) needs to be exposed.
It also looks like the COPY command is placing everything under an /opt directory, so that needs to be included in the app path when launching the Flask app within Docker.
FROM python:alpine3.7
COPY . /opt
WORKDIR /opt
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "/opt/app.py"]
Docker-Flask Example
For a complete Flask-Docker example, including using Gunicorn, see:
Docker Python Flask Example using the Gunicorn WSGI HTTP Server
I am running Flask application in Python using docker-compose. I am able to run the Flask app using 5000 port. I am trying to run it on 6000 besides another Flask app running on 5000. But I am unable run it on 6000 port. Any help would be appreciated.
docker-compose.yml
version: '3.8'
services:
web:
build: ./web
ports:
- "6000:5000"
app.py
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Dockerfile:
FROM python:3
COPY . /app
WORKDIR /app
RUN pip install -U pip
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]
requirements.txt
Flask==1.1.1
Port 6000 is listening. I am able to get a connection succeeded by executing nc command with host and port.
I am unable to run the app on port 6000.
I got the following when I hit http://#{HOST_IP}:6000 in browser
This site can’t be reached
The web page at http://#{HOST_IP}:6000/ might be temporarily down or it may have moved permanently to a new web address.
6000 is unsafe port that is why browser not allowing to access the application.
how-to-fix-err-unsafe-port-error-on-chrome-when-browsing-to-unsafe-ports
But you should not allow this port, just try to publish another port.
version: '3.8'
services:
web:
build: ./web
ports:
- "5001:5000"
For downvoter
Here is Github Repo to verify this
git clone https://github.com/Adiii717/dockerize-flask-app.git
cd dockerize-flask-app/
# this will not work in the browser
PORT=6000 docker-compose up
You haven't defined any routes. The app server has no idea what routes are available nor does it know what you want to return, so you need to specify that.
Here's a more complete version of app.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Please refer to the Flask tutorial for a minimal app.
I am building and running this docker container. It is running a simple flask server. But when I run, it exited right after.
This is my Dockerfile
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
# CMD ["python3", "-m", "http.server", "8080"]
CMD ["python3", "./py_server.py"]
and this is py_server.py
from flask import Flask
app = Flask(__name__)
PORT = 8080
#app.route('/')
def hello_world():
return "Hello World"
if __name__ == '__main__':
app.run(PORT)
this is how I build and run the container respectively.
build:
docker build -t banuka/python-venv .
run:
docker run -dit -p 8080:8080 --name server1 banuka/python-venv:latest
Can someone tell me what I do wrong?
There are several issues:
You want the -it parameter, not -dit:
docker run -it -p 8080:8080 --name server1 banuka/python-venv:latest
You are passing PORT as a variable to the app.run() function, so that it is interpreted as the first host parameter, rather than what you want, which is for it to be the port parameter. What you want is this: app.run(port=8080)
As #Alexandre pointed out, if you're accessing the host remotely, then you need to explicitly bind it to host='0.0.0.0', so we need app.run(host='0.0.0.0',port=8080)
You have a bug in your Flask Code. You're trying to configure Flask Server PORT in a wrong way. This will throw the error you're experiencing:
AttributeError: 'int' object has no attribute 'startswith'
You should configure your Flask Server Port with the following way
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return "Hello World"
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8080)
The documentation: https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.run
EDIT: Added host='0.0.0.0' so you can access your Flask Server remotely.
you are maybe running procces that finishes and then exit ?
if you run you py script and it finishes so your container will be closed to ...
try using while(true) //and then your code
I am trying to create a new app that is written in Python Flask, run by gunicorn and then dockerised.
The problem I have is the performance inside the docker container is very poor, inconsistent and I do eventually get a response but I can't understand why the performance is decreasing. Sometimes I see in the logs [CRITICAL] WORKER TIMEOUT (pid:9).
Here is my app:
server.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return "The server is running!"
if __name__ == '__main__':
app.run()
Dockerfile
FROM python:3.6.9-slim
# Copy all the files to the src folder
COPY build/ /usr/src/
# Create the virtual environment
RUN python3 -m venv /usr/src/myapp_venv
# Install the requirements
RUN /usr/src/myapp_venv/bin/pip3 install -r /usr/src/requirements.txt
# Runs gunicorn
# --chdir sets the directory where gunicorn should look for the server files
# server:app means run the "server.py" file and look for the "app" constructor within that
ENTRYPOINT ["/usr/src/myapp/bin/gunicorn", "--bind", "0.0.0.0:5000", "--workers", "1", "--chdir", "/usr/src/", "server:app"]
# Expose the gunicorn port
EXPOSE 5000
requirements.txt
Click==7.0
Flask==1.1.1
gunicorn==20.0.0
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
I run the docker container like this:
docker build -t killerkode/myapp .
docker run --name myapp -p 5000:5000 killerkode/myapp
I managed to find this helpful article which explains why Gunicorn hangs.
https://pythonspeed.com/articles/gunicorn-in-docker/
The solution for me was to change the worker temp directory and increase the minimum workers to 2. I still see workers being killed off but there is no longer any delays / slowness. I suspect adding in the gthread will improve things further.
Here is my updated Dockerfile:
FROM python:3.6.9-slim
# Copy all the files to the src folder
COPY build/ /usr/src/
# Create the virtual environment
RUN python3 -m venv /usr/src/myapp_venv
# Install the requirements
RUN /usr/src/myapp_venv/bin/pip3 install -r /usr/src/requirements.txt
# Runs gunicorn
# --chdir sets the directory where gunicorn should look for the server files
# server:app means run the "server.py" file and look for the "app" constructor within that
ENTRYPOINT ["/usr/src/myapp/bin/gunicorn", "--bind", "0.0.0.0:5000", "--worker-tmp-dir", "/dev/shm", "--workers", "2", "--chdir", "/usr/src/", "server:app"]
# Expose the gunicorn port
EXPOSE 5000