Deploy FastAPI with gunicorn and uvicorn in docker - docker

I have built a FastAPI service that I deploy with the next DockerFile:
FROM python:3.8.10
RUN mkdir /code
WORKDIR /code
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--proxy-headers","--host=0.0.0.0", "--port=80"]
Because I am going to use docker compose to deploy the image in a server, i want to gunicorn to manage it all.
My question is how I adapt the Dockerfile to include the gunicorn. I have seen that to run the api with both I should use the following command but i do not how to translate this to the docker file:
gunicorn -k uvicorn.workers.UvicornWorker
Thanks

Related

Dockerfile for a fastAPI app using Factory pattern with unicorn

I am building a back-end service for a full-stack application using fastAPI and unicorn.
src/asgi.py
import uvicorn
from src import create_app
app = create_app()
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", log_level="info", reload=True)
src/init.py
from fastapi import FastAPI
from src.api.v1.auth import auth_router
from src.core.config import *
def create_app() -> FastAPI:
root_app = FastAPI()
root_app.include_router(
auth_router,
prefix="/api/v1",
tags=["auth"],
)
return root_app
Dockerfile
FROM python:3.9
RUN mkdir /app
WORKDIR /app
RUN apt update && \
apt install -y postgresql-client
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
How I am building and running:
docker build -t travian-back:v1 .
travian-back:v1 uvicorn asgi:app
There is no error at all, server is up at http://127.0.0.1:8000
Now I am trying to directly add the uvicorn asgi:app command to my Dockerfile. The reason is because I am going to use docker-compose at the end and it would be easier. This is what I have now:
Dockerfile
RUN mkdir /app
WORKDIR /app
RUN apt update && \
apt install -y postgresql-client
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "asgi:app"]
Now instead of doing travian-front:v1 uvicorn asgi:app I am doing travian-back:v1 uvicorn asgi:app , I have no error when building and running my docker image but the server can't be reached at http://127.0.0.1:8000
The thing is that you don't run the asgi file as main, since you use uvicorn to point to it. So it's not listening on 0.0.0.0 or better put, all those options are ignored.
Either invoke the asgi file directly, which I would not recommend, or drop the asgi file and use uvicorn with the --factory flag and point it to your app factory.
ENTRYPOINT ["uvicorn", "src.init:create_app", "--factory", "--host 0.0.0.0"]
I am using entrypoint here so that you can pass additional flags such as log level on run without overriding this.
docker run -p 8000:8000 myapp --log-level warning
That said, I am somewhat confused by your file name init.py. Do you mean __init__.py? If so I would not put the factory in this file, __init__.py is not meant to be used like this. Put it in a file named main.py or similar.

Docker - Issue dockerizing flask app when the file exists in that path

I am trying to dockerize a flask app using the below code:
FROM continuumio/anaconda3:4.4.0
COPY . /demo_app
EXPOSE 5000
WORKDIR /demo_app
RUN pip install -r requirements.txt
CMD ["python", "flask_app", "manage.py", "runserver"]
I am trying to run the docker app using the below code:
docker run -p 5000:5000 test_app
I however am getting an error
python: can't open file 'flask_app': [Errno 2] No such file or directory
demo_app/flask_app/ this is the directory, where python expecting fileName.
python FlaskApp.py
how-run-flask-application
So either change workdir or change the cmd.
WORKDIR /demo_app/flask_app
RUN pip install -r requirements.txt
CMD ["python","manage.py", "runserver"]
Or change the CMD but make sure import should not break by doing this
CMD ["python","flask_app/manage.py", "runserver"]

Dockerize two things and use in one directory

I have an Angular - Flask app that I'm trying to dockerize with the following Dockerfile:
FROM node:latest as node
COPY . /APP
COPY package.json /APP/package.json
WORKDIR /APP
RUN npm install
RUN npm install -g #angular/cli#7.3.9
CMD ng build --base-href /static/
FROM python:3.6
WORKDIR /root/
COPY --from=0 /APP/ .
RUN pip install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["app.py"]
On building the image and running the image, console gives no errors. However, it seems to be stuck. What could be the issue here?
Is it because they are both in different directories?
Since I'm dockerizing Flask as well as Angular, how can I put both in same directory (right now one is in /APP and the other in /root)
OR should I put the two in separate containers and use a docker-compose.yml file?
In that case, how do I write the file? Actually my Flask calls my Angular and both run on same port. So I'm not sure if running in two different containers is a good idea.
I am also providing the commands that I use to build and run the image for reference:
docker image build -t prj .
docker container run --publish 5000:5000 --name prj prj
In the Angular build first stage of the Dockerfile, use RUN instead of CMD.
CMD is for running a command after the final image is built.

Unable to create folders from django app with docker container

I am unable to create folder through the below command when my django app is running through the container is running.
os.makedirs(path)
The same command is able create when i run my django project from command prompt locally without docker.
my Dockerfile
FROM python:3.6.9-stretch
ENV PYTHONUNBUFFERED 1
ENVC_FORCE_ROOT true
RUN mkdir /src
RUN mkdir /static
WORKDIR /src
ADD ./src /src
RUN pip install -r requirements.pip
CMD python manage.py collectstatic --no-input;python manage.py migrate; gunicorn specextractor.wsgi -b 0.0.0.0:8000
when in my views.py i used to create the folders with the username whoever logged into the application. The functionality is working when running without docker , but it fails when running through docker container.
Any suggestion would be really helpful.

Getting "/usr/bin/python: No module named" whenever I run the Docker container

I have a flask API alongside with another class for Machine learning prediction that I need to dockerize so I have a Dockerfile as shown below. I run the container using
sudo docker run -d -p 5000:5000 test
However every-time I run it, it crashes.
I can see that the status of it "Exited (1)" whenever I run
docker ps --all
When I do docker logs containerIDHere I get the reason of the crash as below
/usr/local/bin/python: No module named
Dockerfile
FROM python:3.6
RUN mkdir -p /app
WORKDIR /app
COPY requirements.txt /app
RUN pip install -r ./requirements.txt
COPY Network /app
COPY Train /app
EXPOSE 5000
CMD ["python", "-m" ,"Network.Api"]

Resources