Skip to content

Admin manual

Drilio edited this page Aug 27, 2025 · 47 revisions

📘 Admin manual

🚀 Installation
🐳 Docker Stack Overview
📖 Introduction
🏗 The Stack
⚙️ Environment Configuration
📂 Supporting Files
🚢 Deploy
✅ Check If Your Services Are Up
👥 Create user
👑 Promote User to Admin
🔄 Impersonate User
🗄 Access Database
📜 Logs


🚀 Installation

MMU have two installation mode (Dev and Prod), see README https://github.com/TETRAS-IIIF/mirador-multi-user.

🐳 Docker stack overview

📖 Introduction

This Docker stack setup includes a multi-service environment using docker-compose to orchestrate containers for development and production. The stack is designed to handle different environments with ease by utilizing multiple configuration files and environment variables. Services in docker-compose File

General scheme

schemaSTAGE-multiutilisateur-v3.drawio.png

🏗 The stack

  1. Database (MariaDB) Image: mariadb:latest Handles data persistence for the application.

  2. Frontend (Node.js 20 Alpine) Image: node:20-alpine A lightweight Node.js environment for serving the frontend application.

  3. Backend (Node.js 20 Alpine)# Image: node:20-alpine Lightweight environment for running the backend logic.

  4. Caddy Image: caddy Serves as a lightweight web server to expose files and applications.

Environment Configuration (.env)

⚙️ Environment configuration

A .env file is used to manage environment variables, including the COMPOSE_FILE variable, to define the stack configuration dynamically.

📂 Supported COMPOSE_FILE files

  • port.yml : Exposes container ports to the host system.
version: "3.8"
services:

  db:
    ports:
      - "${DB_EXPOSE_PORT}:3306"

  backend:
    ports:
      - "${BACKEND_PORT}:3000"
      - "9229:9229"

  frontend:
    ports:
      - "${PORT}:4000"

  caddy:
    ports:
      - "${CADDY_PORT}:80"
  • dev.yml : Configures development volumes for live reloading and data persistence.
version: "3.8"
services:

    backend:
      volumes:
        - ./backend/.:/app
        - ./backend/node_modules:/app/node_modules
      command: npm run start:debug

    frontend:
      volumes:
        - ./frontend/.:/app/
        - ./frontend/node_modules:/app/node_modules
  • prod.yml : Configures volumes for production, focusing on stability and performance.
version: "3.8"
services:
    frontend:
      environment:
        - ENV=PROD
    backend:
      volumes:
        - ${HTTP_FOLDER}:/app/upload
  • traefik.yml : Configures Traefik as a reverse proxy for the production environment (the services can be exposed via any other mean of choice).
services:
  frontend:
    networks:
      - default
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.${NAME}.rule=Host(`${HOST}`)"
      - "traefik.http.routers.${NAME}.tls.certresolver=myresolver"
      - "traefik.http.routers.${NAME}.entrypoints=web,websecure"
      - "traefik.http.routers.${NAME}.middlewares=hardening@docker"

  backend:
    networks:
      - default
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.${BACKEND_NAME}.rule=Host(`${BACKEND_HOST}`)"
      - "traefik.http.routers.${BACKEND_NAME}.tls.certresolver=myresolver"
      - "traefik.http.routers.${BACKEND_NAME}.entrypoints=web,websecure"
      - "traefik.http.routers.${BACKEND_NAME}.middlewares=hardening@docker"

networks:
  traefik:
    external: true

This Docker stack is modular, efficient, and environment-aware. The use of multiple configuration files (port.yml, dev.yml, prod.yml, traefik.yml) allows for flexibility while the .env file ensures easy management of deployment settings. It facilitates a robust workflow for both local development and scalable production setups.

🚢 Deploy

Find the documentation to deploy in readme.md there : https://github.com/TETRAS-IIIF/mirador-multi-user?tab=readme-ov-file#mirador-multi-user

Add OIDC provider :

Fill the .env required variables :

OIDC_ISSUER=
OIDC_CLIENT_ID=
OIDC_CLIENT_SECRET=
OIDC_REDIRECT_URI=
PASSPORT_SESSION_SECRET= 
OPENID_CONNECTION=true

Add external app link

  • Fill this variable in .env :

EXTERNAL_DASHBOARD_URL=http://localhost:7000/dashboard

  • Copy/paste .env.external_app.sample into .env
  • Fill new implemented variables
  • comment the line of .env COMPOSE_FILE=docker-compose.yml:prod.yml:port.yml and uncomment COMPOSE_FILE=docker-compose.yml:prod.yml:traefik.yml:external-app.yml

