Close the leaked httpx.AsyncClient in MyWhoosh sync runs, ensure hard failures finish sync_runs as FAILED instead of leaving them stuck at RUNNING, log (non-benign) exceptions surfaced by sync_all_enabled during scheduled ticks, classify GarminImportRejected as a non-retryable per-activity failure, fix a bug where a live Garmin-class action_required state could be silently cleared by a run that did no Garmin work, use the activity's DB primary key instead of the unsanitized remote id for filesystem paths, add regression/coverage tests for the health-state fix and MFA code threading through the real SyncManager, add idempotency coverage to the two-user acceptance test, and note the Dockerfile's single-process assumption. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
15 lines
562 B
Docker
15 lines
562 B
Docker
# Dockerfile
|
|
FROM python:3.12-slim
|
|
WORKDIR /app
|
|
COPY pyproject.toml /app/
|
|
RUN pip install --no-cache-dir .
|
|
COPY app /app/app
|
|
RUN mkdir -p /data && chmod 700 /data
|
|
ENV DATA_DIR=/data
|
|
EXPOSE 8080
|
|
# Single-process assumption: per-user sync locking and the in-process
|
|
# scheduler both live in this one worker's memory. Do not scale this to
|
|
# multiple uvicorn workers or container replicas without adding a
|
|
# cross-process lock -- otherwise duplicate imports become possible.
|
|
CMD ["uvicorn", "app.main:create_app", "--factory", "--host", "0.0.0.0", "--port", "8080"]
|