|
|
@@ -0,0 +1,250 @@
|
|
|
+<!-- --------------------------------------------------------------------------- -->
|
|
|
+
|
|
|
+<!-- Ordner: Docs -->
|
|
|
+
|
|
|
+<!-- Datei: runbook.md -->
|
|
|
+
|
|
|
+<!-- Relativer Pfad: Docs/runbook.md -->
|
|
|
+
|
|
|
+<!-- --------------------------------------------------------------------------- -->
|
|
|
+
|
|
|
+# Runbook: Local Development vs Server Deployment
|
|
|
+
|
|
|
+This runbook describes how to run the project locally (developer machine) and on the internal server.
|
|
|
+
|
|
|
+The goal is a **clean separation** between:
|
|
|
+
|
|
|
+- Local development (uses local NAS fixtures)
|
|
|
+- Server deployment (uses the real NAS mount at `/mnt/niederlassungen`)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. Repository Files and Separation
|
|
|
+
|
|
|
+### 1.1 Compose files
|
|
|
+
|
|
|
+- `docker-compose.yml`
|
|
|
+
|
|
|
+ - Base compose file (server-like)
|
|
|
+ - Mounts the real NAS path: `/mnt/niederlassungen:/mnt/niederlassungen:ro`
|
|
|
+
|
|
|
+- `docker-compose.local.yml`
|
|
|
+
|
|
|
+ - Local override
|
|
|
+ - Mounts local fixtures: `./.local_nas:/mnt/niederlassungen:ro`
|
|
|
+
|
|
|
+### 1.2 Env files
|
|
|
+
|
|
|
+- Committed templates:
|
|
|
+
|
|
|
+ - `.env.docker.example`
|
|
|
+ - `.env.local.example`
|
|
|
+
|
|
|
+- Local runtime env (not committed):
|
|
|
+
|
|
|
+ - `.env.docker`
|
|
|
+
|
|
|
+- Server runtime env (not committed):
|
|
|
+
|
|
|
+ - `.env.server`
|
|
|
+
|
|
|
+The compose file uses:
|
|
|
+
|
|
|
+- `ENV_FILE` to select which env file is loaded into the `app` container.
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. Local Development (Windows/macOS/Linux)
|
|
|
+
|
|
|
+### 2.1 Prerequisites
|
|
|
+
|
|
|
+- Docker Desktop installed and running.
|
|
|
+- Project checked out.
|
|
|
+
|
|
|
+### 2.2 Create local env file
|
|
|
+
|
|
|
+Copy the template:
|
|
|
+
|
|
|
+```bash
|
|
|
+cp .env.docker.example .env.docker
|
|
|
+```
|
|
|
+
|
|
|
+Then edit `.env.docker`:
|
|
|
+
|
|
|
+- Set a strong `SESSION_SECRET` (>= 32 characters)
|
|
|
+- For local HTTP testing add:
|
|
|
+
|
|
|
+```env
|
|
|
+SESSION_COOKIE_SECURE=false
|
|
|
+```
|
|
|
+
|
|
|
+### 2.3 Create local NAS fixtures
|
|
|
+
|
|
|
+Create a minimal NAS tree:
|
|
|
+
|
|
|
+```bash
|
|
|
+mkdir -p ./.local_nas/NL01/2024/10/23
|
|
|
+printf "dummy" > ./.local_nas/NL01/2024/10/23/test.pdf
|
|
|
+```
|
|
|
+
|
|
|
+### 2.4 Start the stack (local)
|
|
|
+
|
|
|
+Run with the local override:
|
|
|
+
|
|
|
+```bash
|
|
|
+docker compose -f docker-compose.yml -f docker-compose.local.yml up --build
|
|
|
+```
|
|
|
+
|
|
|
+### 2.5 Verify health
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -s http://localhost:3000/api/health
|
|
|
+```
|
|
|
+
|
|
|
+Expected (example):
|
|
|
+
|
|
|
+- `db` is `ok`
|
|
|
+- `nas.entriesSample` contains `NL01`
|
|
|
+
|
|
|
+### 2.6 Create a test user in Mongo (manual)
|
|
|
+
|
|
|
+Generate a bcrypt hash (local):
|
|
|
+
|
|
|
+```bash
|
|
|
+node -e "const bcrypt=require('bcryptjs'); console.log(bcrypt.hashSync('secret-password', 10))"
|
|
|
+```
|
|
|
+
|
|
|
+Open Mongo shell inside the DB container:
|
|
|
+
|
|
|
+```bash
|
|
|
+docker exec -it rhl-lieferscheine-db mongosh -u root -p supersecret --authenticationDatabase admin
|
|
|
+```
|
|
|
+
|
|
|
+In `mongosh`:
|
|
|
+
|
|
|
+```js
|
|
|
+use rhl-lieferscheine
|
|
|
+
|
|
|
+show collections
|
|
|
+
|
|
|
+db.users.insertOne({
|
|
|
+ username: "branchuser",
|
|
|
+ email: "nl01@example.com",
|
|
|
+ passwordHash: "<PASTE_HASH_HERE>",
|
|
|
+ role: "branch",
|
|
|
+ branchId: "NL01",
|
|
|
+ createdAt: new Date(),
|
|
|
+ updatedAt: new Date()
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+### 2.7 Login + call protected endpoints
|
|
|
+
|
|
|
+Login (stores cookie in `cookies.txt`):
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -i -c cookies.txt \
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
+ -d '{"username":"BranchUser","password":"secret-password"}' \
|
|
|
+ http://localhost:3000/api/auth/login
|
|
|
+```
|
|
|
+
|
|
|
+Call endpoints with cookie:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -i -b cookies.txt http://localhost:3000/api/branches
|
|
|
+curl -i -b cookies.txt http://localhost:3000/api/branches/NL01/years
|
|
|
+curl -i -b cookies.txt http://localhost:3000/api/branches/NL01/2024/months
|
|
|
+curl -i -b cookies.txt http://localhost:3000/api/branches/NL01/2024/10/days
|
|
|
+curl -i -b cookies.txt "http://localhost:3000/api/files?branch=NL01&year=2024&month=10&day=23"
|
|
|
+```
|
|
|
+
|
|
|
+RBAC negative test (expected 403):
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -i -b cookies.txt http://localhost:3000/api/branches/NL02/years
|
|
|
+```
|
|
|
+
|
|
|
+Logout:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -i -b cookies.txt -c cookies.txt http://localhost:3000/api/auth/logout
|
|
|
+```
|
|
|
+
|
|
|
+### 2.8 Notes for Git Bash on Windows
|
|
|
+
|
|
|
+Git Bash may rewrite paths like `/mnt/niederlassungen`.
|
|
|
+
|
|
|
+If you need to run `docker exec ... ls /mnt/niederlassungen`, disable MSYS path conversion:
|
|
|
+
|
|
|
+```bash
|
|
|
+MSYS_NO_PATHCONV=1 docker exec -it rhl-lieferscheine-app ls -la /mnt/niederlassungen
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. Server Deployment (internal server)
|
|
|
+
|
|
|
+### 3.1 Connect via SSH
|
|
|
+
|
|
|
+```bash
|
|
|
+ssh administrator@192.168.0.23
|
|
|
+```
|
|
|
+
|
|
|
+### 3.2 Prerequisites on the server
|
|
|
+
|
|
|
+- Docker and Docker Compose installed.
|
|
|
+- The real NAS share is mounted at:
|
|
|
+
|
|
|
+ - `/mnt/niederlassungen`
|
|
|
+
|
|
|
+- The mount is readable by Docker.
|
|
|
+
|
|
|
+### 3.3 Create server env file
|
|
|
+
|
|
|
+On the server (in the project folder), create `.env.server` based on the template:
|
|
|
+
|
|
|
+```bash
|
|
|
+cp .env.docker.example .env.server
|
|
|
+```
|
|
|
+
|
|
|
+Edit `.env.server`:
|
|
|
+
|
|
|
+- Set a strong `SESSION_SECRET`.
|
|
|
+- Keep `NODE_ENV=production`.
|
|
|
+- Do **not** set `SESSION_COOKIE_SECURE=false`.
|
|
|
+
|
|
|
+### 3.4 Start the stack on the server
|
|
|
+
|
|
|
+Use the base compose file only (no local override):
|
|
|
+
|
|
|
+```bash
|
|
|
+ENV_FILE=.env.server docker compose -f docker-compose.yml up -d --build
|
|
|
+```
|
|
|
+
|
|
|
+### 3.5 Verify
|
|
|
+
|
|
|
+On the server:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -s http://localhost:3000/api/health
|
|
|
+```
|
|
|
+
|
|
|
+Expected:
|
|
|
+
|
|
|
+- `db` is `ok`
|
|
|
+- `nas.entriesSample` contains real branch folders (`NLxx`)
|
|
|
+
|
|
|
+### 3.6 Logs and troubleshooting
|
|
|
+
|
|
|
+```bash
|
|
|
+docker compose -f docker-compose.yml logs --tail=200 app
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. HTTPS Note (Future)
|
|
|
+
|
|
|
+For real users, the application should be served over HTTPS (reverse proxy / TLS termination).
|
|
|
+
|
|
|
+Local HTTP testing is supported via `SESSION_COOKIE_SECURE=false`.
|