Fix version display: show actual version instead of 'vunknown'

Root cause: Dockerfile build context is ./app/ but VERSION file is at
repo root, so it's excluded from the Docker image. The context processor
tried parent.parent.parent which resolves to / inside the container.

Fix:
- Context processor now checks APP_VERSION env var first, then tries
  multiple file paths (repo root for local dev, app/ dir for Docker)
- Dockerfile accepts APP_VERSION build arg and sets it as ENV
- compose.yml passes APP_VERSION build arg to all service builds

Note: Deploy script needs `export APP_VERSION=$(cat VERSION)` before
docker-compose build for the build arg to pick up the version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
SysAdmin Agent
2026-03-21 21:11:52 +00:00
parent 59e05856b4
commit 4e9fe816d5
3 changed files with 36 additions and 10 deletions

View File

@@ -1,6 +1,8 @@
FROM python:3.12-slim FROM python:3.12-slim
ARG APP_VERSION=unknown
ENV PYTHONDONTWRITEBYTECODE=1 \ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 PYTHONUNBUFFERED=1 \
APP_VERSION=$APP_VERSION
RUN apt-get update && apt-get install -y --no-install-recommends \ RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential libpq-dev postgresql-client \ build-essential libpq-dev postgresql-client \

View File

@@ -1,3 +1,4 @@
import os
from pathlib import Path from pathlib import Path
_VERSION = None _VERSION = None
@@ -6,9 +7,20 @@ _VERSION = None
def app_version(request): def app_version(request):
global _VERSION global _VERSION
if _VERSION is None: if _VERSION is None:
version_file = Path(__file__).resolve().parent.parent.parent / "VERSION" # 1. Environment variable (set in Docker/deployment)
try: _VERSION = os.environ.get("APP_VERSION", "").strip()
_VERSION = version_file.read_text().strip() if not _VERSION:
except FileNotFoundError: # 2. Try VERSION file at common locations
_VERSION = "unknown" base = Path(__file__).resolve().parent.parent # app/
for candidate in [
base.parent / "VERSION", # repo root (local dev)
base / "VERSION", # app/ dir (Docker)
]:
try:
_VERSION = candidate.read_text().strip()
break
except FileNotFoundError:
continue
else:
_VERSION = "unknown"
return {"APP_VERSION": _VERSION} return {"APP_VERSION": _VERSION}

View File

@@ -25,7 +25,10 @@ services:
image: redis:7-alpine image: redis:7-alpine
web: web:
build: ./app build:
context: ./app
args:
APP_VERSION: ${APP_VERSION:-unknown}
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy
@@ -62,7 +65,10 @@ services:
command: ["gunicorn", "core.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"] command: ["gunicorn", "core.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"]
worker: worker:
build: ./app build:
context: ./app
args:
APP_VERSION: ${APP_VERSION:-unknown}
environment: environment:
- POSTGRES_DB=${POSTGRES_DB} - POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER} - POSTGRES_USER=${POSTGRES_USER}
@@ -88,7 +94,10 @@ services:
command: ["celery", "-A", "core", "worker", "-l", "info"] command: ["celery", "-A", "core", "worker", "-l", "info"]
beat: beat:
build: ./app build:
context: ./app
args:
APP_VERSION: ${APP_VERSION:-unknown}
environment: environment:
- POSTGRES_DB=${POSTGRES_DB} - POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER} - POSTGRES_USER=${POSTGRES_USER}
@@ -114,7 +123,10 @@ services:
command: ["celery", "-A", "core", "beat", "-l", "info"] command: ["celery", "-A", "core", "beat", "-l", "info"]
mcp: mcp:
build: ./app build:
context: ./app
args:
APP_VERSION: ${APP_VERSION:-unknown}
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy