From 7f8990fd30bf075076740a6221ef43a73a88b08e Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Thu, 23 Apr 2026 11:16:16 +0700 Subject: [PATCH] fix: allow compose to start without MODEL_URL; defer missing-model error to runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hard ${MODEL_URL:?...} gate made 'docker compose up' fail at config parsing if no .env existed — container never started, no logs beyond compose's own error. Now: - MODEL_URL defaults to empty in compose. The Python loader checks at startup and raises a clear FileNotFoundError naming the missing path and the two ways to fix it (set MODEL_URL, or mount a local file). - Document an alternative local-mount flow in README, mirroring word2sim's ./vectors.bin pattern. - Add container_name: phow2sim for easier docker ps / docker logs. --- README.md | 14 ++++++++++++++ app/vectors.py | 5 +++-- docker-compose.yml | 14 ++++++++------ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a389aea..96fe449 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,20 @@ tries exact → lowercase → space-to-underscore variants. restarts load in ~10s. Health check start period is 10 min to cover the first-boot cost. +### Alternative: mount a local file instead + +If you've already downloaded the `.txt` locally and don't want to +re-upload anywhere, skip `MODEL_URL` entirely and mount the file. In +`docker-compose.yml`, uncomment the bind mount: + +```yaml +volumes: + - phow2v-cache:/data/phow2v + - ./models/word2vec_vi_words_300dims.txt:/data/phow2v/word2vec_vi_words_300dims.txt:ro +``` + +Then `docker compose up` boots straight into parse — no download step. + ## Switching variant Host the desired zip and update `.env`: diff --git a/app/vectors.py b/app/vectors.py index c60545c..782de10 100644 --- a/app/vectors.py +++ b/app/vectors.py @@ -75,10 +75,11 @@ def load_model() -> KeyedVectors: return _MODEL if not txt_path.exists(): - url = os.environ.get("MODEL_URL") + url = os.environ.get("MODEL_URL", "").strip() if not url: raise FileNotFoundError( - f"MODEL_PATH {txt_path} missing and no MODEL_URL set for auto-download" + f"no vectors at MODEL_PATH={txt_path}; set MODEL_URL in .env " + f"(or mount a local .txt into {txt_path.parent}) and retry" ) _download_and_extract(url, txt_path) diff --git a/docker-compose.yml b/docker-compose.yml index 784d3da..64d913e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,20 @@ services: phow2sim: build: . + container_name: phow2sim ports: - "8001:8000" environment: - # MODEL_URL: a URL that serves the PhoW2V zip with a plain GET. - # Any auth (share token, signed URL, etc.) must be encoded in the - # URL itself — the service does not send Authorization headers. - # Example (Nextcloud public share): - # https://cloud.example.com/s//download - MODEL_URL: ${MODEL_URL:?set MODEL_URL in .env to your PhoW2V zip URL} + # URL serving the PhoW2V zip with a plain GET. Any auth goes in + # the URL itself (share token, signed URL, etc.) — the service + # sends no Authorization header. Leave empty only if you've + # pre-populated the volume (see the volume mount below). + MODEL_URL: ${MODEL_URL:-} MODEL_PATH: ${MODEL_PATH:-/data/phow2v/word2vec_vi_words_300dims.txt} volumes: - phow2v-cache:/data/phow2v + # Or mount a locally-downloaded .txt and skip MODEL_URL entirely: + # - ./models/word2vec_vi_words_300dims.txt:/data/phow2v/word2vec_vi_words_300dims.txt:ro restart: unless-stopped volumes: