Portal live on Dokploy: ODBC Kerberos library and India time in the image
Dockerfile installs libgssapi-krb5-2 (ODBC Driver 18 could not load without it) and runs on TZ=Asia/Kolkata with tzdata (the server is UTC). Context.md: how the Portal was deployed (Drop zip, SQL login, DB host). 71 test files, 1224 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c049cece23
commit
83a0cf65ae
3 files changed
+64
-8
No files matched your search
+35
-5
@@ -187,7 +187,8 @@ Get-ChildItem tests\test_*.py | ForEach-Object { "$($_.Name): $((python $_.FullN
|
||||
- Tests run offline against fake HTML pages in `tests/fixtures/` and fake DB
|
||||
connections; they never touch eCW or SQL Server (`test_cdp_browser.py`
|
||||
starts a local Chromium on a debug port). As of 2026-10-27: 71 test
|
||||
files, **1222 tests** (full run 2026-10-27: 1222/1222) (earlier flaky, each
|
||||
files, **1224 tests** (full run 2026-10-27: 1222/1222; the 2 Dockerfile
|
||||
tests since, with test_portal_signin.py 24/24) (earlier flaky, each
|
||||
failed once and passed on rerun: test_verify_no_live_writes,
|
||||
depression_dx_pointer, progress_note_wait — watch them) (about 5 minutes for all of them).
|
||||
|
||||
@@ -623,8 +624,9 @@ the Portal (restarted 2026-10-26, [portal] terminal tab).
|
||||
|
||||
History: `git log --oneline`.
|
||||
|
||||
Last code commits: `70ba709` (2026-10-27, Portal server mode for Dokploy —
|
||||
§10), `f99dc17` (2026-10-27, Portal roles Super Admin /
|
||||
Last code commits: `cc3a01a` (2026-10-27, Portal container on India time —
|
||||
§10), `69c51d8` (2026-10-27, Dockerfile: libgssapi-krb5-2 for ODBC Driver
|
||||
18 — §10), `70ba709` (2026-10-27, Portal server mode for Dokploy — §10), `f99dc17` (2026-10-27, Portal roles Super Admin /
|
||||
Admin / Viewer — §2), `61338b4` (2026-10-26, Sign-in page redesign + tab
|
||||
icon — §5), `a436489` (2026-10-26, Portal look: aligned header /
|
||||
footer, 7-day chart, today's reasons, pass rate — §5), `2d4d4fc`
|
||||
@@ -762,8 +764,36 @@ test claim ids — new posts must not (§7).
|
||||
- **Gitea:** one overall snapshot update at the end of a day, when the
|
||||
operator asks (from the clone `D:\ecw-charge-validation`; operator
|
||||
pushes; 2026-10-26: `ba15a57` → `120fd68`).
|
||||
- **Portal for the client — Gitea + Dokploy (asked 2026-10-23; server
|
||||
mode built 2026-10-27 `70ba709`, not deployed yet).** `Dockerfile`
|
||||
- **Portal for the client — Gitea + Dokploy (asked 2026-10-23; LIVE on
|
||||
Dokploy 2026-10-27, `cc3a01a`, Ecare network only).** URL
|
||||
`http://10.200.0.15:8085` (Dokploy project Ecw_ChargeValidation →
|
||||
production → app **Portal**; port 8085 → 8000). The operator signed in
|
||||
there as Super Admin; Dashboard, Users, Sign-ins work. How it got there:
|
||||
- **Source = Drop (zip upload), not Git:** Dokploy cannot clone from
|
||||
Gitea (`server certificate verification failed`, Traefik's self-signed
|
||||
cert); Gitea has no internal http port and no SSH; the operator cannot
|
||||
open Dokploy Settings → Git Providers; the OTS-Team Gitea account does
|
||||
not see `automation-tools`. So: `git archive --format=zip HEAD
|
||||
Dockerfile requirements-portal.txt src web` → `D:\ecw-portal-deploy\
|
||||
portal-<hash>.zip` → app → General → Provider → **Drop** → select →
|
||||
the **Deploy under the drop box** (the top Deploy / Reload rebuilds the
|
||||
last upload). Long term: ask the Dokploy admin for a Gitea provider.
|
||||
- **DB:** the SQL Server is on the operator's PC (`MECARE331` =
|
||||
10.50.2.131), instance TCP port 58468 (dynamic — a SQL restart may move
|
||||
it; set a static port later). SQL login **`cv_portal`** (made in SSMS
|
||||
2026-10-27: db_datareader + INSERT/UPDATE `CV_PortalUser`, INSERT
|
||||
`CV_PortalSignIn`); its password only in Dokploy's env
|
||||
(`RESULTS_DB_CONN`), never here or in chat. The Portal works only while
|
||||
that PC is on.
|
||||
- **Fixes found live:** `69c51d8` the image needs `libgssapi-krb5-2` by
|
||||
name (autoremove took it; ODBC Driver 18 "Can't open lib ... file not
|
||||
found"); `cc3a01a` `TZ=Asia/Kolkata` + `tzdata` (the server is UTC: a
|
||||
15:45 IST Sign-in read 10:15; three such rows stay in CV_PortalSignIn
|
||||
from 2026-10-27 ~15:45). Errors seen: `SQLSTATE 01000` = driver not
|
||||
loading; `28000` = login missing / wrong password.
|
||||
- Sessions are in memory: every Deploy / Reload signs everyone out.
|
||||
- For the client: needs a public HTTPS URL (or VPN) from IT, and the DB
|
||||
off a desktop PC. `Dockerfile`
|
||||
(python 3.13-slim + ODBC Driver 18, copies only `src/` + `web/`,
|
||||
`requirements-portal.txt`); env in Dokploy, never in Git:
|
||||
`RESULTS_DB_CONN` (a SQL login; a Linux container cannot use
|
||||
|
||||
+5
-3
@@ -4,7 +4,8 @@
|
||||
# and PORTAL_URLS in Dokploy's environment — never in Git (.env.example).
|
||||
FROM python:3.13-slim-bookworm
|
||||
|
||||
# Microsoft ODBC Driver 18 for SQL Server, for pyodbc.
|
||||
# Microsoft ODBC Driver 18 for SQL Server, for pyodbc. libgssapi-krb5-2 by
|
||||
# name: the driver needs it, and autoremove took it with curl otherwise.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends curl gnupg ca-certificates \
|
||||
&& curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \
|
||||
@@ -12,7 +13,7 @@ RUN apt-get update \
|
||||
&& curl -fsSL https://packages.microsoft.com/config/debian/12/prod.list \
|
||||
-o /etc/apt/sources.list.d/mssql-release.list \
|
||||
&& apt-get update \
|
||||
&& ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 \
|
||||
&& ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 libgssapi-krb5-2 tzdata \
|
||||
&& apt-get purge -y curl gnupg && apt-get autoremove -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -24,7 +25,8 @@ COPY web ./web
|
||||
|
||||
RUN useradd --create-home portal
|
||||
USER portal
|
||||
ENV PORTAL_SERVER=1 PYTHONUNBUFFERED=1
|
||||
# India time, like the bot's rows: Sign-ins and "today" in IST, not UTC.
|
||||
ENV PORTAL_SERVER=1 PYTHONUNBUFFERED=1 TZ=Asia/Kolkata
|
||||
EXPOSE 8000
|
||||
CMD ["python", "-m", "uvicorn", "web.app:app", "--host", "0.0.0.0", \
|
||||
"--port", "8000", "--proxy-headers", "--forwarded-allow-ips", "*"]
|
||||
@@ -378,6 +378,30 @@ def the_portal_url_gives_the_hosts_origins_and_a_secure_cookie():
|
||||
assert "; secure" in r.headers["set-cookie"].lower(), r.headers
|
||||
|
||||
|
||||
@case
|
||||
def the_container_keeps_the_odbc_drivers_kerberos_library():
|
||||
"""Dokploy, 2026-10-27: autoremove took libgssapi-krb5-2 with curl, so
|
||||
ODBC Driver 18 could not load ("Can't open lib ... file not found")."""
|
||||
docker = (pathlib.Path(__file__).resolve().parent.parent
|
||||
/ "Dockerfile").read_text(encoding="utf-8")
|
||||
line = next(l for l in docker.splitlines() if "msodbcsql18" in l
|
||||
and "install" in l)
|
||||
assert "libgssapi-krb5-2" in line, line
|
||||
|
||||
|
||||
@case
|
||||
def the_container_keeps_india_time():
|
||||
"""Dokploy, 2026-10-27: the server clock is UTC, so a Sign-in at 15:45
|
||||
IST was recorded 10:15 and "today" would turn at 18:30 IST. The bot's
|
||||
rows are IST; the Portal must be too."""
|
||||
docker = (pathlib.Path(__file__).resolve().parent.parent
|
||||
/ "Dockerfile").read_text(encoding="utf-8")
|
||||
assert "TZ=Asia/Kolkata" in docker
|
||||
line = next(l for l in docker.splitlines() if "msodbcsql18" in l
|
||||
and "install" in l)
|
||||
assert "tzdata" in line, line
|
||||
|
||||
|
||||
@case
|
||||
def no_signed_in_page_carries_an_inline_style():
|
||||
app, _, _ = _portal()
|
||||
|
||||
Reference in new issue
Block a user