✅ Check if your services are up :

  • Backend should respond with : "Hello world !"
  • Frontend should respond with home page
  • Caddy should respond with a 502 : bad gateway ( this is intended to avoid people to navigate into caddy's files)

Post-deployment Checks

Steps to verify deployment success:

  • Application is running
  • Logs are clean

Functionality tested

Account
  • Create account with internal app flow
  • Create account with oidc provider
  • Valid mail
  • Use Forgot password
  • Change password
  • Connect with new password
  • Go to settings
  • Change name
  • Change password
  • Change Mail
Project
  • Create a project
  • Change name , created date, thumbnail and description of this project
  • Add a user to the project
  • Change right of the user
  • Remove user from project
  • Set Metadata
  • Duplicate Project
  • Delete Project
  • Filter projects
  • Generate a snapShot
  • share snapShot
Manifest
  • Create a manifest
  • Change name , created date, thumbnail and description of this manifest
  • Add a user to the manifest
  • Change right of the user
  • Remove user from manifest
  • Set Metadata
  • Delete manifest
  • Filter manifest
  • Upload manifest
  • Link manifest
Create Manifest
  • Add media video and images
  • set thumbnail
  • change name
Advances edit mode
  • Change some field in advanced edit
Media
  • Upload media
  • Link media
  • Change name , created date, thumbnail and description of this media
  • Add a user to the media
  • Change right of the user
  • Remove user from media
  • Set Metadata
  • Delete media
  • Filter media
Group
  • Create a group
  • Change name , created date, thumbnail and description of this group
  • Add a user to the group
  • Change right of the user
  • Remove user from group

👥 Create user

First login using an account with administration privileges (see next section to promote User to Admin).

Then, as shown in the following screenshot:

  1. Click in the left panel to access the admin area
  2. Click CREATE USER
  3. Fill in the informations and click SUBMIT
image

The new user receives a welcoming email with a link to confirm his email address and to accept the GUC. The admin can "force" this like illustrated in the following screenshot. It is for instance useful if the created user does not receive the welcoming email.

image

👑 Promote user to admin

1 - Connect to mariadb container using

docker-compose exec db /bin/bash

2 - Then exec :

mariadb -uroot -p

3 - See list of user and privileges :

SELECT id,mail,_isAdmin FROM multiUsers.`user`;

4 - Promote user :

UPDATE multiUsers.`user` SET `_isAdmin` = 1 WHERE id = <USER ID> ;

If you want to revocke the Admin status execute stape 1 and 2 ans then :

UPDATE multiUsers.`user` SET `_isAdmin` = 0 WHERE id = <USER ID> ;

🔄 Impersonate user

To impersonate user you must be an admin, follow the steps from Promote user to admin section.

1 - Connect to you admin account on the login page

2 - click on Admin in your left panel 6a2075e239c1b89afe8222816c88e8c7.png

3 - Find a user to impersonate ( you can use the filter field at the top ) fdd0d69f0ed88ce36a75829360e73aff.png click on the "IMPERSONATE" button

🗄 Access database

To access db you must config .env COMPOSE_FILE variable to add port.yml COMPOSE_FILE=docker-compose.yml:prod.yml:traefik.yml

then you can configure any GUI like dbeaver to access it

📜 Logs

you'll find backend logs ( level depends on your .env config LOG_LEVEL) into mirador-multi-user/backend/dist/src/utils/logs/app.log

General scheme

schemaSTAGE-multiutilisateur-v3.drawio.png

🏗 The stack

  1. Database (MariaDB) Image: mariadb:latest Handles data persistence for the application.

  2. Frontend (Node.js 20 Alpine) Image: node:20-alpine A lightweight Node.js environment for serving the frontend application.

  3. Backend (Node.js 20 Alpine)# Image: node:20-alpine Lightweight environment for running the backend logic.

  4. Caddy Image: caddy Serves as a lightweight web server to expose files and applications.

Environment Configuration (.env)

⚙️ Environment configuration

A .env file is used to manage environment variables, including the COMPOSE_FILE variable, to define the stack configuration dynamically.

📂 Supported COMPOSE_FILE files

  • port.yml : Exposes container ports to the host system.
version: "3.8"
services:

  db:
    ports:
      - "${DB_EXPOSE_PORT}:3306"

  backend:
    ports:
      - "${BACKEND_PORT}:3000"
      - "9229:9229"

  frontend:
    ports:
      - "${PORT}:4000"

  caddy:
    ports:
      - "${CADDY_PORT}:80"
  • dev.yml : Configures development volumes for live reloading and data persistence.
version: "3.8"
services:

    backend:
      volumes:
        - ./backend/.:/app
        - ./backend/node_modules:/app/node_modules
      command: npm run start:debug

    frontend:
      volumes:
        - ./frontend/.:/app/
        - ./frontend/node_modules:/app/node_modules
  • prod.yml : Configures volumes for production, focusing on stability and performance.
version: "3.8"
services:
    frontend:
      environment:
        - ENV=PROD
    backend:
      volumes:
        - ${HTTP_FOLDER}:/app/upload
  • traefik.yml : Configures Traefik as a reverse proxy for the production environment (the services can be exposed via any other mean of choice).
services:
  frontend:
    networks:
      - default
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.${NAME}.rule=Host(`${HOST}`)"
      - "traefik.http.routers.${NAME}.tls.certresolver=myresolver"
      - "traefik.http.routers.${NAME}.entrypoints=web,websecure"
      - "traefik.http.routers.${NAME}.middlewares=hardening@docker"

  backend:
    networks:
      - default
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.${BACKEND_NAME}.rule=Host(`${BACKEND_HOST}`)"
      - "traefik.http.routers.${BACKEND_NAME}.tls.certresolver=myresolver"
      - "traefik.http.routers.${BACKEND_NAME}.entrypoints=web,websecure"
      - "traefik.http.routers.${BACKEND_NAME}.middlewares=hardening@docker"

networks:
  traefik:
    external: true

This Docker stack is modular, efficient, and environment-aware. The use of multiple configuration files (port.yml, dev.yml, prod.yml, traefik.yml) allows for flexibility while the .env file ensures easy management of deployment settings. It facilitates a robust workflow for both local development and scalable production setups.

🚢 Deploy

Find the documentation to deploy in readme.md there : https://github.com/TETRAS-IIIF/mirador-multi-user?tab=readme-ov-file#mirador-multi-user

Add OIDC provider :

Fill the .env required variables :

OIDC_ISSUER= OIDC_CLIENT_ID= OIDC_CLIENT_SECRET= OIDC_REDIRECT_URI= PASSPORT_SESSION_SECRET= OPENID_CONNECTION=true

Add external app link

Fill this variable in .env :

EXTERNAL_DASHBOARD_URL=http://localhost:7000/dashboard

✅ Check if your services are up :

  • Backend should respond with : "Hello world !"
  • Frontend should respond with home page
  • Caddy should respond with a 502 : bad gateway ( this is intended to avoid people to navigate into caddy's files)

Post-deployment Checks

Steps to verify deployment success:

  • Application is running
  • Logs are clean

Functionality tested

Account
  • Create account with internal app flow
  • Create account with oidc provider
  • Valid mail
  • Use Forgot password
  • Change password
  • Connect with new password
  • Go to settings
  • Change name
  • Change password
  • Change Mail
Project
  • Create a project
  • Change name , created date, thumbnail and description of this project
  • Add a user to the project
  • Change right of the user
  • Remove user from project
  • Set Metadata
  • Duplicate Project
  • Delete Project
  • Filter projects
  • Generate a snapShot
  • share snapShot
Manifest
  • Create a manifest
  • Change name , created date, thumbnail and description of this manifest
  • Add a user to the manifest
  • Change right of the user
  • Remove user from manifest
  • Set Metadata
  • Delete manifest
  • Filter manifest
  • Upload manifest
  • Link manifest
Create Manifest
  • Add media video and images
  • set thumbnail
  • change name
Advances edit mode
  • Change some field in advanced edit
Media
  • Upload media
  • Link media
  • Change name , created date, thumbnail and description of this media
  • Add a user to the media
  • Change right of the user
  • Remove user from media
  • Set Metadata
  • Delete media
  • Filter media
Group
  • Create a group
  • Change name , created date, thumbnail and description of this group
  • Add a user to the group
  • Change right of the user
  • Remove user from group

👥 Create user

First login using an account with administration privileges (see next section to promote User to Admin).

Then, as shown in the following screenshot:

  1. Click in the left panel to access the admin area
  2. Click CREATE USER
  3. Fill in the informations and click SUBMIT

you can configure logs level into .env file :

# 0 = ERROR, 1 = WARN, 2 = DEBUG, 3 = LOG, 4 = VERBOSE
LOG_LEVEL=0

You can also access logs of any service ( frontend - db - backend - caddy ) by using the command docker-compose logs <name-of-your-service> into ./mirador-multi-user

Custom assets

Custom assets can be added to the platform to personnalise some content. Custom assets have to be placed in the following folder : <root_deployment_folfder>/frontend/customAssets

The following can be configured:

  • Consent.tsx
  • favicon.svg
  • landing-footer.tsx
  • MediaFooter.tsx
  • CustomTerms.tsx
  • landing-background.webp
  • TermsFooter.tsx

For instance, the following content in landing-footer.tsx will display a capsule on the landing page, containing the logos placed in the customAssets/logos directory:

const imagePaths = Object.values(images).map((module) => (module as { default: string }).default);\
\
export const LandingFooter = () => {\
 return (\
   \<div\
     style={{\
       position: 'fixed',\
       bottom: '10px',\
       right: '10px',\
       background: 'rgba(255, 255, 255, 0.8)', // Semi-transparent white\
       borderRadius: '15px', // Rounded capsule shape\
       padding: '10px',\
       display: 'flex',\
       alignItems: 'center',\
       gap: '10px',\
       height: '70px', // Fixed height\
     }}\
   >\
     {imagePaths.map((image, index) => (\
       \<img\
         key={index}\
         src={image}\
         alt={\`Logo ${index + 1}\`}\
         style={{\
           height: '100%', // Fill the capsule height\
           width: 'auto', // Maintain aspect ratio\
         }}\
       />\
     ))}\
   \</div>\
 );\
};

Clone this wiki locally