Files
Project-SDE-WP-Suite/DEPLOY-login-portal.md
n.siegfried bdb798efdd Add Portainer deploy guide for the login portal
Standalone instructions for the Portainer admin: set AUTH_SECRET_KEY,
rebuild + redeploy the stack, and bootstrap the first admin account.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 14:52:27 -07:00

3.7 KiB

Deploy: Work Package Suite — login portal update

Instructions for the Portainer admin to take the new secure login portal live. No prior context needed.

Repo: Project-SDE-WP-Suite (primegit) — changes are merged to main.

What changed: the app now has a username/password login. Going live needs:

  1. one new environment variable,
  2. a rebuild of the stack (not just a restart), and
  3. creating the first admin account.

Why a rebuild (not a restart): both the nginx/webserver and api images bake the code in at build time (COPY html/ and COPY server/ in their Dockerfiles). A plain restart will not pick up the new code — the images must be rebuilt from the latest main.


1. Add an environment variable to the stack

In the stack's Environment variables section, add:

Name Value Notes
AUTH_SECRET_KEY a long random string Required. Signs the login session cookies.
AUTH_SESSION_HOURS 12 Optional. Hours a login lasts before re-auth (defaults to 12).

Generate the secret on the host with:

openssl rand -base64 48

If AUTH_SECRET_KEY is not set, the app still starts but falls back to a random per-process key — logins then reset on every restart and break across the 2 gunicorn workers. It must be set to a fixed value.

The existing database variables (POSTGRES_*) are unchanged.


2. Pull latest main, rebuild, and redeploy

  • Pull the latest commit on main and redeploy the stack with image rebuild enabled (e.g. "Re-pull and redeploy" / force rebuild). This rebuilds both the webserver and api images.
  • New Python dependencies (bcrypt, PyJWT) are in requirements.txt and install automatically during the rebuild.
  • The users table is created automatically on API startup — no DB migration needed.

3. Verify the containers

  • Confirm wp_api and the webserver container are both running.
  • If wp_api fails to start, check its Logs. (A missing AUTH_SECRET_KEY only logs a warning — it won't crash — but please confirm it's set.)

4. Create the first admin account

The login system needs one admin user in the production (Postgres) database. Open the wp_api container's Console (/bin/sh) and run:

python -m server.manage_users create-admin <username> --name "<Full Name>"

It prompts for a password (minimum 8 characters) and prints Created admin: <username>.

Non-interactive alternative:

python -m server.manage_users create-admin <username> --name "<Full Name>" --password "<password>"

Other CLI commands (run the same way): list, create <user> --role user, reset-password <user>, disable <user>, enable <user>.


5. Confirm it works

  1. Load the site's normal URL — it should redirect to a login page.
  2. Sign in with the admin account from step 4.
  3. That admin can then add all other users from the in-app Admin → User administration page (top-right Admin link), so no further shell access is needed.

Reference — what's in this release

  • server/auth.py — bcrypt password hashing, JWT session cookie, the request gate.
  • server/app.py/api/auth/* endpoints + middleware that refuses every /api data route without a valid session.
  • server/manage_users.py — the CLI used in step 4.
  • html/login.html, html/auth-guard.js — login page and per-page guard.
  • html/admin.html / admin.js — Admin Console gated on the admin role, with the user administration UI.
  • Sessions are stateless: a signed JWT in an HttpOnly, SameSite=Lax cookie, marked Secure automatically when served over HTTPS (via X-Forwarded-Proto from nginx).