I'm messing about with Docker (using Docker Toolbox for OSX) and can't seem to get my application to work. It's a simple flask application which looks like this:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return 'Hello World!'
if __name__ == '__main__':
app.run()
Now my Dockerfile contains the following
FROM python:2.7.11-wheezy
ADD ./application/* /opt/local/application/
ADD ./project-requirements.txt /opt/local/application/requirements.txt
RUN pip install -r /opt/local/application/requirements.txt
CMD ["/usr/local/bin/python", "/opt/local/application/app.py"]
EXPOSE 5000
I build the container by running docker build -t python_app . and subsequently boot the container by running docker -i -P python_app and see that the application is booted inside the container, as the output of the command is * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit).
Now when I run docker ps I can see the container is running
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
448defb349ce python_app "/usr/local/bin/pytho" About a minute ago Up About a minute 0.0.0.0:32769->5000/tcp angry_jang
But when I try to curl the container, I get a connection refused error.
$ curl $(docker-machine ip default):32769
curl: (7) Failed to connect to 192.168.99.100 port 32769: Connection refused
I have no clue where I'm going wrong with this and any help is much appreciated!
I found the issue, I had to change
app.run()
to
app.run(host='0.0.0.0')
in the app.py file.
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'm trying to create a simple web application container within Ubuntu-WSL2 with the help of the Docker. So I've built my container creating my-simple-webapp folder and within that folder, I've created Dockerfile and app.py files;
Dockerfile
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y python python-pip
RUN pip install flask
COPY app.py /opt/
ENTRYPOINT FLASK_APP=/opt/app.py flask run --host=0.0.0.0 --port=8080
app.py
import os
from flask import Flask
app = Flask(__name__)
#app.route("/")
def main():
return "Welcome!"
#app.route('/how are you')
def hello():
return 'I am good, how about you?'
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
When I run the command docker build ./my-simple-webapp it works without error. However when I use my browser to connect my container typing 172.17.0.2:8080, o.o.o.o:8080 or localhost:8080 connection times out.
Resource : https://github.com/mmumshad/simple-webapp-flask
If all you run is docker build... then you still need to start your container with docker run....
You can open the docker dashboard (in your Windows tray) to see if your container is actually running.
To actually run your app you need to start a container. First, build the image:
docker build -t simple-webapp-flask .
Then start a container using the image, with 8080:8080 mapping from container to your host:
docker run -p 8080:8080 simple-webapp-flask
If you want to deploy your flask application, you need to choose from the following options:
https://flask.palletsprojects.com/en/1.1.x/deploying/
The way you are trying to do it, can be used only for development purposes.
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 have created a simple flask app that is running on a this is the skeleton o the flask app, which by default runs at port 5000:
# Create the application instance
app = connexion.App(__name__, specification_dir="./")
# read the swagger.yml file to configure the endpoints
app.add_api("swagger.yml")
# Create a URL route in our application for "/"
#app.route("/")
def home():
"""
This function just responds to the browser URL
localhost:5000/
:return: the rendered template "home.html"
"""
return render_template("home.html")
if __name__ == "__main__":
app.run(debug=True)
In the Dockerfile I'm exposing the same port:
RUN python3 -m pip install -r requirements.txt
COPY . /app
EXPOSE 5000
Then I run the container as:
sudo docker run -d -p 5000:5000 my_app:latest
and once the container is up, I'm able to acces to app at:
http://localhost:5000
Now, I'm trying to change to port 5100, for that I'm changing:
a) In the Dockerfile:
COPY . /app
EXPOSE 5100
...
b) When I run the container:
sudo docker run -d -p 5100:5100 my_app:latest
But when I try to visit: http://localhost:5100/
The app is not running there
When I do Docker ps this is shown:
EDIT:
I tried changing the flask app:
app.run(host='0.0.0.0', port=5100)
Still not working, this is the screenshot from docker ps:
Not sure if the error is because still says 5000: at the begining:
5000/tcp, 0.0.0.0:5100->5100/tcp romantic_fermi
This is what I get from docker logs...
* Serving Flask app "server" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
You could technically change the default port assigned to the Flask object, but it's simpler to just change the docker mapping.
When you run a command like this:
$ docker run -d -p 5100:5100 my_app:latest
You are saying that you want to forward a port from inside the container (on the right) to your host machine (on the left).
# Left side is your host machine
# Right side is inside of the container
5100:5100
So you could update your run to map to 5000 inside of the container:
$ docker run -d -p 5100:5000 my_app:latest
Then you'll be able to access via http://localhost:5100
PS: If you haven't used docker-compose before, I would highly recommend setting it up after you've worked through this issue. It'll make your life easier in general.
On your .py script ou need to set 5100 port with:
app.run(debug=True,host='0.0.0.0', port=5100)
Everything else you did is correct!
If still your python are listening on port 5000, probably it's the old version.