runbook.md 5.6 KB

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:

cp .env.docker.example .env.docker

Then edit .env.docker:

  • Set a strong SESSION_SECRET (>= 32 characters)
  • For local HTTP testing add:

    SESSION_COOKIE_SECURE=false
    

2.3 Create local NAS fixtures

Create a minimal NAS tree:

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:

docker compose -f docker-compose.yml -f docker-compose.local.yml up --build

2.5 Verify health

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):

node -e "const bcrypt=require('bcryptjs'); console.log(bcrypt.hashSync('secret-password', 10))"

Open Mongo shell inside the DB container:

docker exec -it rhl-lieferscheine-db mongosh -u root -p supersecret --authenticationDatabase admin

In mongosh:

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):

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:

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):

curl -i -b cookies.txt http://localhost:3000/api/branches/NL02/years

Logout:

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:

MSYS_NO_PATHCONV=1 docker exec -it rhl-lieferscheine-app ls -la /mnt/niederlassungen

3. Server Deployment (internal server)

3.1 Connect via SSH

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:

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):

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:

printf "ENV_FILE=.env.server
" > .env

After that, you can start the stack with:

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

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.