Fastapi: [QUESTION] Docker build conversion from Flask...

Created on 27 Sep 2019  Â·  15Comments  Â·  Source: tiangolo/fastapi

Description

How can I change existing Dockerfile from flask project to Fastapi

Currently I have

FROM python:3.7
ENV HOME /root 
CMD [“/sbin/my_init”]
COPY . /app
WORKDIR /app
ENV PYTHONPATH /app
COPY pip.conf /root/.pip/pip.conf
RUN pip install -r requirements.pip
EXPOSE 5000
ENTRYPOINT [“python”]
CMD [“main.py”]

my-api/main.py:

APP = FastAPI(debug=True)

@APP.get("/hello-world")
async def hello():
    return {"Hello": "World"}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

And this is to be replaced by simply

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7

COPY ./app /app/app

It is doing the equivalent under the hood?
No pip install -r requirements.txt ? Have postgresql drivers and many dependencies...
No EXPOSE ?

COPY failed: stat /vat/lib/docker/tmp/docker-build746414079/app: no such file or directory

EDIT:

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7

COPY ./app 

$ docker build -t myfastapi .

$ docker run --rm -it -p 8000:80 myfastapi

{"loglevel": "info", "workers": 2, "bind": "0.0.0.0:80", "workers_per_core": 1.0, "host": "0.0.0.0", "port": "80"}

[2019-09-27 09:51:06 +0000] [1] [INFO] Starting gunicorn 19.9.0

[2019-09-27 09:51:06 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)

[2019-09-27 09:51:06 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker

[2019-09-27 09:51:06 +0000] [8] [INFO] Booting worker with pid: 8

[2019-09-27 09:51:06 +0000] [9] [INFO] Booting worker with pid: 9

email-validator not installed, email fields will be treated as str.

To install, run: pip install email-validator

email-validator not installed, email fields will be treated as str.

To install, run: pip install email-validator

[2019-09-27 09:51:06 +0000] [8] [INFO] Started server process [8]

[2019-09-27 09:51:06 +0000] [8] [INFO] Waiting for application startup.

[2019-09-27 09:51:06 +0000] [9] [INFO] Started server process [9]

[2019-09-27 09:51:06 +0000] [9] [INFO] Waiting for application startup.

[2019-09-27 09:51:17 +0000] [8] [INFO] ('172.17.0.1', 50510) - "GET /hello HTTP/1.1" 404

Tried in Chrome browser:

http://localhost:8000/hello-world

But this is getting 404?
{"detail" "Not Found"}

question

Most helpful comment

The CPU thing on Mac (not just Mac, I believe, though Mac may make it worse given the way volumes are handled) is a known issue with uvicorn. There has been discussion of integrating watchdog. You could submit a PR with it to uvicorn if it is a significant problem for you.

https://stackoverflow.com/questions/45682010/docker-invalid-reference-format#51208726

Based on the above link it looks like you need to change $(...) to ${...} on windows. I would encourage you to try searching the internet for your error messages rather than posting them straight here.

All 15 comments

You're going to http://localhost:8000/hello-world, but your server is listening on port 80. Try navigating to http://localhost/hello-world ?

Here's an example you may want to study:
https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/backend.dockerfile

You'll probably want to use a requirements.txt rather than listing out all dependencies directly in the dockerfile, the way it is done in the link above. (It sounds like that's how you are already doing it in your flask app, so shouldn't be too hard to port)

You might find the readme here useful: https://github.com/tiangolo/full-stack-fastapi-postgresql/tree/master/%7B%7Bcookiecutter.project_slug%7D%7D

Thanks but this:

https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/backend.dockerfile

does not show uvicorn:APP --reload command?

so just two lines in Dockerfile

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7

COPY ./app 

is sufficient to define a normally more verbose Dockerfile?

@DrNickMartin http://localhost/hello-world also no response...

@DrNickMartin http://localhost/hello-world also no response...

What do the container logs say anything useful? Would be good to confirm if you are hitting your webserver.

Got it working now:

docker run -d —rm -p 80:80 -v $(pwd):/app myfastapi /start-reload.sh

Then http://localhost/hello-world works

But CPU in Mac OS keeps revving?

Do I need to set number of worker threads, etc?

@scheung38 I believe the --reload flag on uvicorn is currently implemented in a way that is relatively inefficient. If you disable the flag (eg by running /start.sh rather than /start-reload.sh) you should notice reduced cpu usage.

@dmontagu so meaning changes in local machine I will need to

docker run --rm -d -e APP_MODULE="app.custom_app.custom_main:api" --name mycontainer -p 80:80 -v $(pwd):/app myfastapi /start.sh

everytime?

Is this a bug? if i use --reload to do live reload and it is causing CPU to rev until it is burning my Mac...

Win 10:

docker run --rm -d -e APP_MODULE="app.custom_app.custom_main:api" --name mycontainer -p 80:80 -v $(pwd):/app myfastapi /start.sh

invalid reference format?

How to perform this in Win 10?

The CPU thing on Mac (not just Mac, I believe, though Mac may make it worse given the way volumes are handled) is a known issue with uvicorn. There has been discussion of integrating watchdog. You could submit a PR with it to uvicorn if it is a significant problem for you.

https://stackoverflow.com/questions/45682010/docker-invalid-reference-format#51208726

Based on the above link it looks like you need to change $(...) to ${...} on windows. I would encourage you to try searching the internet for your error messages rather than posting them straight here.

@dmontagu thank you so much you are a real help. :)

if __name__ = "__main__":
    uvicorn.run(app, host="0.0.0.0", port=5000)

docker run --rm -it -d -e WORKER_PER_CORE="3 -e APP_MODULE="custom.custom_folder:APP" " etc

we can equally bake environment variables as per of the docker build process? so that

docker run -p 5000:5000 my-api-container

is all that is needed?

Tried in Dockerfile:

ENTRYPOINT["uvicorn"]

CMD["rest.rest:APP', "--host", "0.0.0.0", "--port", "5000"]

but

docker build -t my-api .

returns

Unknown : CMD["UVICORN"]

https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/celeryworker.dockerfile

Has example but not using Uvicorn?

@scheung38 you don't need to explicitly set the command in your Dockerfile nor in your docker command. It's handled for you in the image.

Yes, the Dockerfile is quite less verbose, because it does a lot for you.

You can add an extra fragment of something like:

COPY /app/requirements.txt

RUN pip install -r /app/requirements.txt

And you don't need anything else apart from the normal.

Please read the docs here: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker/blob/master/README.md

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

Was this page helpful?
0 / 5 - 0 ratings