release: default to Web UI in Docker image, add HEALTHCHECK and APP_VERSION; CI smoke test; compose docs and dockerhub compose file

This commit is contained in:
matt 2025-08-28 20:40:19 -07:00
parent 9357a04541
commit be672ac5d2
6 changed files with 96 additions and 4 deletions

View file

@ -32,6 +32,7 @@ jobs:
# Escape newlines for label usage
DESC=$(awk 'BEGIN{ORS="\\n"} {print}' RELEASE_NOTES.md)
echo "desc=$DESC" >> $GITHUB_OUTPUT
echo "version=$VERSION_REF" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@ -39,6 +40,26 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Smoke test image boots Web UI by default (amd64)
shell: bash
run: |
# Build a local test image (amd64) and load into docker
docker buildx build --platform linux/amd64 --load -t mtg-deckbuilder:test --build-arg APP_VERSION=${{ steps.notes.outputs.version }} .
# Run container and wait for it to serve on 8080
docker rm -f mtg-smoke 2>/dev/null || true
docker run -d --name mtg-smoke -p 8080:8080 mtg-deckbuilder:test
echo "Waiting for Web UI..."
for i in {1..30}; do
if curl -fsS http://localhost:8080/ >/dev/null; then echo "Up"; break; fi
sleep 2
done
# Final assert; print logs on failure
if ! curl -fsS http://localhost:8080/ >/dev/null; then
echo "Web UI did not start in time. Container logs:" && docker logs mtg-smoke || true
exit 1
fi
docker rm -f mtg-smoke >/dev/null 2>&1 || true
- name: Docker Hub login
uses: docker/login-action@v3
with:
@ -58,6 +79,7 @@ jobs:
org.opencontainers.image.title=MTG Python Deckbuilder
org.opencontainers.image.version=${{ github.ref_name }}
org.opencontainers.image.description=${{ steps.notes.outputs.desc }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Build and push
uses: docker/build-push-action@v6
@ -68,4 +90,6 @@ jobs:
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
APP_VERSION=${{ steps.notes.outputs.version }}

View file

@ -7,6 +7,8 @@ WORKDIR /app
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ARG APP_VERSION=dev
ENV APP_VERSION=${APP_VERSION}
# Install system dependencies if needed
RUN apt-get update && apt-get install -y \
@ -46,12 +48,25 @@ RUN cd /app/code && ls -la deck_files logs csv_files config owned_cards
# Set the working directory to code for proper imports
WORKDIR /app/code
# Run the application
CMD ["python", "main.py"]
# Add a tiny entrypoint to select Web UI (default) or CLI
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Expose web port for the optional Web UI
EXPOSE 8080
# Container health check: verify Web UI health endpoint (skip if APP_MODE=cli)
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD python -c "import os,sys,json,urllib.request;\
m=os.getenv('APP_MODE','web');\
\
\
\
sys.exit(0) if m=='cli' else None;\
d=urllib.request.urlopen('http://127.0.0.1:8080/healthz', timeout=3).read();\
sys.exit(0 if json.loads(d.decode()).get('status')=='ok' else 1)"
# Note: For the Web UI, start uvicorn in your orchestrator (compose/run) like:
# uvicorn code.web.app:app --host 0.0.0.0 --port 8080
# (now default) container starts Web UI automatically; to run CLI set APP_MODE=cli
# Phase 9: enable web list virtualization with env WEB_VIRTUALIZE=1

BIN
README.md

Binary file not shown.

View file

@ -53,5 +53,4 @@ services:
- ${PWD}/config:/app/config
- ${PWD}/owned_cards:/app/owned_cards
working_dir: /app
command: ["bash", "-lc", "cd /app && uvicorn code.web.app:app --host 0.0.0.0 --port 8080"]
restart: "no"

View file

@ -0,0 +1,34 @@
services:
web:
image: mwisnowski/mtg-python-deckbuilder:latest
# Tip: pin to a specific tag when available, e.g. :2.0.2 (defaults to Web UI)
container_name: mtg-deckbuilder-web
ports:
- "8080:8080" # Host:Container — open http://localhost:8080
environment:
# UI features/flags (all optional)
- SHOW_LOGS=1 # 1=enable /logs page; 0=hide (default off if unset)
- SHOW_DIAGNOSTICS=1 # 1=enable /diagnostics & /diagnostics/perf; 0=hide (default off)
- ENABLE_PWA=0 # 1=serve manifest/service worker (experimental); 0=disabled
- WEB_VIRTUALIZE=1 # 1=enable list virtualization/lazy tweaks in Web UI; 0=off
- WEB_TAG_PARALLEL=1 # 1=parallelize heavy tagging steps in Web UI; 0=serial
- WEB_TAG_WORKERS=4 # Worker count for parallel tagging (only used if WEB_TAG_PARALLEL=1)
# Theming (optional)
- THEME=system # Default theme for first-time visitors: system|light|dark
# 'light' maps to the consolidated Light (Blend) palette
- ENABLE_THEMES=1 # 1=show theme selector in header; 0=hide selector
# Note: THEME still applies as the default even if selector is hidden
# Version label (optional; shown in footer/diagnostics)
# - APP_VERSION=v2.0.2
volumes:
# Persist app data locally; ensure these directories exist next to this compose file
- ${PWD}/deck_files:/app/deck_files
- ${PWD}/logs:/app/logs
- ${PWD}/csv_files:/app/csv_files
- ${PWD}/config:/app/config
- ${PWD}/owned_cards:/app/owned_cards
restart: unless-stopped

20
entrypoint.sh Normal file
View file

@ -0,0 +1,20 @@
#!/usr/bin/env sh
set -e
# Always operate from the code directory for imports to work
cd /app/code || exit 1
# Select mode: default to Web UI
MODE="${APP_MODE:-web}"
if [ "$MODE" = "cli" ]; then
# Run the CLI (interactive menu; use DECK_MODE=headless for non-interactive)
exec python main.py
fi
# Web UI (FastAPI via uvicorn)
HOST="${HOST:-0.0.0.0}"
PORT="${PORT:-8080}"
WORKERS="${WORKERS:-1}"
exec uvicorn web.app:app --host "$HOST" --port "$PORT" --workers "$WORKERS"