From 6fcbfd979654babc36f2578d20da474823a3f9d8 Mon Sep 17 00:00:00 2001 From: devRaGonSa Date: Mon, 23 Mar 2026 16:39:18 +0100 Subject: [PATCH] Add Dockerized local project workflow --- README.md | 98 ++++++++++++++++--- .../done/TASK-060-backend-dockerization.md | 60 ++++++++++++ .../done/TASK-061-frontend-dockerization.md | 55 +++++++++++ ...62-docker-compose-project-orchestration.md | 52 ++++++++++ .../TASK-063-docker-runbook-and-env-docs.md | 55 +++++++++++ backend/.dockerignore | 11 +++ backend/.env.example | 16 +++ backend/Dockerfile | 20 ++++ backend/README.md | 91 +++++++++++++++++ docker-compose.yml | 22 +++++ frontend/.dockerignore | 7 ++ frontend/Dockerfile | 12 +++ 12 files changed, 483 insertions(+), 16 deletions(-) create mode 100644 ai/tasks/done/TASK-060-backend-dockerization.md create mode 100644 ai/tasks/done/TASK-061-frontend-dockerization.md create mode 100644 ai/tasks/done/TASK-062-docker-compose-project-orchestration.md create mode 100644 ai/tasks/done/TASK-063-docker-runbook-and-env-docs.md create mode 100644 backend/.dockerignore create mode 100644 backend/.env.example create mode 100644 backend/Dockerfile create mode 100644 docker-compose.yml create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile diff --git a/README.md b/README.md index 5e15f69..558ed46 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ HLL Vietnam es la base inicial del repositorio para una futura web de comunidad enfocada en la comunidad hispana de Discord del juego HLL Vietnam. -En esta primera fase, el proyecto se centra en una landing sencilla, limpia y profesional que sirva como punto de entrada para la comunidad. La implementación actual utiliza HTML, CSS y JavaScript sin frameworks pesados para mantener una base fácil de mantener y ampliar. +En esta primera fase, el proyecto se centra en una landing sencilla, limpia y profesional que sirva como punto de entrada para la comunidad. La implementacion actual utiliza HTML, CSS y JavaScript sin frameworks pesados para mantener una base facil de mantener y ampliar. ## Estado actual - Landing inicial de comunidad. - Estructura de repositorio preparada para crecer. -- Carpeta de backend reservada para una futura implementación en Python. -- Carpeta `ai/` ya integrada como capa operativa para orquestación por tasks y trabajo con Codex. +- Carpeta de backend reservada para una futura implementacion en Python. +- Carpeta `ai/` ya integrada como capa operativa para orquestacion por tasks y trabajo con Codex. ## Estructura del repositorio @@ -24,16 +24,19 @@ En esta primera fase, el proyecto se centra en una landing sencilla, limpia y pr | `-- decisions.md |-- frontend/ | |-- index.html +| |-- historico.html +| |-- Dockerfile +| |-- .dockerignore | `-- assets/ | |-- css/ -| | `-- styles.css | |-- js/ -| | `-- main.js | `-- img/ -| `-- .gitkeep |-- backend/ | |-- README.md | |-- requirements.txt +| |-- Dockerfile +| |-- .dockerignore +| |-- .env.example | `-- app/ | `-- __init__.py |-- ai/ @@ -48,27 +51,90 @@ En esta primera fase, el proyecto se centra en una landing sencilla, limpia y pr | | `-- README.md | `-- tasks/ | |-- pending/ -| | `-- .gitkeep | |-- in-progress/ -| | `-- .gitkeep | `-- done/ -| `-- .gitkeep +|-- docker-compose.yml `-- scripts/ - |-- codex-runner.ps1 - `-- run-integration-tests.ps1 ``` ## Backend futuro -El backend principal está previsto en Python, pero en esta fase no se incluye lógica funcional ni dependencias de servidor. La estructura queda preparada para incorporar esa capa más adelante sin reorganizar el repositorio. +El backend principal esta previsto en Python, pero en esta fase no se introduce infraestructura final de produccion. La base actual prioriza un bootstrap pequeno, una persistencia local clara y una evolucion controlada. -## Cómo abrir el frontend localmente +## Como abrir el frontend localmente 1. Ve a la carpeta `frontend/`. 2. Abre `index.html` directamente en el navegador. -No hace falta servidor para esta primera versión. +No hace falta servidor para esta primera version. -## Evolución prevista +## Ejecucion con Docker -La capa inspirada en `ai-dev-platform-template` ya está integrada y adaptada al contexto real de HLL Vietnam. Las siguientes iteraciones deben centrarse en usarla para planificar y ejecutar tasks reales del producto sin ampliar alcance fuera de ese flujo. +El repositorio ya incluye: + +- `backend/Dockerfile` +- `frontend/Dockerfile` +- `docker-compose.yml` +- `backend/.env.example` + +Primer arranque: + +```powershell +docker compose up --build +``` + +Accesos locales esperados: + +- frontend: `http://localhost:8080` +- backend: `http://localhost:8000` +- health del backend: `http://localhost:8000/health` + +Persistencia: + +- el SQLite historico se conserva en `backend/data/hll_vietnam_dev.sqlite3` +- los snapshots JSON se conservan en `backend/data/snapshots/` +- `docker-compose.yml` monta `./backend/data` dentro del contenedor en `/app/data` + +Reinicio normal: + +```powershell +docker compose up -d +``` + +Parada: + +```powershell +docker compose down +``` + +Recreacion de imagenes tras cambios: + +```powershell +docker compose up --build +``` + +## Operaciones historicas con Docker + +Refresh historico puntual dentro del contenedor backend: + +```powershell +docker compose exec backend python -m app.historical_ingestion refresh +``` + +Bootstrap o backfill historico: + +```powershell +docker compose exec backend python -m app.historical_ingestion bootstrap +``` + +Regeneracion puntual de snapshots mediante refresh controlado: + +```powershell +docker compose exec backend python -m app.historical_runner --max-runs 1 +``` + +Si se prefiere operar fuera de Docker, el backend sigue pudiendo arrancar localmente con `python -m app.main` desde `backend/`. + +## Evolucion prevista + +La capa inspirada en `ai-dev-platform-template` ya esta integrada y adaptada al contexto real de HLL Vietnam. Las siguientes iteraciones deben centrarse en usarla para planificar y ejecutar tasks reales del producto sin ampliar alcance fuera de ese flujo. diff --git a/ai/tasks/done/TASK-060-backend-dockerization.md b/ai/tasks/done/TASK-060-backend-dockerization.md new file mode 100644 index 0000000..488378f --- /dev/null +++ b/ai/tasks/done/TASK-060-backend-dockerization.md @@ -0,0 +1,60 @@ +# TASK-060-backend-dockerization + +## Goal +Preparar el backend Python del proyecto para ejecutarse correctamente dentro de un contenedor Docker, con una imagen reproducible, variables de entorno claras y persistencia adecuada de datos históricos y snapshots. + +## Context +El backend ya funciona localmente, pero aún no está preparado formalmente para una ejecución containerizada estándar. Antes de pensar en despliegue real, hace falta empaquetarlo de forma consistente y dejar claro cómo se inyectan configuración, rutas de datos y puertos. + +## Steps +1. Revisar la estructura actual del backend y su forma de arranque. +2. Diseñar un Dockerfile específico para el backend. +3. Asegurar que el backend pueda arrancar en contenedor con: + - host correcto + - puerto configurable + - variables de entorno ya soportadas por el proyecto +4. Revisar qué rutas del backend deben persistirse fuera del contenedor, especialmente: + - SQLite histórica + - snapshots JSON + - cualquier artefacto operativo relevante +5. Preparar una estrategia razonable de `.dockerignore` para backend. +6. Mantener la imagen lo más simple y reproducible posible. +7. No resolver todavía reverse proxy final ni TLS en esta task. +8. Al completar la implementación: + - dejar el repositorio consistente + - hacer commit + - hacer push al remoto si el entorno lo permite + +## Files to Read First +- AGENTS.md +- backend/README.md +- backend/app/main.py +- backend/app/config.py +- backend/app/historical_ingestion.py +- backend/app/historical_runner.py +- backend/app/historical_snapshots.py +- backend/requirements.txt +- .gitignore + +## Expected Files to Modify +- backend/Dockerfile +- backend/.dockerignore +- backend/README.md +- opcionalmente archivos de entorno de ejemplo si mejoran claridad, por ejemplo: + - backend/.env.example + +## Constraints +- No romper el arranque local existente. +- No eliminar la persistencia local del histórico. +- No hacer cambios destructivos. +- Mantener el trabajo centrado en containerizar el backend. + +## Validation +- Existe un Dockerfile de backend funcional. +- La persistencia necesaria del backend queda identificada y documentada. +- El backend puede ejecutarse con configuración inyectable por entorno. +- Los cambios quedan committeados y se hace push si el entorno lo permite. + +## Change Budget +- Preferir menos de 5 archivos modificados o creados. +- Preferir menos de 220 líneas cambiadas. diff --git a/ai/tasks/done/TASK-061-frontend-dockerization.md b/ai/tasks/done/TASK-061-frontend-dockerization.md new file mode 100644 index 0000000..3781832 --- /dev/null +++ b/ai/tasks/done/TASK-061-frontend-dockerization.md @@ -0,0 +1,55 @@ +# TASK-061-frontend-dockerization + +## Goal +Preparar el frontend estático del proyecto para ejecutarse dentro de un contenedor Docker de forma simple y estable, con una estrategia clara para servir `historico.html`, la landing y los assets. + +## Context +El frontend actual es estático y ya funciona localmente, pero aún no tiene una imagen Docker formal para ejecución consistente. Hace falta dejarlo empaquetado de forma simple, sin introducir complejidad innecesaria. + +## Steps +1. Revisar la estructura actual del frontend. +2. Diseñar un Dockerfile adecuado para servir el frontend estático. +3. Elegir una estrategia simple y mantenible para servir: + - `index.html` + - `historico.html` + - assets CSS/JS/img +4. Asegurar que el frontend pueda configurarse para hablar con el backend containerizado si hay alguna URL/base path que deba quedar clara. +5. Preparar una estrategia razonable de `.dockerignore` si procede. +6. No introducir frameworks ni bundlers nuevos. +7. No resolver todavía reverse proxy final ni TLS en esta task. +8. Al completar la implementación: + - dejar el repositorio consistente + - hacer commit + - hacer push al remoto si el entorno lo permite + +## Files to Read First +- AGENTS.md +- frontend/index.html +- frontend/historico.html +- frontend/assets/js/main.js +- frontend/assets/js/historico.js +- frontend/assets/css/styles.css +- frontend/assets/css/historico.css +- .gitignore + +## Expected Files to Modify +- frontend/Dockerfile +- frontend/.dockerignore +- opcionalmente una mínima documentación asociada si ayuda a explicar el arranque +- opcionalmente un archivo de configuración simple si mejora claridad del servido estático + +## Constraints +- No romper el frontend local actual. +- No introducir frameworks nuevos. +- No hacer cambios destructivos. +- Mantener el trabajo centrado en containerizar el frontend estático. + +## Validation +- Existe un Dockerfile de frontend funcional. +- El frontend puede servirse correctamente desde contenedor. +- La landing y la página histórica quedan accesibles. +- Los cambios quedan committeados y se hace push si el entorno lo permite. + +## Change Budget +- Preferir menos de 4 archivos modificados o creados. +- Preferir menos de 180 líneas cambiadas. diff --git a/ai/tasks/done/TASK-062-docker-compose-project-orchestration.md b/ai/tasks/done/TASK-062-docker-compose-project-orchestration.md new file mode 100644 index 0000000..4214150 --- /dev/null +++ b/ai/tasks/done/TASK-062-docker-compose-project-orchestration.md @@ -0,0 +1,52 @@ +# TASK-062-docker-compose-project-orchestration + +## Goal +Añadir una orquestación básica por Docker Compose para levantar conjuntamente frontend y backend del proyecto con persistencia adecuada del histórico. + +## Context +Una vez frontend y backend estén dockerizados, hace falta una forma simple de arrancarlos juntos para desarrollo y predespliegue. Esta task debe dejar una base clara y operativa sin meterse todavía en infraestructura final de producción. + +## Steps +1. Revisar los Dockerfile de frontend y backend. +2. Diseñar un `docker-compose.yml` o equivalente moderno para levantar ambos servicios. +3. Asegurar que el backend exponga correctamente su puerto al frontend. +4. Configurar persistencia razonable para: + - SQLite histórica + - snapshots JSON +5. Preparar nombres de servicio y red interna claros. +6. Asegurar que el proyecto pueda arrancarse con una instrucción sencilla. +7. No introducir todavía reverse proxy público, TLS ni balanceo. +8. Al completar la implementación: + - dejar el repositorio consistente + - hacer commit + - hacer push al remoto si el entorno lo permite + +## Files to Read First +- AGENTS.md +- backend/Dockerfile +- frontend/Dockerfile +- backend/README.md +- frontend files relevantes +- .gitignore + +## Expected Files to Modify +- docker-compose.yml +- backend/README.md +- opcionalmente README raíz si conviene documentar el arranque conjunto +- opcionalmente archivos `.env.example` si mejoran claridad + +## Constraints +- No romper el uso local fuera de Docker. +- No meter todavía infraestructura final de producción. +- No hacer cambios destructivos. +- Mantener el trabajo centrado en levantar el proyecto completo con Docker Compose. + +## Validation +- Existe una orquestación Docker Compose clara para frontend y backend. +- Los datos persistentes del backend no se pierden al recrear contenedores. +- El proyecto puede levantarse con un flujo simple y documentado. +- Los cambios quedan committeados y se hace push si el entorno lo permite. + +## Change Budget +- Preferir menos de 5 archivos modificados o creados. +- Preferir menos de 220 líneas cambiadas. diff --git a/ai/tasks/done/TASK-063-docker-runbook-and-env-docs.md b/ai/tasks/done/TASK-063-docker-runbook-and-env-docs.md new file mode 100644 index 0000000..eee8a2e --- /dev/null +++ b/ai/tasks/done/TASK-063-docker-runbook-and-env-docs.md @@ -0,0 +1,55 @@ +# TASK-063-docker-runbook-and-env-docs + +## Goal +Documentar de forma clara cómo ejecutar el proyecto con Docker, qué variables de entorno utiliza y qué persistencia necesita, dejando una guía práctica para desarrollo y predespliegue. + +## Context +Una containerización útil no queda cerrada solo con Dockerfiles y Compose; hace falta documentación clara para levantar el proyecto, entender los volúmenes, configurar entorno y evitar errores de operación. + +## Steps +1. Revisar el estado final de la containerización del frontend y backend. +2. Documentar cómo construir y arrancar el proyecto con Docker. +3. Documentar variables de entorno relevantes del backend. +4. Documentar qué carpetas o volúmenes deben persistirse. +5. Incluir una guía breve para: + - primer arranque + - reinicio + - regeneración de snapshots + - backfill histórico dentro o fuera del contenedor si aplica +6. No convertir esta task en una guía de infraestructura final. +7. Mantener la documentación práctica y enfocada al estado real del proyecto. +8. Al completar la implementación: + - dejar el repositorio consistente + - hacer commit + - hacer push al remoto si el entorno lo permite + +## Files to Read First +- AGENTS.md +- README.md +- backend/README.md +- docker-compose.yml +- backend/app/config.py +- backend/app/historical_ingestion.py +- backend/app/historical_runner.py + +## Expected Files to Modify +- README.md +- backend/README.md +- opcionalmente docs/docker-deployment.md +- opcionalmente archivos de ejemplo de entorno si ayudan a claridad + +## Constraints +- No meter documentación ficticia. +- No describir infraestructura que aún no exista. +- No hacer cambios destructivos. +- Mantener el trabajo centrado en un runbook realista para Docker. + +## Validation +- La documentación explica cómo levantar el proyecto con Docker. +- Las variables y volúmenes relevantes quedan claras. +- Existe una guía útil para el flujo operativo básico. +- Los cambios quedan committeados y se hace push si el entorno lo permite. + +## Change Budget +- Preferir menos de 5 archivos modificados o creados. +- Preferir menos de 220 líneas cambiadas. diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..50e1456 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,11 @@ +.git +.gitignore +.venv/ +__pycache__/ +*.pyc +*.pyo +*.pyd +data/*.sqlite3 +data/snapshots/** +!data/.gitkeep +!data/snapshots/.gitkeep diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 0000000..19d01a2 --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,16 @@ +HLL_BACKEND_HOST=0.0.0.0 +HLL_BACKEND_PORT=8000 +HLL_BACKEND_STORAGE_PATH=/app/data/hll_vietnam_dev.sqlite3 +HLL_BACKEND_ALLOWED_ORIGINS=http://127.0.0.1:8080,http://localhost:8080 +HLL_BACKEND_REFRESH_INTERVAL_SECONDS=120 +HLL_HISTORICAL_CRCON_PAGE_SIZE=50 +HLL_HISTORICAL_CRCON_TIMEOUT_SECONDS=15 +HLL_HISTORICAL_CRCON_DETAIL_WORKERS=8 +HLL_HISTORICAL_CRCON_REQUEST_RETRIES=3 +HLL_HISTORICAL_CRCON_RETRY_DELAY_SECONDS=0.5 +HLL_HISTORICAL_SNAPSHOT_REFRESH_INTERVAL_SECONDS=900 +HLL_HISTORICAL_FULL_SNAPSHOT_EVERY_RUNS=4 +HLL_HISTORICAL_REFRESH_MAX_RETRIES=2 +HLL_HISTORICAL_REFRESH_RETRY_DELAY_SECONDS=30 +HLL_HISTORICAL_WEEKLY_FALLBACK_MIN_MATCHES=3 +HLL_HISTORICAL_WEEKLY_FALLBACK_MAX_WEEKDAY=2 diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..f1ff44b --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + HLL_BACKEND_HOST=0.0.0.0 \ + HLL_BACKEND_PORT=8000 \ + HLL_BACKEND_STORAGE_PATH=/app/data/hll_vietnam_dev.sqlite3 + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir --requirement requirements.txt + +COPY app ./app + +RUN mkdir -p /app/data/snapshots + +EXPOSE 8000 + +CMD ["python", "-m", "app.main"] diff --git a/backend/README.md b/backend/README.md index 0da6411..e9adeb0 100644 --- a/backend/README.md +++ b/backend/README.md @@ -77,6 +77,60 @@ Variables opcionales: - `HLL_HISTORICAL_WEEKLY_FALLBACK_MIN_MATCHES` - `HLL_HISTORICAL_WEEKLY_FALLBACK_MAX_WEEKDAY` +Variables especialmente relevantes para Docker y Compose: + +- `HLL_BACKEND_HOST` +- `HLL_BACKEND_PORT` +- `HLL_BACKEND_STORAGE_PATH` +- `HLL_BACKEND_ALLOWED_ORIGINS` +- `HLL_HISTORICAL_CRCON_PAGE_SIZE` +- `HLL_HISTORICAL_CRCON_TIMEOUT_SECONDS` +- `HLL_HISTORICAL_CRCON_DETAIL_WORKERS` +- `HLL_HISTORICAL_CRCON_REQUEST_RETRIES` +- `HLL_HISTORICAL_CRCON_RETRY_DELAY_SECONDS` +- `HLL_HISTORICAL_SNAPSHOT_REFRESH_INTERVAL_SECONDS` +- `HLL_HISTORICAL_FULL_SNAPSHOT_EVERY_RUNS` +- `HLL_HISTORICAL_REFRESH_MAX_RETRIES` +- `HLL_HISTORICAL_REFRESH_RETRY_DELAY_SECONDS` + +Para ejecucion containerizada, el repositorio incluye tambien: + +- `backend/Dockerfile` +- `backend/.dockerignore` +- `backend/.env.example` + +El contenedor usa el mismo entrypoint real del proyecto: + +```powershell +python -m app.main +``` + +Dentro del contenedor arranca por defecto con: + +- `HLL_BACKEND_HOST=0.0.0.0` +- `HLL_BACKEND_PORT=8000` +- `HLL_BACKEND_STORAGE_PATH=/app/data/hll_vietnam_dev.sqlite3` + +Build local: + +```powershell +docker build -t hll-vietnam-backend ./backend +``` + +Ejecucion local con persistencia bind-mounted: + +```powershell +docker run --rm ` + -p 8000:8000 ` + --env-file backend/.env.example ` + -v ${PWD}\backend\data:/app/data ` + hll-vietnam-backend +``` + +Si se prefiere no usar `--env-file`, el contenedor puede arrancar solo con sus +defaults para host, puerto y path de SQLite. El bind mount de `/app/data` sigue +siendo la forma recomendada de no perder persistencia al recrear el contenedor. + El `frontend/index.html` viene preparado para volver a consultar el bloque de servidores cada `120000` ms (`120s`) sin recargar la pagina completa. La landing lee ese valor desde `data-server-refresh-ms`, por lo que puede ajustarse en el @@ -210,6 +264,12 @@ Por defecto el archivo se crea en: backend/data/hll_vietnam_dev.sqlite3 ``` +En Docker, ese mismo rol de persistencia debe montarse fuera del contenedor en: + +```text +/app/data/hll_vietnam_dev.sqlite3 +``` + Variable opcional: - `HLL_BACKEND_STORAGE_PATH` @@ -237,6 +297,12 @@ Por defecto se escriben bajo: backend/data/snapshots// ``` +En Docker, estos snapshots deben persistirse bajo: + +```text +/app/data/snapshots// +``` + Ejemplos: - `backend/data/snapshots/comunidad-hispana-01/server-summary.json` @@ -260,6 +326,16 @@ La persistencia usa una identidad de archivo estable por combinacion de servidor, tipo y metrica para que cada refresh reemplace el artefacto anterior sin mezclarlo con el historico bruto. +Resumen de persistencia recomendada para contenedor: + +- montar `/app/data` +- conservar el SQLite historico en `/app/data/hll_vietnam_dev.sqlite3` +- conservar los snapshots JSON en `/app/data/snapshots/` + +Con `docker compose`, esa persistencia ya queda montada desde: + +- `./backend/data -> /app/data` + ## Bootstrap del colector El backend incluye un bootstrap minimo para el futuro flujo de snapshots: @@ -594,6 +670,14 @@ python -m app.historical_ingestion refresh python -m app.historical_runner --interval 1800 ``` +Los mismos flujos desde Docker Compose: + +```powershell +docker compose exec backend python -m app.historical_ingestion bootstrap +docker compose exec backend python -m app.historical_ingestion refresh +docker compose exec backend python -m app.historical_runner --interval 1800 +``` + Flags utiles: - `--server comunidad-hispana-01` para limitar a un servidor @@ -676,6 +760,13 @@ Flags utiles del runner: - `--retry-delay 10` para bajar la espera entre fallos - `--max-runs 1` para una validacion puntual sin bucle indefinido +Para regenerar snapshots de forma puntual dentro del contenedor sin dejar un +bucle permanente, la validacion operativa minima es: + +```powershell +docker compose exec backend python -m app.historical_runner --max-runs 1 +``` + Variables utiles del runner: - `HLL_HISTORICAL_SNAPSHOT_REFRESH_INTERVAL_SECONDS` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0339cd9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,22 @@ +services: + backend: + build: + context: ./backend + container_name: hll-vietnam-backend + env_file: + - ./backend/.env.example + ports: + - "8000:8000" + volumes: + - ./backend/data:/app/data + restart: unless-stopped + + frontend: + build: + context: ./frontend + container_name: hll-vietnam-frontend + depends_on: + - backend + ports: + - "8080:8080" + restart: unless-stopped diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..6d13b20 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,7 @@ +.git +.gitignore +.venv/ +__pycache__/ +*.pyc +*.pyo +*.pyd diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..849b258 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +WORKDIR /srv/frontend + +COPY . /srv/frontend + +EXPOSE 8080 + +CMD ["python", "-m", "http.server", "8080", "--bind", "0.0.0.0", "--directory", "/srv/frontend"]