alexp97 commited on
Commit
c0f31a8
·
1 Parent(s): 15d6ad0

chore(infra): contenedores, despliegue y scripts de arranque local

Browse files

Añade Dockerfiles de backend y UI, docker-compose, render.yaml para el despliegue gratuito y los scripts PowerShell de arranque local sin Docker (run_backend, run_ui, dev) que usan 'python -m uvicorn' para evitar los shims .exe bloqueados por OneDrive. Incluye placeholders de models/ y sample_data/.

backend/Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Imagen del backend FastAPI del MVP (CPU).
2
+ FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
3
+
4
+ WORKDIR /app
5
+
6
+ # Instalar dependencias de producción desde el manifiesto
7
+ COPY pyproject.toml ./
8
+ RUN uv sync --no-dev
9
+
10
+ COPY backend/ ./backend/
11
+
12
+ # Para ACTIVAR el conteo: descargar el modelo desde Hugging Face Hub en el build.
13
+ # (Mientras COUNTING_ENABLED=false el backend funciona en standby y no requiere modelo.)
14
+ # ARG MODEL_VERSION=2.0.0
15
+ # RUN uv run python -c "from huggingface_hub import hf_hub_download; \
16
+ # hf_hub_download(repo_id='<org>/agrovision-plantcount', \
17
+ # filename='agrovision-plantcount-v${MODEL_VERSION}.onnx', local_dir='/app/models')"
18
+
19
+ ENV COUNTING_ENABLED=false
20
+ ENV MODEL_PATH=/app/models/agrovision-plantcount-v2.0.0.onnx
21
+ ENV MODEL_VERSION=2.0.0
22
+ EXPOSE 8000
23
+ CMD ["uv", "run", "uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compose.yml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stack local del MVP: backend FastAPI (api) + UI Shiny (ui).
2
+ # El conteo arranca en standby (COUNTING_ENABLED=false); la app levanta igual.
3
+ services:
4
+ api:
5
+ build:
6
+ context: .
7
+ dockerfile: backend/Dockerfile
8
+ ports:
9
+ - "8000:8000"
10
+ environment:
11
+ - COUNTING_ENABLED=false
12
+ - ALLOWED_ORIGINS=http://localhost:8001
13
+ volumes:
14
+ - ./models:/app/models:ro
15
+ - ./sample_data:/app/sample_data:ro
16
+ healthcheck:
17
+ test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/api/status')\""]
18
+ interval: 10s
19
+ timeout: 5s
20
+ retries: 5
21
+
22
+ ui:
23
+ build:
24
+ context: .
25
+ dockerfile: frontend/Dockerfile
26
+ ports:
27
+ - "8001:8001"
28
+ environment:
29
+ - API_BASE_URL=http://api:8000
30
+ depends_on:
31
+ api:
32
+ condition: service_healthy
frontend/Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Imagen de la UI Shiny for Python del MVP.
2
+ FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
3
+
4
+ WORKDIR /app
5
+
6
+ COPY pyproject.toml ./
7
+ RUN uv sync --no-dev
8
+
9
+ COPY frontend/ ./frontend/
10
+
11
+ ENV API_BASE_URL=http://localhost:8000
12
+ EXPOSE 8001
13
+ CMD ["uv", "run", "shiny", "run", "frontend/app.py", "--host", "0.0.0.0", "--port", "8001"]
models/.gitkeep ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # Carpeta para el artefacto del modelo (agrovision-plantcount-*.onnx).
2
+ # Los pesos NO se versionan: se descargan de Hugging Face Hub en el build.
render.yaml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Despliegue del backend del MVP en Render (capa gratuita).
2
+ # La UI Shiny se despliega aparte en ShinyApps.io (rsconnect deploy shiny ./frontend).
3
+ services:
4
+ - type: web
5
+ name: agrovision-mvp-api
6
+ runtime: docker
7
+ dockerfilePath: ./backend/Dockerfile
8
+ plan: free
9
+ healthCheckPath: /api/status
10
+ envVars:
11
+ - key: COUNTING_ENABLED
12
+ value: "false" # true cuando el modelo esté publicado
13
+ - key: ALLOWED_ORIGINS
14
+ value: https://<tu-app>.shinyapps.io
15
+ - key: MODEL_VERSION
16
+ value: "2.0.0"
sample_data/README.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # sample_data
2
+
3
+ Ortomosaicos de ejemplo para probar el conteo localmente (cuando el módulo deje el modo *standby*).
4
+
5
+ - Las imágenes (`*.png`, `*.jpg`, `*.tif`) **no se versionan** (ver `.gitignore`).
6
+ - Coloca aquí un ortomosaico de arándano de prueba, p. ej. `lote_demo.png`.
7
+ - El conteo se activa con `COUNTING_ENABLED=true` y el modelo publicado en Hugging Face Hub.
scripts/dev.ps1 ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Arranca backend + UI en ventanas PowerShell separadas (local, sin Docker).
2
+ # Uso: ./scripts/dev.ps1
3
+ Start-Process powershell -ArgumentList "-NoExit", "-File", "`"$PSScriptRoot\run_backend.ps1`""
4
+ Start-Sleep -Seconds 2
5
+ Start-Process powershell -ArgumentList "-NoExit", "-File", "`"$PSScriptRoot\run_ui.ps1`""
6
+
7
+ Write-Host "Backend: http://127.0.0.1:8000/api/status"
8
+ Write-Host "UI Shiny: http://127.0.0.1:8001"
scripts/run_backend.ps1 ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Levanta el backend FastAPI del MVP en local (sin Docker), en http://127.0.0.1:8000
2
+ Set-Location (Split-Path -Parent $PSScriptRoot)
3
+
4
+ # Entorno virtual fuera de OneDrive (evita errores de hardlink/lock en carpetas sincronizadas)
5
+ $env:UV_PROJECT_ENVIRONMENT = "$env:LOCALAPPDATA\agrovision-venv"
6
+ $env:UV_LINK_MODE = "copy"
7
+
8
+ uv sync
9
+ # Se usa "python -m uvicorn" (no el shim uvicorn.exe) para evitar errores de
10
+ # ejecución en carpetas sincronizadas por OneDrive.
11
+ uv run python -m uvicorn backend.main:app --host 127.0.0.1 --port 8000 --reload
scripts/run_ui.ps1 ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Levanta la UI Shiny del MVP en local (sin Docker), en http://127.0.0.1:8001
2
+ Set-Location (Split-Path -Parent $PSScriptRoot)
3
+
4
+ $env:UV_PROJECT_ENVIRONMENT = "$env:LOCALAPPDATA\agrovision-venv"
5
+ $env:UV_LINK_MODE = "copy"
6
+
7
+ # La app Shiny es ASGI: se sirve con uvicorn (python -m) para evitar el shim
8
+ # shiny.exe, que OneDrive bloquea. Equivale a `shiny run frontend/app.py`.
9
+ uv run python -m uvicorn frontend.app:app --host 127.0.0.1 --port 8001 --reload