I've setup a Python Flask project to point at an interpreter running in Docker:
Starting the Flask app from PyCharm IDE results in following output:
51be5e336622:python3 -u /opt/project/app.py
Starting server
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
Starting server
* Debugger is active!
* Debugger PIN: 328-461-278
Trying to open http://localhost:5000/ results in a page not found error.
If I run the app using Docker with Dockerfile:
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
EXPOSE 5000
#CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
CMD [ "python3", "-u" , "/app/app.py"]
The above Dockerfile builds the container PyCharm connects to and is configured within Pycharm as:
Running the Docker container using command docker run -p 5000:5000 services, the app is started on http://localhost:5000/ successfully.
Do I need to map the port 5000 from PyCharm IDE to the Docker container running on port 5000? How to achieve this, there does not seem to be an option within PyCharm IDE?
With the help of https://blog.jetbrains.com/pycharm/2017/03/docker-compose-getting-flask-up-and-running/ this is now working.
Dockerfile:
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
EXPOSE 5000
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
main method in app.py:
if __name__ == '__main__':
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)
logging.basicConfig(level=logging.INFO,
filename='./logs/' + str(
int(round(time.time() * 1000))) +'trade.log',
filemode="a+",
format="%(asctime)-15s %(levelname)-8s %(message)s",
datefmt='%Y-%m-%d %H:%M:%S')
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
print('Starting server')
app.run(host="0.0.0.0", port=5000, debug=True)
docker-compose.yml, note use of port 5000 :
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/app
Start docker-compose:
docker-compose up
Update PyCharm to use docker compose instance:
Output of executing main in app.py:
Attaching to ml-services_web_1
web_1 | Starting server
web_1 | * Serving Flask app "app" (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: on
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1 | * Restarting with stat
web_1 | Starting server
web_1 | * Debugger is active!
web_1 | * Debugger PIN: 828-722-345
web_1 | 172.20.0.1 - - [06/Apr/2021 13:36:32] "GET / HTTP/1.1" 200 -
http://localhost:5000/ is now accessible.
Related
This question already has answers here:
Deploying a minimal flask app in docker - server connection issues
(8 answers)
Closed 7 months ago.
[Editted]
I am trying to dockerize a simple flask project. I kept getting this error when I run the project using docker. On the other hand the project works just fine when I run it normally using python3 test-flask.py
Docker File
FROM python:3.9.6-slim
# https://www.lifewithpython.com/2021/05/python-docker-env-vars.html
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONUTF8=1 \
PIP_DISABLE_PIP_VERSION_CHECK=on
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
curl \
wget \
unzip \
jq \
ffmpeg \
libsndfile1-dev \
&& rm -rf /var/lib/apt/lists/*
RUN wget "https://download.pytorch.org/whl/cpu/torch-1.10.2%2Bcpu-cp39-cp39-linux_x86_64.whl" \
&& pip install torch-1.10.2+cpu-cp39-cp39-linux_x86_64.whl
RUN mkdir app
WORKDIR /app
COPY README.md .
COPY requirements.txt .
COPY setup.py .
COPY src ./src
RUN pip install .
# COPY main.py .
COPY test_flask.py .
CMD [ "python", "test_flask.py", "run", "--host", "0.0.0.0"]
docker-compose.yml
version: '3.9'
services:
asr-cpu-local:
build:
context: ./
dockerfile: ./Dockerfile
volumes:
- ./data:/data
- ./models:/models
ports:
- 127.0.0.1:8000:8000
In the Terminal and Docker Container log, after I run it with docker, it shows no error at all
* Serving Flask app 'test_flask' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:8000 (Press CTRL+C to quit)
* Restarting with stat
For additional information, I have run docker port to check, but the error still occured:
docker port <container-name>
8000/tcp -> 127.0.0.1:8000
For the File test_flask.py:
from flask import Flask
app = Flask(__name__)
import librosa
from src.jrasr.predictors import Wav2vec2bert2bertPredictor
MODEL_CONFIG = {
"name": "Wav2vec2bert2bertPredictor",
"version": "0.0.1",
"models": [
{
"name": "wav2vec2",
"dir": "/models/wav2vec2-base-csj-kana-v0.0.1"
},
{
"name": "bert2bert",
"dir": "/models/bert2bert-csj-kana-v0.0.1"
}
]
}
#app.before_first_request
def load_model_to_app():
# Load the model
app.predictor = Wav2vec2bert2bertPredictor(MODEL_CONFIG)
#app.route('/')
def index():
return "This is Home Page"
#app.route('/data/<audio_path>')
def predict(audio_path):
model = app.predictor
audio_path = "/data/"+audio_path
data, _ = librosa.load(audio_path, sr=16000, mono=True, duration=10)
words = model.predict(data)
result = "".join(words)
return result
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8000, debug=True)
But when I try to access the Ip address as shown in the Terminal and Docker Container Log, I got that 127.0.0.1 refuse to connect such as in the image shown below. The problem is in the terminal and docker log, there isn't any Error message, but still I can't access it, can anyone tell me, how to solve my problems?
Error at the local browser
127.0.0.1 is the localhost interface and when running inside the container only the container has access to it. To be accessible outside the container it should be the special IP 0.0.0.0 to bind all interfaces.
Solution 1
Change the host to be 0.0.0.0 instead of 127.0.0.1 in the test_flask.py. Something like the following snippet.
WARNING: As 0.0.0.0 binds all interfaces to the outside world it could be a security risk if running it locally instead of in a container. That said, the Solution 2 is the recommended one (With the 127.0.0.1 in the Python source as it is). So, when running it directly locally it binds to the localhost and when running it in the container it binds the outside world of the container itself.
...
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
Solution 2
On the other hand, to run it passing the host as an argument the Dockerfile should be changed to the following:
...
ENV FLASK_APP=test_flask
CMD ["flask", "run", "--host=0.0.0.0"]
Test it with the browser connecting to http://localhost:8000/ or http://127.0.0.1:8000/
folks i have a web folder which has the following files inside:
app.py
Docker file
requirements.txt
outside that file i have a docker-compose.yml
the code is as follows:
app.py
code...
if __name__ == "__main__":
app.run(host='0.0.0.0')
on the requirements txt:
Flask
flask_restful
on the DockerFile:
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./app.py" ]
and on the docker-compose.yml:
version: '3'
services:
web:
build: ./web
ports:
- "5000:5000"
i go on the terminal and i run
docker compose build and
docker compose up
and server runs as below:
se 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
PS C:\Users\sarandis\Desktop\Python API\web service> docker compose up
webservice-web-1 | * Serving Flask app 'app' (lazy loading)
webservice-web-1 | * Environment: production 0.6s
webservice-web-1 | WARNING: This is a development server.
Do not use it in a production deployment.
webservice-web-1 | Use a production WSGI server instead.
webservice-web-1 | * Debug mode: off Do not use it in a production deployment.
webservice-web-1 | * Running on all addresses.
webservice-web-1 | WARNING: This is a development server.
Do not use it in a production deployment.
webservice-web-1 | * Running on http://172.18.0.2:5000/ (PreDo not use it in a production deployment.ss CTRL+C to quit) ss CTRL+C to quit)
Gracefully stopping...
the problem i have when i click on the url it provides me it says that the site cant be reached!!
why is that? what em i doing wrong?
note that when i do flask run the app runs at it should and all the get and post requests work fine!
Thank you in advance
Have you tried to access http://localhost:5000 instead of the provided URL?
Docker creates image file and get run but no result on browser.
my Flask code
from flask import Flask
app = Flask(__name__)
#app.route("/")
def home():
return "Hello World"
if __name__ == "__main__":
app.run(host ='0.0.0.0', port = 5001,debug=True)
Dockerfile
FROM python:alpine3.7
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
docker-compose.yml file
version: "3.8"
services:
app:
build: .
command: python app.py
ports:
- "5001:5001"
volumes:
- .:/python-flask
after giving command :- docker-compose up
Result:
Starting docker_demo_app_1 ... done
Attaching to docker_demo_app_1
app_1 | * Serving Flask app 'app' (lazy loading)
app_1 | * Environment: production
app_1 | WARNING: This is a development server. Do not use it in a production deployment.
app_1 | Use a production WSGI server instead.
app_1 | * Debug mode: on
app_1 | * Running on all addresses.
app_1 | WARNING: This is a development server. Do not use it in a production deployment.
app_1 | * Running on http://172.18.0.2:5001/ (Press CTRL+C to quit)
app_1 | * Restarting with stat
app_1 | * Debugger is active!
app_1 | * Debugger PIN: 103-335-354
When I run http://172.18.0.2:5001/ on browser it says -
This site can’t be reached
172.18.0.2 took too long to respond.
That
Running on http://172.18.0.2:5001/
is misleading. That's the IP address inside the container. If you're connecting from outside the container, use
http://127.0.0.1:5001/
which is local to the browser. If your browsing from elsewhere, substitute the IP address of the server that's running the docker image.
0.0.0.0 will run on your machine’s IP address. To access your app via web browser , navigate to http://<machineIP>:5001
I am new to Docker.
Here is a very simple application written in DashPlotly:
FROM python:3.8-slim
COPY . /app
WORKDIR /app
RUN pip3 install --no-cache -r requirements.txt
EXPOSE 8050
CMD ["python3","./app.py","--host","0.0.0.0"]
#docker build -t test .
#docker run -p 8051:8050 -it test
Connecting to the PostgreSQL database...
Running on http://127.0.0.1:8050/
Debugger PIN: 479-458-364
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
But when a point the browser to 127.0.0.1:8051, it says connection reset...
The solution is to force the DashPlotly server to run on 0.0.0.0
app.run_server(host='0.0.0.0',debug=False, port=8050)
Im new to docker and Flask and I'm getting an issue when I try to run the app. The browser says the site (172.17.0.2:5000) can't be reached.
For anyone wondering, the Dockerfiles:
FROM ubuntu
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install flask
RUN mkdir -p /opt/MyApp-test
COPY . /opt/MyApp-test
WORKDIR /opt/MyApp-test
EXPOSE 5000
ENTRYPOINT python3 main.py
CMD flask run --host 0.0.0.0
The main.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return 'IT WORKED! I AM RUNNING FROM A DOCKER CONTAINER!!!'
if __name__ == '__main__':
app.run()
And when I run the container, I get:
(base) daniellombardi#Daniels-MacBook-Pro MyApp-test % docker run 2625
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
I try to go to http://127.0.0.1:5000/, unable to connect, then I inspect the container to get its IP address, and it says 172.0.1 instead of 127.0.0.1:5000, but also unable to connect. And the app works when I run it on my computer.
You should just bind the exposed port inside of your container to a port in docker host when calling docker run, thus docker run should be called this way:
docker run 2625 -p 5000:5000