Files
famapp/public/offline.html
T
ginnoir c73338e256 Code-side
src/lib/dev-login-config.ts — startup assertion: throws if NODE_ENV=production + ENABLE_DEV_LOGIN=true, scoped to runtime (skipped during next build).
Container

scripts/migrate.mjs — runs Drizzle migrations against DATABASE_URL.
deploy/docker-entrypoint.sh — runs migrations then exec node server.js. Skip with RUN_MIGRATIONS=false.
Dockerfile — copies drizzle/, scripts/migrate.mjs, entrypoint into runner stage; ENTRYPOINT now points at the script.
Compose

deploy/compose.yaml — famapp now image: ${FAMAPP_IMAGE:-ghcr.io/ginnoir/famapp:latest} (build still works locally as fallback). Authentik pinned via AUTHENTIK_IMAGE_TAG (default 2024.12.3). New RUN_MIGRATIONS env passed through.
.env.production.example — documents FAMAPP_IMAGE, AUTHENTIK_IMAGE_TAG, RUN_MIGRATIONS.
CI/CD

.github/workflows/ci.yml — push/PR: typecheck + lint + format:check + build.
.github/workflows/release.yml — v* tag: build + push ghcr.io/ginnoir/famapp:vX.Y.Z, :X.Y, :latest to GHCR.
Docs

deploy/README.md — full deploy/rollback/release runbook.
CHANGELOG.md — release log seeded with an Unreleased entry.
docs/tasks/09-pre-deploy-checklist.md — task 09 reframed from one-shot removal to a recurring pre-deploy checklist.
STATUS.md — updated.
Verified: pnpm typecheck, pnpm format, pnpm build, and docker compose config all clean.
2026-05-06 17:37:37 -05:00

96 lines
2.1 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#4F46E5" />
<title>famapp — offline</title>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--indigo: #4f46e5;
--indigo-light: #e0e7ff;
}
body {
font-family:
system-ui,
-apple-system,
sans-serif;
min-height: 100dvh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1.25rem;
padding: 2rem;
background: #f9fafb;
color: #111827;
text-align: center;
}
.icon {
width: 72px;
height: 72px;
border-radius: 16px;
background: var(--indigo);
display: flex;
align-items: center;
justify-content: center;
}
.icon svg {
width: 40px;
height: 40px;
}
h1 {
font-size: 1.25rem;
font-weight: 600;
}
p {
font-size: 0.9375rem;
color: #6b7280;
max-width: 28ch;
}
button {
margin-top: 0.5rem;
padding: 0.625rem 1.5rem;
background: var(--indigo);
color: white;
border: none;
border-radius: 0.5rem;
font-size: 0.9375rem;
font-weight: 500;
cursor: pointer;
}
button:active {
opacity: 0.85;
}
</style>
</head>
<body>
<div class="icon">
<!-- House silhouette -->
<svg viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<polygon points="20,5 34,17 31,17 31,35 9,35 9,17 6,17" fill="white" />
<rect x="15" y="22" width="10" height="13" rx="1" fill="#4F46E5" />
</svg>
</div>
<h1>You're offline</h1>
<p>famapp needs a connection — check your network and try again.</p>
<button onclick="location.reload()">Retry</button>
</body>
</html>