Skip to content
Advertisement

How to stop uvicorn ASGI web server running when building Dockerfile?

Docker build running endlessly

I’m trying to build a docker image, but i’m running into an issue with uvicorn server running while building which causes it to never build.

so i’m looking for an alternative way of building/running the docker image.

Required the docker image should run the uvicorn server on startup

Haven’t found any real solution from browsing SOF/Google

Code

main.py file

from fastapi import FastAPI, Request, Response
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles

from src.scraper import Scraper

app = FastAPI()
templates = Jinja2Templates(directory="src/templates")
app.mount("/static", StaticFiles(directory="src/static"), name="static")

scraper = Scraper()
scraper.scrapedata()


@app.get("/")
async def home(request: Request):
    return templates.TemplateResponse("index.html", {"request": request, "items": scraper.scrapedata()})


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

Dockerfile

FROM python:3.9.2-buster

ENV PYTHONDONTWRITEBYTECODEBYDEFAULT=1

ENV PYTHONUNBUFFERED=1

ENV PYTHONPATH "${PYTHONPATH}:/usr/src/"

COPY requirements.txt .
RUN python -m pip install --upgrade pip
RUN python -m pip install -r requirements.txt

WORKDIR /website
COPY . /website

RUN adduser -u 5678 --disabled-password --gecos "" webuser && chown -R webuser /website
USER webuser

EXPOSE 8000

#this is the cause for endless running. Any other way to do this?
RUN python -m uvicorn src.main:app --host 0.0.0.0 --port 8000

Console output

[+] Building 15.2s (11/12)
[+] Building 974.8s (11/12)
 => [internal] load build definition from Dockerfile                                                               0.1s
 => => transferring dockerfile: 512B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 34B                                                                                   0.0s
 => [internal] load metadata for docker.io/library/python:3.9.2-buster                                             2.4s
 => [1/8] FROM docker.io/library/python:3.9.2-buster@sha256:56f1b4dbdebb3b6ec31126e256c0852d18e79909ed1df8b594e56  0.0s
 => [internal] load build context                                                                                  0.2s
 => => transferring context: 135.50kB                                                                              0.2s
 => CACHED [2/8] COPY requirements.txt .                                                                           0.0s
 => CACHED [3/8] RUN python -m pip install --upgrade pip                                                           0.0s
 => CACHED [4/8] RUN python -m pip install -r requirements.txt                                                     0.0s
 => CACHED [5/8] WORKDIR /website                                                                                  0.0s
 => [6/8] COPY . /website                                                                                          0.3s
 => [7/8] RUN adduser -u 5678 --disabled-password --gecos "" webuser && chown -R webuser /website                  5.5s
 => [8/8] RUN python -m uvicorn src.main:app --host 0.0.0.0 --port 8000                                          966.2s
 => => # 200
 => => # INFO:     Started server process [7]
 => => # INFO:     Waiting for application startup.
 => => # INFO:     Application startup complete.
 => => # INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)


Advertisement

Answer

Use CMD instead of RUN to launch the uvicorn server in the Dockerfile. It will retard the execution of the command to when the container is launched.

RUN runs commands during the image building.

CMD runs commands during container launching.

Your Dockerfile would be rewritten as follows:

FROM python:3.9.2-buster

ENV PYTHONDONTWRITEBYTECODEBYDEFAULT=1

ENV PYTHONUNBUFFERED=1

ENV PYTHONPATH "${PYTHONPATH}:/usr/src/"

COPY requirements.txt .
RUN python -m pip install --upgrade pip
RUN python -m pip install -r requirements.txt

WORKDIR /website
COPY . /website

RUN adduser -u 5678 --disabled-password --gecos "" webuser && chown -R webuser /website
USER webuser

EXPOSE 8000

CMD ["python", "-m", "uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement