I have issues with hot reloading of a FAST API app inside a Docker container.
I can see that the volume mapping is doing its thing and the files are updated inside the docker container.
The console log tells me uvicorn is watching files inside the correct folder.
But any change I make is not triggering a reload of the app.
I have the following setup:
My docker-compose.yaml
:
#docker-compose.yml
version: "3"
services:
app:
container_name: api
image: api:latest
depends_on:
- mysqldb
build:
context: .
dockerfile: Dockerfile.dev
args:
DEV: "true"
ports:
- "8080:8080"
env_file:
- .env
environment:
- WATCHFILES_FORCE_POLLING=true
- DEV=1
- MYSQL_HOSTNAME=mysqldb
- MYSQL_PORT=3306
command: uvicorn app.main:app --host 0.0.0.0 --port 8080 --reload --reload-dir /src/app
volumes:
- ./app:/src/app
mysqldb:
container_name: mysqldb
image: mysql:latest
restart: always
ports:
- 3307:3306
environment:
MYSQL_ROOT_PASSWORD: randompassword
MYSQL_DATABASE: my-database
And my Dockerfile
#dockerfile.dev
FROM python:3.10-slim-buster
ENV PYTHONUNBUFFERED 1
COPY requirements.txt /
COPY alembic.ini /
COPY migrations /migrations
RUN pip install --upgrade pip setuptools wheel gunicorn uvloop httptools
RUN pip install -r requirements.txt
RUN pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
RUN pip install sentence-transformers
# Copy the source code to src folder
COPY . /src
ENV PYTHONPATH=/src
EXPOSE 8080
# FOR local dev the startup happens inside the docker-compose with reload options
COPY startup.sh /src/startup.sh
RUN chmod +x /src/startup.sh
CMD ["uvicorn", "app.main:app","--host", "0.0.0.0", "--port", "8080", "--reload"]
I've tried almost all possible configurations of the reload.
After tinkering arround with different set ups we now have a stable reload workspace. The issue with the uvicorn --reload statement had to do with volume mapping and the point when the command got called.
Now instead of running the uvicorn command from the docker compose file I run a command to keep the container alive:
command: /bin/sh -c "while true; do sleep 30; done"
Then I connect manually with the container:
docker exec -it ml_api /bin/bash
And then i can start (or manually restart) the uvicorn (or guvicorn) server. The reload statement now works correctly and if any big changes happen I can restart uvicorn without restarting my docker container.