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?
Related
I am dockerizing a React-Flask web application with separate containers for the frontend and the backend Flask API. Up to now I have only run this on my localhost using the default Flask development server. I then installed Gunicorn to prep the application for deployment with Docker later, and that also ran smoothly on my localhost.
After I ran docker compose up the two images built successfully, are attached to the same network, and I got this in the logs:
Logs For backend:
Starting gunicorn 20.1.0
Listening at: http://0.0.0.0:5000 (1)
Using worker: gthread
Logs For frontend:
react-flask-app#0.1.0 start
react-scripts start
Project is running at http://172.21.0.2/
Starting the development server...
But when I try to access the site at http://172.21.0.2/, localhost:5000 or localhost:3000 it is not accessible. Do I maybe need to add the name of the frontend or backend service?
In Docker Desktop it's showing that the frontend is running at port 5000 but there is no port listed for the backend, it just says it's running.
This is what my files and setup look like:
I added a gunicorn_config.py file as I read it is a good practice, rather than adding all of the arguments to the CMD in the Dockerfile:
bind = "0.0.0.0:5000"
workers = 4
threads = 4
timeout = 120
Then in my Flask backend Dockerfile I have the following CMD for Gunicorn:
FROM python:3.8-alpine
EXPOSE 5000
WORKDIR /app
COPY requirements.txt requirements.txt
ADD requirements.txt /app
RUN pip install --upgrade pip
ADD . /app
COPY . .
RUN apk add build-base
RUN apk add libffi-dev
RUN pip install -r requirements.txt
CMD ["gunicorn", "--config", "gunicorn_config.py", "main:app"]
Here I do "main:app" where my Flask app file is called main.pyand then app is my Flask app object.
I'm generally confused about ports and how this will interact with Gunicorn and in general. I specified port 5000 in the EXPOSE of both of my Dockerfiles.
This is my frontend Dockerfile:
WORKDIR /app
COPY . /app
RUN npm install --legacy-peer-deps
COPY package*.json ./
EXPOSE 3000
ENTRYPOINT [ "npm" ]
CMD ["start"]
And used 5000 in the bind value of my Gunicorn config file. Also, I previously added port 5000 as a proxy in package.json.
I will initially want to run the application using Docker on my localhost but will deploy it to a public host service like Digital Ocean later.
This is my Docker compose file:
services:
middleware:
build: .
ports:
- "5000:5000"
frontend:
build:
context: ./react-flask-app
dockerfile: Dockerfile
ports:
- "3000:3000"
The other thing to mention is that I also created a wsgi.py file and I was wondering do I need to add this to the Gunicorn CMD in my Dockerfile:
from main import app
if __name__ == "__main__":
app.run()
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'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.
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)
I'm trying to get gunicorn working with nginx in a docker compose file. My python code is just a flask CRUD app.
The entry point for my flask app is at ./flask_app/app.py and I've got the following for a docker compose yaml file
version: '3'
services:
flask_app:
container_name: flask_app
restart: always
build: ./flask_app
ports:
- "8000:8000"
command: gunicorn -w 1 -b :8000 app:server
nginx:
container_name: nginx
restart: always
build: ./nginx
ports:
- "80:80"
depends_on:
- flask_app
and here's my app file
from flask import Flask
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_pyfile('config.py')
db = SQLAlchemy(app)
ma = Marshmallow(app)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=6000, debug=True)
However when I run the above I'm getting the following error
Recreating ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_flask_app ... error
ERROR: for ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_ce38627418c1_flask_app Cannot start service flask_app: OCI runtime create failed: container_linux.go:296: starting container process caused "exec: \"gunicorn\": executable file not found in $PATH": unknown
ERROR: for flask_app Cannot start service flask_app: OCI runtime create failed: container_linux.go:296: starting container process caused "exec: \"gunicorn\": executable file not found in $PATH": unknown
ERROR: Encountered errors while bringing up the project.
As far as I can tell it doesn't seem my app = Flask(__name__) variable and I'm not sure why. I'm basing my approach on this working example https://github.com/sladkovm/docker-flask-gunicorn-nginx.
Does anyone have any ideas?
EDIT: In my flask_app directory I have a Dockerfile that the docker_compose file is pointing to. Here is what it looks like:
FROM python:3.6.2
RUN mkdir -p /flask_app/app
WORKDIR /flask_app/app
COPY . /flask_app/app
RUN pip install --no-cache-dir -r requirements.txt
COPY . /flask_app/app
This may not be the solution for the original poster's problem, but in case anyone else new to docker is on this page searching for a solution, maybe this will help.
If you're building with docker-compose, remember that docker-compose up doesn't actually rebuild images (https://github.com/docker/compose/issues/1487), so perhaps your old requirements file without gunicorn is still being used.
To fix this, rebuild with docker-compose build and you should be fine.
Hopefully this helped someone.
try
pip install gunicorn
pip freeze > requirements.txt
and then
docker-compose build
docker-compose up -d
enjoy