# Docker Support, Meow Expiry and Time-Zone-Aware Clock **Date:** 2026-08-23 **Project:** ScratchingPost **Status:** resolved **Tags:** docker, expiry, scheduling, timezone, clock, sqlite, v1.1.0, v1.1.1 ## Context Jess wanted Scratching Post deployable in Docker as an alternative to IIS, and wanted slides (Meows) to be able to expire automatically after an end date. Running in a container exposed a time-zone problem: containers default to UTC, so expiry checks against `DateTime.Now` fired at the wrong local time. Released as v1.1.0 (Docker + expiry, 2026-08-22) and v1.1.1 (timezone, 2026-08-23). ## Key Decisions - **`ExpiresAt` on the Slide (Meow) model**, nullable — no expiry by default. - **Expired Meows are filtered server-side** from both the live display and the playlist API, not hidden client-side. - **Auto-add the `ExpiresAt` column for existing databases at startup** — because the app uses `EnsureCreated()` (no migrations), existing IIS databases wouldn't otherwise get the new column. - **Central `Clock` helper instead of raw `DateTime.Now`** — one place that knows the configured time zone; used for expiry checks, the Expired badge, and form text. - **`TimeZone` setting: blank = host local time** — so existing IIS installs behave exactly as before; Docker image defaults to `UTC` with `tzdata` installed so a named zone can be set. - **Configurable data directory** so the SQLite DB and uploads live on persistent Docker volumes. ## Technical Details - `Infrastructure/Clock.cs` — `Clock.Now` returns time in the configured zone; configured from the `TimeZone` setting at startup. Imported into Razor views. - `appsettings.json` → `TimeZone` (e.g. an IANA zone name; blank = host local). - Docker: multi-stage `Dockerfile`, `.dockerignore`, `docker-compose.yml` with persistent volumes for DB and uploads; `tzdata` installed in the runtime image. - Create/Edit Meow forms have a Scheduling card with an expiry date field and text clarifying which time zone it uses. - Meows list shows an Expires column and an Expired badge (computed with `Clock.Now`). ## Code Changes - `Models/` — `ExpiresAt` on Slide. - `Data/` — configurable data directory; startup check adds `ExpiresAt` column if missing. - Display/playlist controllers — skip expired Meows. - `Views/` — Scheduling card on Create/Edit; Expires column + Expired badge on list; Clock import. - `Infrastructure/Clock.cs` — new. - `Program.cs` — configure Clock from `TimeZone`. - `Dockerfile`, `.dockerignore`, `docker-compose.yml` — new. - `README.md` — Docker deployment, Meow expiration, TimeZone setting; version bumps to v1.1.0 / v1.1.1. ## Open Questions / Next Steps - Add a start date ("publish from") to pair with expiry, if needed. - **ASK** priority-slide feature still planned. - If more schema changes accumulate, consider moving from `EnsureCreated()` + ad-hoc column checks to real EF migrations. ## Artifacts - Release v1.1.1 — `6a6d524` Document TimeZone setting; bump to v1.1.1 - `baac95d` — Use Clock.Now for expiry checks - v1.1.0 — Docker deployment and Meow expiration - Repo: https://gitea.hideawaygaming.com.au/jessikitty/ScratchingPost