skip to Main Content

I’m setting up a fastapi compose.yaml file for development.

Here the simplified layout of my project:

enter image description here

Dockerfile -> size optimized: 170MB


    # The builder image, used to build the virtual environment
    FROM python:3.11-bullseye as builder
    
    # Install package manager
    RUN pip install poetry==1.7.1
    
    # Define environment
    ENV POETRY_NO_INTERACTION=1 
        POETRY_VIRTUALENVS_IN_PROJECT=1 
        POETRY_VIRTUALENVS_CREATE=1 
        POETRY_CACHE_DIR=/tmp/poetry_cache
    
    # Set work directory
    WORKDIR /app
    
    # Copy project dependencies
    COPY pyproject.toml poetry.lock ./
    # Install production dependencies only and remove poetry cache directory
    RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR
    
    # The runtime image, used to run the service
    FROM python:3.11-slim-bullseye as runtime
    
    # Set virtual environment path and add it to the system Path
    ENV VIRTUAL_ENV=/app/.venv 
        PATH="/app/.venv/bin:$PATH"
    
    # Copy project dependencies from builder stage
    COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
    
    # Copy project code
    COPY app/ /app/
    
    # Run service
    CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]

The layout generated in the debian container is the same, so everything is okay, when I run the container it deploys a fastapi server that works perfect!

I want to create a development environment that watch my code and reloads the server in every change.

For that I created the following compose.yaml:


    services:
      api:
        image: pws
        build:
          context: .
          dockerfile: Dockerfile
        restart: on-failure
        ports:
          - "80:80"
        volumes:
          # - ./app/:/app   # I have tried many combinations of this line
          - ./app/:/app/
        command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--reload"]

The issue is that running "docker compose up" goes well when "volumes" are not specified, but at the moment I try to include it, breaks:

Error:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "uvicorn": executable file not found in $PATH: unknown

2

Answers


  1. Chosen as BEST ANSWER

    I have found a workarround using docker compose watch, but still curious about what is happening with bind mounts using "volumes"

    services:
      api:
        image: pws
        build:
          context: .
          dockerfile: Dockerfile
        container_name: pws
        environment:
          - WATCHFILES_FORCE_POLLING=true
        restart: on-failure
        ports:
          - "80:80"
        develop:
          watch:
            - action: sync
              path: ./app/
              target: /app/
              ignore:
                - .venv/
        command: ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--reload"]
    

  2. On the host you have .venv in your root directory, but in your Dockerfile it’s app/.venv, so when you mount app from host there is no .venv in the container

    To resolve it in your Dockerfile you should move .venv to /.venv(or anywhere outside of /app) from /app/.venv

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search