docs: clarify dev hosts and deployment guidance

This commit is contained in:
Daniel Volz
2026-05-24 13:36:01 +02:00
committed by GitHub
parent 3eb56885f9
commit 767ae23843
7 changed files with 71 additions and 27 deletions
+5
View File
@@ -10,6 +10,8 @@ PUID=1000
PGID=1000
PORT=3000
# Docker Compose quickstart serves the frontend on http://localhost:4174.
# Local Vite development usually uses http://localhost:5173 or http://localhost:4173 instead.
CORS_ORIGINS=http://localhost:4174
# Server default timezone for scheduled reminders.
@@ -18,8 +20,11 @@ TZ=Europe/Berlin
# Public base URL used for notification action links.
# Required for intake reminder action buttons.
# Use an externally reachable HTTPS URL for remote/self-hosted access.
# PUBLIC_APP_URL=https://medassist.example.com
# If this uses a non-local host, include that origin in CORS_ORIGINS.
# Local Vite development automatically allows this hostname; set
# VITE_ALLOWED_HOSTS only when you need additional development hostnames.
# Log level: debug, info, warn, error, silent
LOG_LEVEL=info
+6 -19
View File
@@ -1,26 +1,13 @@
# MedAssist-ng - Copilot Entry Point
## VERY IMPORTANT - Prioritized Constraints
This file is intentionally thin. `AGENTS.md` is the canonical governance file for this repository.
**First: Update Memory and Reports**
- Always keep agent work memory updated in `doku/memory_notes.md` so progress and decisions remain recoverable across context loss.
- If `doku/memory_notes.md` is missing, create it immediately.
- Always keep a user-facing work report updated in `doku/report.md` so completed work is easy to review.
- If `doku/report.md` is missing, create it immediately.
- This memory/report rule replaces the previous `doku/APP_BEHAVIOR.md` persistence requirement.
**Second: Follow Governance Rules**
- Consult `AGENTS.md` for governance, workflow, and skill rules when that file exists in the workspace.
When `AGENTS.md` exists in the workspace, use it as the single source of truth for governance, workflow, and skill rules.
If rules differ between files, follow `AGENTS.md`.
## Required Startup Steps
1. Read `AGENTS.md` first when it exists in the workspace.
2. If `AGENTS.md` exists, identify triggered skills from it and read each referenced `SKILL.md` before making changes.
3. Follow delegation boundaries exactly (`@testing-manager` for testing, `@release-manager` for release orchestration).
4. When work moves into a different thematic area, create or switch to a dedicated local branch or worktree before editing code, and reuse the same branch/worktree for follow-up work inside that same theme.
## Scope
This file intentionally stays minimal to prevent duplicated or conflicting instructions.
2. Ensure `doku/memory_notes.md` and `doku/report.md` exist and keep them updated during meaningful work. These files are local-only and must not be staged or committed unless explicitly requested.
3. Identify triggered skills from `AGENTS.md` and read only the matching `SKILL.md` files before making changes.
4. Follow delegation boundaries from `AGENTS.md`: `@testing-manager` for testing work and `@release-manager` for release orchestration, including the documented fallback protocol when a required specialist is unavailable.
5. Keep all non-canonical instruction files brief and aligned with `AGENTS.md`; do not duplicate full governance here.
+2
View File
@@ -24,6 +24,8 @@ on:
concurrency:
group: docker-build-${{ github.ref }}
# Cancel older runs on the same ref so the shared branch tag stays aligned
# with the newest commit instead of racing older builds against newer ones.
cancel-in-progress: true
# Default minimal permissions
+15 -2
View File
@@ -157,10 +157,13 @@ Share your medication schedule with others via a public link.
### Multi-Person Support
- Manage medications for multiple people
- Share schedules via link. Recipients can mark doses as taken, you see it live
- Optionally allow shared links to view and edit intake journal notes for their visible schedule window
- Optionally embed the medication overview directly on shared links via a settings toggle
### Data Export & Import
- Export all your data (medications, dose history, settings) as JSON
- Export all your data (medications, dose history, intake journal notes, settings) as JSON
- Review validated import contents before replacing current data
- Optionally download a fresh backup before confirming import
- Import previously exported data with automatic ID remapping
- Choose whether to include sensitive data in exports
@@ -188,6 +191,16 @@ docker compose -p medassist-ng up -d
Open `http://localhost:4174` and start tracking your medications.
### Verify Deployment
After the containers start, confirm the stack is actually healthy:
1. Run `docker compose ps` and confirm the `backend` service is `healthy` and the `frontend` service is running.
2. Open `http://localhost:3000/health` and confirm the backend responds with JSON that includes `"status":"ok"`.
3. Open `http://localhost:4174` and confirm the app shell loads and can reach the API.
If the frontend loads but API requests fail, check the backend health endpoint first and confirm `CORS_ORIGINS` includes the frontend origin you are using. If you plan to open reminder or share links from another device, set `PUBLIC_APP_URL` to the externally reachable app URL instead of relying on `localhost`.
# Configuration
Configure the application with environment variables in `.env`. Keep the basic container settings in the README and use the dedicated docs for the full reference.
@@ -206,7 +219,7 @@ Optional but commonly needed:
| Variable | Default | Description |
|----------|---------|-------------|
| `PUBLIC_APP_URL` | — | Public base URL for notification action links |
| `PUBLIC_APP_URL` | — | Public base URL for notification action and share links |
Detailed configuration references:
+13 -3
View File
@@ -9,9 +9,9 @@ Configure MedAssist with environment variables in `.env`. Start from `.env.examp
| `PUID` | `1000` | User ID for container file permissions |
| `PGID` | `1000` | Group ID for container file permissions |
| `PORT` | `3000` | Backend API port |
| `CORS_ORIGINS` | `http://localhost:4174` | Allowed origins for CORS |
| `CORS_ORIGINS` | `http://localhost:4174` | Allowed origins for CORS in the Docker Compose quickstart; local Vite development commonly uses `http://localhost:5173` or `http://localhost:4173` |
| `TZ` | `Europe/Berlin` | Server default timezone for scheduled reminders |
| `PUBLIC_APP_URL` | — | Public base URL for notification action links. Must be reachable by phones, browsers, and notification providers; do not point this to `localhost` or an internal Docker hostname. |
| `PUBLIC_APP_URL` | — | Public base URL for notification action and share links. Strongly recommended for any deployment used from another device; do not point this to `localhost` or an internal Docker hostname. Local Vite development also allows this hostname automatically. |
| `LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error`, or `silent` |
| `RATE_LIMIT_MAX` | `100` | Maximum requests per minute per IP |
| `OPENAPI_DOCS_ENABLED` | `auto` | Explicitly enable or disable `/docs` and `/docs/json` |
@@ -22,6 +22,12 @@ API docs behavior:
- `OPENAPI_DOCS_ENABLED=true` enables `/docs` and `/docs/json`.
- `OPENAPI_DOCS_ENABLED=false` disables the docs only.
`CORS_ORIGINS` note:
- The `.env.example` file is optimized for the Docker Compose quickstart, where the frontend runs on `http://localhost:4174`.
- Local frontend development uses the Vite dev server instead, so the backend schema defaults cover `http://localhost:5173` and `http://localhost:4173`.
- If you use a custom hostname or reverse proxy, include that origin in `CORS_ORIGINS`.
## Authentication
| Variable | Default | Description |
@@ -102,13 +108,17 @@ API reference:
Reminder timing uses IANA timezones. `TZ` is the server default. Users can override it in Settings.
These values are runtime defaults. User-specific settings can override reminder behavior after first save.
## Push Notifications
Push notification setup, provider support, and URL examples are documented in [PUSH_NOTIFICATIONS.md](PUSH_NOTIFICATIONS.md).
Recommended provider: `ntfy`, especially for intake reminders with direct actions.
Notification action links use `PUBLIC_APP_URL` as their base URL. For self-hosted setups, this should normally be your externally reachable HTTPS address, for example `https://med.example.com`.
Notification action and share links should use `PUBLIC_APP_URL` as their reachable base URL. For self-hosted setups, this should normally be your externally reachable HTTPS address, for example `https://med.example.com`.
If `PUBLIC_APP_URL` is missing in a remote deployment, reminder links can still be generated from local origins that are unreachable from phones or external browsers.
## Default User Settings
+11 -2
View File
@@ -19,8 +19,17 @@ If the frontend dev server runs behind a reverse proxy or on a remote host, set
These development overrides are documented here intentionally and are not part of the standard operator-focused `.env.example` surface.
## API Proxy Contract
- Frontend browser code should call `/api/*`, not hardcoded backend hostnames.
- Vite rewrites `/api/*` to the backend target configured by `BACKEND_URL` or the built-in default for the current environment.
- Default backend target:
- local dev outside Docker: `http://localhost:3000`
- dev stack inside Docker: `http://backend-dev:3000`
- If your backend runs on a different host or service name, set `BACKEND_URL` explicitly before starting Vite.
- `BACKEND_URL`: backend target used by the Vite `/api` proxy; default `http://localhost:3000` outside Docker and `http://backend-dev:3000` in Docker
- `VITE_ALLOWED_HOSTS`: comma-separated hostnames allowed to connect to the dev server; default `localhost,127.0.0.1`
- `VITE_ALLOWED_HOSTS`: comma-separated hostnames allowed to connect to the dev server; default `localhost,127.0.0.1` plus the hostname from `PUBLIC_APP_URL` when configured
- `VITE_HMR_HOST`: public hostname for HMR websocket connections
- `VITE_HMR_PROTOCOL`: websocket protocol override (`ws` or `wss`)
- `VITE_HMR_CLIENT_PORT`: public websocket port exposed to the browser
@@ -43,4 +52,4 @@ npm run check
npm run build
```
Use the root-level commands for full-stack validation when a change spans backend and frontend. Keep using the package-local commands when you are validating only one slice.
Use the root-level commands for full-stack validation when a change spans backend and frontend. Keep using the package-local commands when you are validating only one slice.
+19 -1
View File
@@ -20,6 +20,22 @@ function parseOptionalPort(value: string | undefined) {
return Number.isFinite(parsed) ? parsed : undefined;
}
function parseUrlHostname(value: string | undefined) {
if (!value) {
return undefined;
}
try {
return new URL(value).hostname;
} catch {
return undefined;
}
}
function uniqueHosts(hosts: Array<string | undefined>) {
return [...new Set(hosts.filter((host): host is string => Boolean(host)))];
}
// Read version from package.json at build time
const packageJson = JSON.parse(readFileSync("./package.json", "utf-8"));
@@ -27,7 +43,9 @@ const packageJson = JSON.parse(readFileSync("./package.json", "utf-8"));
// In Docker, prefer backend-dev to avoid localhost proxy failures.
const defaultBackendTarget = existsSync("/.dockerenv") ? "http://backend-dev:3000" : "http://localhost:3000";
const backendTarget = process.env.BACKEND_URL || defaultBackendTarget;
const allowedHosts = parseCsvEnv(process.env.VITE_ALLOWED_HOSTS, ["localhost", "127.0.0.1"]);
const configuredAllowedHosts = parseCsvEnv(process.env.VITE_ALLOWED_HOSTS, []);
const baseAllowedHosts = configuredAllowedHosts.length > 0 ? configuredAllowedHosts : ["localhost", "127.0.0.1"];
const allowedHosts = uniqueHosts([...baseAllowedHosts, parseUrlHostname(process.env.PUBLIC_APP_URL)]);
const hmrHost = process.env.VITE_HMR_HOST?.trim();
const hmrProtocol = process.env.VITE_HMR_PROTOCOL === "ws" ? "ws" : process.env.VITE_HMR_PROTOCOL === "wss" ? "wss" : undefined;
const hmrClientPort = parseOptionalPort(process.env.VITE_HMR_CLIENT_PORT);