faizath commited on
Commit
48f2a01
·
verified ·
1 Parent(s): 2164b09

build: add the container image and developer targets

Browse files

The artifact is baked into the image rather than mounted so that the
image tag is a complete description of what the service predicts and a
rollback is deploying the previous tag.

The build runs the golden row check so that an image unable to reproduce
its own recorded prediction never reaches a registry.

Files changed (2) hide show
  1. Dockerfile +48 -0
  2. Makefile +41 -0
Dockerfile ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # The model is baked into the image rather than mounted, so the image tag is a complete
2
+ # description of what the service will predict and rolling back means deploying the
3
+ # previous tag. The build fails if the artifact does not reproduce its own golden row.
4
+
5
+ FROM python:3.13-slim AS builder
6
+
7
+ ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
8
+ PIP_NO_CACHE_DIR=1
9
+
10
+ WORKDIR /app
11
+ COPY requirements.txt .
12
+ RUN python -m venv /opt/venv \
13
+ && /opt/venv/bin/pip install --upgrade pip \
14
+ && /opt/venv/bin/pip install -r requirements.txt
15
+
16
+
17
+ FROM python:3.13-slim AS runtime
18
+
19
+ ENV PATH="/opt/venv/bin:$PATH" \
20
+ PYTHONPATH=/app \
21
+ PYTHONDONTWRITEBYTECODE=1 \
22
+ PYTHONUNBUFFERED=1 \
23
+ OMP_NUM_THREADS=2 \
24
+ OPENBLAS_NUM_THREADS=2 \
25
+ MKL_NUM_THREADS=2
26
+
27
+ COPY --from=builder /opt/venv /opt/venv
28
+
29
+ WORKDIR /app
30
+ COPY phiusiil/ ./phiusiil/
31
+ COPY server/ ./server/
32
+ COPY model/ ./model/
33
+ COPY pyproject.toml README.md ./
34
+
35
+ RUN useradd --uid 10001 --no-create-home --shell /usr/sbin/nologin serve \
36
+ && chown -R serve:serve /app
37
+ USER serve
38
+
39
+ # Boot-time honesty check, at build time: an image whose artifact produces different
40
+ # numbers from the training run must not be publishable.
41
+ RUN python -m server.selftest --golden
42
+
43
+ EXPOSE 8000
44
+
45
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
46
+ CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/healthz', timeout=4).status==200 else 1)"
47
+
48
+ CMD ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "8000"]
Makefile ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ VENV := .venv
2
+ PY := $(VENV)/bin/python
3
+ PIP := $(VENV)/bin/pip
4
+ PORT ?= 8000
5
+ IMAGE ?= fetiai-v1-phiusiil-binclf-knn-scratch-500k:local
6
+
7
+ .DEFAULT_GOAL := help
8
+
9
+ help: ## Show this help
10
+ @grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-16s\033[0m %s\n", $$1, $$2}'
11
+
12
+ $(VENV): ## Create the virtualenv
13
+ python3 -m venv $(VENV)
14
+
15
+ install: $(VENV) ## Install pinned dependencies
16
+ $(PIP) install --upgrade pip
17
+ $(PIP) install -r requirements.txt -r requirements-dev.txt
18
+
19
+ selftest: ## Verify the artifact reproduces its recorded golden row
20
+ $(PY) -m server.selftest --golden
21
+
22
+ namecheck: ## Fail if the parent project's internal library name appears anywhere
23
+ $(PY) -m pytest tests/test_naming.py -q
24
+
25
+ test: ## Run the full offline suite
26
+ $(PY) -m pytest -q
27
+
28
+ serve: ## Run the API on http://127.0.0.1:$(PORT)
29
+ $(VENV)/bin/uvicorn server.app:app --host 127.0.0.1 --port $(PORT)
30
+
31
+ docker-build: ## Build the container image
32
+ docker build -t $(IMAGE) .
33
+
34
+ docker-test: ## Run the golden-row self-test inside the built image
35
+ docker run --rm $(IMAGE) python -m server.selftest --golden
36
+
37
+ clean: ## Remove caches
38
+ rm -rf .pytest_cache .ruff_cache .mypy_cache
39
+ find . -name __pycache__ -type d -prune -exec rm -rf {} +
40
+
41
+ .PHONY: help install selftest namecheck test serve docker-build docker-test clean