# 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: "", 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.4.1 Optional: Persist ENV_FILE selection via `.env` If you want a simpler startup command (and to avoid forgetting `ENV_FILE=...`), you can create a small `.env` file **on the server only** that defines which env file Compose should use. Create `./.env` in the project root: ```bash printf "ENV_FILE=.env.server " > .env ``` After that, you can start the stack with: ```bash docker compose -f docker-compose.yml up -d --build ``` Notes: - Keep `.env` server-local (do not commit it). - `.env.server` still contains secrets and must not be committed. - Always run `docker compose` from the project root so Compose picks up the correct `.env` file. ```` ### 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`.