Rebrand to volundr; add deploy artifacts
- User-facing brand "bike-admin" -> "volundr" (page titles, top bar, login header, FastAPI title, README/AGENTS). Directory, remote, BIKE_ADMIN_* env prefix and bike_admin.db filename are unchanged. - Add deploy/: systemd unit (bike-admin.service) and a production .env template (env.production.example).
This commit is contained in:
@@ -4,7 +4,7 @@ Guidance for working in this repo.
|
||||
|
||||
## What this is
|
||||
|
||||
`bike-admin` is a small single-user web app for logging bike service/repair
|
||||
**volundr** (packaged as `bike_admin`) is a small single-user web app for logging bike service/repair
|
||||
"events" (type, date, mileage, cost, notes) and seeing per-bike hints: a
|
||||
**service-due** status derived from the newest mileage and the most recent
|
||||
`service` event, plus **MOT / insurance renewal** statuses derived from the most
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# bike-admin
|
||||
# volundr
|
||||
|
||||
A small, secure, single-user web app for logging bike service and repair
|
||||
"events" (type, date, mileage, cost, notes) and getting a clear **service-due**
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
"""bike-admin package."""
|
||||
"""volundr package."""
|
||||
|
||||
+1
-1
@@ -215,7 +215,7 @@ async def lifespan(_: FastAPI):
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(title="bike-admin", lifespan=lifespan)
|
||||
app = FastAPI(title="volundr", lifespan=lifespan)
|
||||
|
||||
|
||||
@app.exception_handler(FastAPIUnauthorized)
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}bike-admin{% endblock %}</title>
|
||||
<title>{% block title %}volundr{% endblock %}</title>
|
||||
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="/static/main.css">
|
||||
<script src="/static/htmx.min.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="topbar">
|
||||
<a class="brand" href="/">bike-admin</a>
|
||||
<a class="brand" href="/">volundr</a>
|
||||
<nav class="nav">
|
||||
<a href="/bikes/new" class="btn btn-primary">+ Bike</a>
|
||||
<a href="/logout"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ bike.name }} - bike-admin{% endblock %}
|
||||
{% block title %}{{ bike.name }} - volundr{% endblock %}
|
||||
{% block content %}
|
||||
<div class="page-head">
|
||||
<h1>{{ bike.name }}</h1>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Edit bike - bike-admin{% endblock %}
|
||||
{% block title %}Edit bike - volundr{% endblock %}
|
||||
{% block content %}
|
||||
<div class="page-head"><h1>Edit {{ bike.name }}</h1></div>
|
||||
<div class="card">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}New bike - bike-admin{% endblock %}
|
||||
{% block title %}New bike - volundr{% endblock %}
|
||||
{% block content %}
|
||||
<div class="page-head"><h1>New bike</h1></div>
|
||||
<div class="card">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Dashboard - bike-admin{% endblock %}
|
||||
{% block title %}Dashboard - volundr{% endblock %}
|
||||
{% block content %}
|
||||
<div class="page-head">
|
||||
<h1>Your bikes</h1>
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Log in - bike-admin</title>
|
||||
<title>Log in - volundr</title>
|
||||
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="/static/main.css">
|
||||
</head>
|
||||
<body class="auth">
|
||||
<main class="container auth-card">
|
||||
<h1 style="margin-top:0">bike-admin</h1>
|
||||
<h1 style="margin-top:0">volundr</h1>
|
||||
<p class="muted">Log in to manage your bikes.</p>
|
||||
|
||||
{% if error %}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
[Unit]
|
||||
Description=volundr (bike service-due + MOT/insurance tracker)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=bike
|
||||
Group=bike
|
||||
WorkingDirectory=/opt/bike_admin
|
||||
# Leading `-` = optional: the app still boots (and prompts for a password)
|
||||
# if the .env has not been created yet.
|
||||
EnvironmentFile=-/opt/bike_admin/.env
|
||||
ExecStart=/opt/bike_admin/.venv/bin/uvicorn app.main:app \
|
||||
--host 0.0.0.0 --port 8000 \
|
||||
--forwarded-allow-ips 192.168.0.0/16 --proxy-headers
|
||||
Restart=on-failure
|
||||
RestartSec=2
|
||||
# Hardening
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/opt/bike_admin/data
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,25 @@
|
||||
# bike_admin production environment (copied to /opt/bike_admin/.env on the server)
|
||||
# All values are BIKE_ADMIN_-prefixed. This file is NOT committed (see .gitignore).
|
||||
|
||||
# --- Required -------------------------------------------------
|
||||
BIKE_ADMIN_USERNAME=jake
|
||||
BIKE_ADMIN_PASSWORD=change-me-to-something-strong
|
||||
|
||||
# --- Required in production -----------------------------------
|
||||
# Secret used to derive the CSRF / session tokens. Generate with:
|
||||
# python3 -c "import secrets;print(secrets.token_urlsafe(32))"
|
||||
BIKE_ADMIN_SECRET_KEY=
|
||||
|
||||
# Adds the Secure flag to the session cookie (we're served over HTTPS via Caddy).
|
||||
BIKE_ADMIN_IS_PRODUCTION=true
|
||||
|
||||
# Bind to all interfaces so the hermodr reverse proxy (on another host) can reach it.
|
||||
# The app trusts X-Forwarded-* headers from the proxy (BIKE_ADMIN_TRUST_PROXY defaults true).
|
||||
BIKE_ADMIN_BIND_HOST=0.0.0.0
|
||||
BIKE_ADMIN_BIND_PORT=8000
|
||||
|
||||
# --- Optional fine-tuning (defaults shown) ---------------------
|
||||
# BIKE_ADMIN_SERVICE_DUE_SOON_MILES=200 # service "book soon" lead time
|
||||
# BIKE_ADMIN_RENEWAL_DUE_SOON_DAYS=60 # MOT/insurance "due soon" lead time
|
||||
# BIKE_ADMIN_RENEWAL_MONTHS=12 # MOT/insurance validity (months)
|
||||
# BIKE_ADMIN_DATA_DIR=/opt/bike_admin/data
|
||||
Reference in New Issue
Block a user