Aller au contenu
Table des matières

DasherControl : Un tableau de bord et ses trois frontières

DasherControl réunit des liens et des applications intégrées dans des espaces de travail sauvegardés. Vue gère l’interface, Rust et Rocket exposent l’API, et Diesel conserve la disposition dans PostgreSQL. Le contrôle Docker suit un parcours distinct.

Application et services Docker
  • Mis à jour
  • 8
  • Rust · 46.84%
  • MIT
Rust (Rocket)Vue 3PostgreSQLDocker Compose Rust Node.js cargo test
Composants documentés
2Explorer les modules
Documents source
2Lire les instructions
Langages du dépôtRust 46.84%6

Parts calculées à partir des octets GitHub Linguist.

Rust46.84%
46.84%60 028 octets
Vue43.67%
43.67%55 958 octets
JavaScript4%
4%5 121 octets
Shell2.55%
2.55%3 267 octets
Langage%Octets
Rust46.84%60 028
Vue43.67%55 958
JavaScript4%5 121
Shell2.55%3 267
Dockerfile2.05%2 628
PLpgSQL0.89%1 145

1. Aperçu

1.1. Pourquoi il existe

Architecture homelab découplée : backend Rust/Rocket pilotant le démon Docker via Shiplift, associé à un frontend Vue réactif.

1.2. Cas d’usage

Tableau de bord centralisé pour services conteneurisés en homelab, signets et gestion d'espaces de travail.

2. Cas d’utilisation

Tableau de bord Rust (Rocket) et Vue pour homelab : espaces de travail en grille d’applets et contrôle Docker de base.

Diagramme de cas d’utilisation de DasherControl : Se connecter au tableau; Disposer des applets en grille; Changer d’espace de travail; Piloter les conteneurs Docker; Ouvrir un terminal SSH webDasherControlSe connecter au tableauDisposer des applets en grilleChanger d’espace de travailPiloter les conteneurs DockerOuvrir un terminal SSH webAdmin du homelab«système»Moteur Docker«système»PostgreSQL
Acteurs à gauche (personnes) et à droite (systèmes externes) ; chaque ovale est un cas d’utilisation appuyé par les fichiers cités ci-dessous.
Se connecter au tableau
Admin du homelabPostgreSQL

cargo run --bin create_admin crée le premier compte ; POST /tenants/api/login vérifie le hachage bcrypt et renvoie un JWT utilisé par les routes protégées.

Disposer des applets en grille
Admin du homelab

GridLayoutMain.vue place des applets comme IFrame, Shortcut, Editor, Canvas, Terminal et DockerManager sur une grille redimensionnable.

Changer d’espace de travail
Admin du homelabPostgreSQL

Les routes /workspaces/api créent, mettent à jour, listent et suppriment les espaces de travail et leurs applets, stockés dans PostgreSQL via Diesel.

Piloter les conteneurs Docker
Admin du homelabMoteur Docker

/containers/api/docker_list liste les conteneurs via shiplift, et /containers/api/stop/<id> et restart/<id> agissent sur un conteneur si un jeton valide est fourni.

Ouvrir un terminal SSH web
Admin du homelab

src/bin/start_websocket.rs relie un WebSocket à une session ssh2 pour l’applet Terminal ; le README indique que le terminal web est en cours.

2.1. Scénario : Installer le tableau de bord sur un serveur Ubuntu

  1. Construire l’interface avec cd frontend && npm install && npm run build.
  2. Définir DATABASE_URL dans Rocket.toml et .env, puis lancer diesel migration run.
  3. Lancer cargo run --bin create_admin, puis cargo run pour démarrer le serveur Rocket.
  4. Se connecter, ajouter des applets IFrame pour des services comme Sonarr ou Jellyfin et enregistrer l’espace.
  5. Ouvrir l’applet DockerManager pour lister les conteneurs et en redémarrer un.

Fichiers consultésREADME.mdCargo.tomlsrc/main.rssrc/tenants/handler.rssrc/workspaces/handler.rssrc/containers/handler.rssrc/bin/create_admin.rssrc/bin/start_websocket.rsfrontend/components/GridLayoutMain.vue

3. Démarrage

Ces commandes viennent de la documentation du dépôt. Elles n’ont pas été exécutées pendant cette revue.

README.md · Install (Tested only on Ubuntu 20.04)
// bash scripts/rust-setup-dev.sh
// bash scripts/js-dev-setup.sh
cd frontend && npm install && npm run build && cd ..
cargo install diesel_cli --no-default-features --features postgres
// go in Rocket.toml and .env and change DATABASE_URL to your postgresql server
diesel migration run
// create admin user
cargo run --bin create_admin
// run web app
cargo run
Commandes déclarées dans les manifestes

3.1. frontend/package.json

lint
eslint --ext .js,.vue frontend tests/unit
build
npm run clean && webpack --mode production
test
echo "Error: no test specified" && exit 1
docker-compose.yml · Docker
DOCKER_BUILDKIT=1 docker build -t antoinebou13/dashercontrol .
DOCKER_BUILDKIT=1 docker-compose up -d --build && docker-compose logs -f

4. Références du dépôt

Le dépôt ne fournit pas de guide détaillé pour ces étapes. Commencez par le README et les fichiers commentés ci-dessus.

Documentation source

2 documents lus parmi 2 candidats.

5. Fonctions et composants 2

Propriété des espaces
Les routes de liste obtiennent l’identifiant du tenant depuis un jeton. La route de lecture des applets vérifie le tenant de l’espace avant de retourner son contenu. L’espace et ses applets constituent ainsi une disposition persistante liée à un utilisateur.
Opérations sur les conteneurs
src/containers/docker.rs regroupe des opérations Docker avec Shiplift. Ces appels gèrent des conteneurs et des images, plutôt que les dispositions. Leur gestion d’échec est importante: une liste en erreur affiche un message et retourne un vecteur vide.

6. Architecture

Ouvrez un composant pour suivre ses connexions, ou explorez le diagramme complet.

Composants du système Contexte
Mermaid Diagramme interactif

Vue générale des composants et des échanges vérifiés dans le dépôt.

Vue statique de l’architecture de DasherControl
Aperçu statique. Le diagramme interactif le remplace après le chargement de Mermaid.
flowchart LR

subgraph group_dashboard["Dashboard UI"]
  node_main_ui["Dashboard Shell<br/>[Main.vue]"]
  node_grid["Workspace Grid<br/>[GridLayoutMain.vue]"]
  node_grid_item["Grid Items<br/>[GridItemApplet.vue]"]
  node_applet_router["Applet Selector<br/>[Applet.vue]"]
  node_applet_authoring["Applet Creation<br/>[CreateNew.vue]"]
  node_editor["Applet Editor<br/>[Editor.vue]"]
  node_iframe["Embedded Sites"]
  node_shortcut["Shortcuts<br/>[Shortcut.vue]"]
  node_canvas["Canvas Applet<br/>[Canvas.vue]"]
  node_login_ui["Login Screen<br/>[Login.vue]"]
end

subgraph group_identity["Tenant Identity"]
  node_tenant_api["Tenant Endpoints<br/>[handler.rs]"]
  node_tenant_model["Tenant Accounts<br/>[model.rs]"]
  node_token_auth["Token Validation<br/>[token.rs]"]
end

subgraph group_workspace["Workspace Data"]
  node_workspace_api["Workspace Endpoints<br/>[handler.rs]"]
  node_workspace_model["Workspace Records<br/>[model.rs]"]
  node_database[("PostgreSQL Access<br/>[db.rs]")]
  node_schema["Database Schema<br/>[schema.rs]"]
end

subgraph group_integrations["Runtime Integrations"]
  node_docker_ui["Docker Manager<br/>[DockerManager.vue]"]
  node_container_api["Container Endpoints<br/>[handler.rs]"]
  node_docker_engine["Docker Engine<br/>[docker.rs]"]
  node_terminal_ui["Terminal Applet<br/>[Terminal.vue]"]
  node_terminal_ws["Terminal WebSocket<br/>[websocket.rs]"]
  node_server["Rocket Server<br/>[main.rs]"]
end

node_user(("Dashboard User"))

node_user -->|"uses"| node_main_ui
node_main_ui -->|"renders"| node_grid
node_grid -->|"renders"| node_grid_item
node_grid_item -->|"renders"| node_applet_router
node_applet_router -->|"selects"| node_applet_authoring
node_applet_router -->|"selects"| node_editor
node_applet_router -->|"selects"| node_iframe
node_applet_router -->|"selects"| node_shortcut
node_applet_authoring -->|"configures"| node_applet_authoring
node_grid -->|"requests"| node_workspace_api
node_tenant_api -->|"authenticates"| node_tenant_model
node_tenant_api -->|"issues tokens"| node_token_auth
node_token_auth -->|"checks session"| node_tenant_model
node_workspace_api -->|"queries"| node_workspace_model
node_workspace_api -->|"validates"| node_token_auth
node_tenant_model -->|"queries"| node_schema
node_workspace_model -->|"queries"| node_schema
node_tenant_api -->|"uses connection"| node_database
node_workspace_api -->|"uses connection"| node_database
node_docker_ui -->|"requests"| node_container_api
node_container_api -->|"controls"| node_docker_engine
node_applet_router -->|"selects"| node_docker_ui
node_applet_router -->|"selects"| node_terminal_ui
node_server -->|"mounts routes"| node_tenant_api
node_server -->|"mounts routes"| node_workspace_api
node_server -->|"mounts routes"| node_container_api
node_server -->|"references"| node_terminal_ws
node_user -.->|"may use"| node_canvas
node_terminal_ui -.->|"SSH terminal"| node_terminal_ws


class node_main_ui,node_grid,node_grid_item,node_applet_router,node_applet_authoring,node_editor,node_iframe,node_shortcut,node_canvas,node_login_ui,node_user toneBlue
class node_tenant_api,node_tenant_model,node_token_auth toneAmber
class node_workspace_api,node_workspace_model,node_database,node_schema toneMint
class node_docker_ui,node_container_api,node_docker_engine,node_terminal_ui,node_terminal_ws,node_server toneRose

Un tableau de bord homelab configurable où les utilisateurs organisent des espaces de travail composés d’applets. Vue appelle des routes Rocket pour la persistance, les contrôles de locataire et les actions Docker; PostgreSQL conserve les espaces et un adaptateur séparé communique avec Docker.

Composants
24
Connexions
29
Liens appuyés par le code
26/29
Version texte du diagramme
  • Interface Vue → Routes Rocket
  • Routes Rocket → Diesel et PostgreSQL
  • Routes Rocket → Adaptateur Shiplift
  • Adaptateur Shiplift → Démon Docker
Suivre un parcours dans le code

Le chargement d’un espace passe par ses routes et ses applets. Le redémarrage d’un conteneur passe plutôt par l’adaptateur Docker. L’interface doit distinguer un espace vide, Docker indisponible et une iframe bloquée par l’application intégrée.

7. Dossier technique

Établi à partir du code au commit d5e4b5a (66 fichiers). Chaque élément vient d’une correspondance de motif dans le code: ouvrez le fichier lié avant de vous y fier.

7.1. Couches et modules

Les dossiers sont classés par couche selon leur nom, de l’interface utilisateur jusqu’à l’accès aux données. Comme le classement repose sur les noms seulement, le diagramme ne dit rien des appels entre couches.

Mermaid Vue en couches
flowchart TB
  subgraph L_presentation["Présentation"]
    direction TB
    presentation_0["frontend/components<br/>20 fichiers"]
    presentation_1["frontend<br/>4 fichiers"]
    presentation_2["frontend/pages<br/>4 fichiers"]
    presentation_3["frontend/public<br/>1 fichier"]
  end
  subgraph L_interface["Points d’entrée et API"]
    direction TB
    interface_0["bin<br/>2 fichiers"]
    interface_1["(root)<br/>1 fichier"]
    interface_2["containers<br/>1 fichier"]
    interface_3["src<br/>1 fichier"]
    interface_more["+2"]
  end
  subgraph L_application["Services applicatifs"]
    direction TB
    application_0["scripts<br/>5 fichiers"]
  end
  subgraph L_domain["Domaine et règles métier"]
    direction TB
    domain_0["containers<br/>1 fichier"]
    domain_1["src<br/>1 fichier"]
    domain_2["tenants<br/>1 fichier"]
    domain_3["workspaces<br/>1 fichier"]
  end
  subgraph L_infrastructure["Données et infrastructure"]
    direction TB
    infrastructure_0["src<br/>1 fichier"]
  end
  subgraph L_core["Source principale"]
    direction TB
    core_0["tenants<br/>4 fichiers"]
    core_1["certs<br/>3 fichiers"]
    core_2["containers<br/>3 fichiers"]
    core_3["terminal<br/>3 fichiers"]
    core_more["+2"]
  end
  subgraph L_tests["Tests"]
    direction TB
    tests_0["tests<br/>6 fichiers"]
    tests_1["frontend<br/>1 fichier"]
  end
  subgraph L_hosting["Build, CI et hébergement"]
    direction TB
    hosting_0[".github<br/>6 fichiers"]
    hosting_1["(root)<br/>2 fichiers"]
  end
  L_presentation ~~~ L_interface
  L_interface ~~~ L_application
  L_application ~~~ L_domain
  L_domain ~~~ L_infrastructure
  L_infrastructure ~~~ L_core
  L_core ~~~ L_tests
  L_core ~~~ L_hosting
Modules et couche principale
ModuleCoucheFichiersTypesExtensions
frontend/componentsPrésentation200.vue
tenantsSource principale615.rs
containersSource principale53.rs
scriptsServices applicatifs50.sh
srcSource principale55.rs
workspacesSource principale510.rs
frontendPrésentation40.js .vue
frontend/pagesPrésentation40.vue
certsSource principale30.sh
terminalSource principale30.rs
binPoints d’entrée et API23.rs
(root)Points d’entrée et API10.sh
frontend/publicPrésentation10.xml

7.2. Modèle C4

Du contexte du système aux déclarations du code. Chaque niveau conserve les limites des sources disponibles.

UML 1 · Contexte du système
1 · Contexte du système

La vue C4 la plus large : qui utilise le projet et sur quels systèmes et stockages externes il s’appuie. Rendu avec uml-mcp.

Source PlantUML
@startuml
!include <C4/C4_Context>
LAYOUT_LEFT_RIGHT()
Person(P_http, "Client HTTP")
System(SYS, "DasherControl", "DasherControl réunit des liens et des applications intégrées dans des…")
SystemDb(D0, "Boîte à outils SQL Rust")
Rel(P_http, SYS, "Utilise")
Rel(SYS, D0, "Lit et écrit")
@enduml
UML 2 · Conteneurs
2 · Conteneurs

Un niveau plus près : les parties qui s’exécutent séparément dans le projet, leur langage principal et le chemin des appels entre elles. Rendu avec uml-mcp.

Source PlantUML
@startuml
!include <C4/C4_Container>
LAYOUT_LEFT_RIGHT()
Person(P_http, "Client HTTP")
System_Boundary(SYS, "DasherControl") {
  Container(APP, "DasherControl", "Rust")
  ContainerDb(DB0, "Boîte à outils SQL Rust", "")
}
Rel(P_http, APP, "Utilise")
Rel(APP, DB0, "Lit et écrit")
@enduml
UML 3 · Composants et couches
3 · Composants et couches

Modules regroupés par couche du code. Les limites indiquent l’organisation, sans affirmer une isolation à l’exécution ni des appels. Rendu avec uml-mcp.

Source PlantUML
@startuml
!include <C4/C4_Component>
LAYOUT_TOP_DOWN()
System_Boundary(SYS, "DasherControl") {
Boundary(L0, "Présentation", "layer") {
Component(M0_0, "frontend/components", "Vue", "20 fichiers")
Component(M0_1, "frontend", "JavaScript, Vue", "4 fichiers")
Component(M0_2, "frontend/pages", "Vue", "4 fichiers")
Component(M0_3, "frontend/public", ".xml", "1 fichiers")
}
Boundary(L1, "Points d’entrée et API", "layer") {
Component(M1_0, "bin", "Rust", "2 fichiers")
Component(M1_1, "(root)", ".sh", "1 fichiers")
Component(M1_2, "containers", "Rust", "1 fichiers")
Component(M1_3, "src", "Rust", "1 fichiers")
Component(M1_4, "tenants", "Rust", "1 fichiers")
Component(M1_5, "workspaces", "Rust", "1 fichiers")
}
Boundary(L2, "Services applicatifs", "layer") {
Component(M2_0, "scripts", ".sh", "5 fichiers")
}
Boundary(L3, "Domaine et règles métier", "layer") {
Component(M3_0, "containers", "Rust", "1 fichiers")
Component(M3_1, "src", "Rust", "1 fichiers")
Component(M3_2, "tenants", "Rust", "1 fichiers")
Component(M3_3, "workspaces", "Rust", "1 fichiers")
}
Boundary(L4, "Données et infrastructure", "layer") {
Component(M4_0, "src", "Rust", "1 fichiers")
}
Boundary(L5, "Source principale", "layer") {
Component(M5_0, "tenants", "Rust", "4 fichiers")
Component(M5_1, "certs", ".sh", "3 fichiers")
Component(M5_2, "containers", "Rust", "3 fichiers")
Component(M5_3, "terminal", "Rust", "3 fichiers")
Component(M5_4, "workspaces", "Rust", "3 fichiers")
Component(M5_5, "src", "Rust", "2 fichiers")
}
Boundary(L6, "Tests", "layer") {
Component(M6_0, "tests", "Rust", "6 fichiers")
Component(M6_1, "frontend", "JavaScript", "1 fichiers")
}
Boundary(L7, "Build, CI et hébergement", "layer") {
Component(M7_0, ".github", ".md, .yml", "6 fichiers")
Component(M7_1, "(root)", "Dockerfile, .yml", "2 fichiers")
}
}
@enduml
UML 4 · Code
4 · Code

Déclarations, champs et méthodes sélectionnés, regroupés par fichier source. Aucun héritage ni appel n’est déduit. Rendu avec uml-mcp.

Source PlantUML
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
top to bottom direction
hide empty members
package "DasherControl" {
package "src/containers/docker.rs" as F0 {
class "DockerInterface" as T0_0 {
  get_containers()
  get_images()
  docker_info()
  log_container()
  pull_image()
  check_image_exist()
}
}
package "src/tenants/model.rs" as F1 {
class "TenantConfiguration" as T1_0 {
  create()
  all()
  get()
}
class "DBJsonType" as T1_1 {
  from_sql()
  to_sql()
}
class "LoginHistory" as T1_2 {
  create()
  save_login_history()
}
class "Tenant" as T1_3 {
  id
  email
  name
  username
  password
  role
  created_at
  login_session
}
class "NewTenant" as T1_4 {
  email
  name
  username
  password
  role
  created_at
}
class "RegisterTenant" as T1_5 {
  email
  name
  username
  role
  password
  password_confirmation
}
class "RegisterTenantNoRole" as T1_6 {
  email
  name
  username
  role
  password
  password_confirmation
}
class "AuthTenant" as T1_7 {
  email
  username
  password
}
}
package "src/fairing.rs" as F2 {
class "CORS" as T2_0 {
  info()
  on_response()
}
}
package "src/db.rs" as F3 {
class "DbConn" as T3_0 {
  from_request()
  deref()
}
}
package "src/tenants/error.rs" as F4 {
class "MyError" as T4_0 {
  from()
  fmt()
}
}
package "src/workspaces/model.rs" as F5 {
class "Applet" as T5_0 {
  id
  name
  position_x
  position_y
  width
  height
  editable
  applet_data
}
class "NewApplet" as T5_1 {
  name
  position_x
  position_y
  width
  height
  editable
  applet_data
}
class "NewAppletNoWorkspace" as T5_2 {
  name
  position_x
  position_y
  width
  height
  editable
}
class "Workspace" as T5_3 {
  id
  display_order
  name
  tenant_id
}
class "WorkspaceWithApplets" as T5_4 {
  id
  display_order
  name
  tenant_id
}
class "NewWorkspace" as T5_5 {
  display_order
  name
  tenant_id
}
}
package "src/tenants/token.rs" as F6 {
class "Claims" as T6_0 {
  iat
  sub
  exp
  xsrf_token
  email
  username
  role
}
}
package "src/bin/create_admin.rs" as F7 {
class "NewTenant" as T7_0 {
  id
  email
  name
  username
  password
  role
  created_at
}
}
package "src/containers/model.rs" as F8 {
class "Container" as T8_0 {
  id
  name
  tenant_id
}
}
}
@enduml

7.3. Flux de données

Les appels du diagramme GitDiagram, dans l’ordre où on les rencontre depuis les points d’entrée. GitDiagram produit ce graphe par IA; les chemins de fichiers cités ont été comparés à l’arbre du dépôt.

Mermaid Diagramme de séquence
sequenceDiagram
  autonumber
  participant P0 as Rocket Server
  participant P1 as Tenant Endpoints
  participant P2 as Workspace Endpoints
  participant P3 as Container Endpoints
  participant P4 as Terminal WebSocket
  participant P5 as Dashboard User
  participant P6 as Dashboard Shell
  participant P7 as Canvas Applet
  participant P8 as Tenant Accounts
  participant P9 as Token Validation
  participant P10 as PostgreSQL Access
  participant P11 as Workspace Records
  participant P12 as Docker Engine
  participant P13 as Workspace Grid
  participant P14 as Database Schema
  P0->>P1: mounts routes
  P0->>P2: mounts routes
  P0->>P3: mounts routes
  P0->>P4: references
  P5->>P6: uses
  P5--)P7: may use
  P1->>P8: authenticates
  P1->>P9: issues tokens
  P1->>P10: uses connection
  P2->>P11: queries
  P2->>P9: validates
  P2->>P10: uses connection
  P3->>P12: controls
  P6->>P13: renders
  P8->>P14: queries
  P9->>P8: checks session
Étapes en texte (+5)
  1. Rocket Server vers Tenant Endpoints mounts routes
  2. Rocket Server vers Workspace Endpoints mounts routes
  3. Rocket Server vers Container Endpoints mounts routes
  4. Rocket Server vers Terminal WebSocket references
  5. Dashboard User vers Dashboard Shell uses
  6. Dashboard User vers Canvas Applet may use
  7. Tenant Endpoints vers Tenant Accounts authenticates
  8. Tenant Endpoints vers Token Validation issues tokens
  9. Tenant Endpoints vers PostgreSQL Access uses connection
  10. Workspace Endpoints vers Workspace Records queries
  11. Workspace Endpoints vers Token Validation validates
  12. Workspace Endpoints vers PostgreSQL Access uses connection
  13. Container Endpoints vers Docker Engine controls
  14. Dashboard Shell vers Workspace Grid renders
  15. Tenant Accounts vers Database Schema queries
  16. Token Validation vers Tenant Accounts checks session
  17. Workspace Records vers Database Schema queries
  18. Workspace Grid vers Grid Items renders
  19. Workspace Grid vers Workspace Endpoints requests
  20. Grid Items vers Applet Selector renders
  21. Applet Selector vers Applet Creation selects
  22. Applet Selector vers Applet Editor selects
  23. Applet Selector vers Embedded Sites selects
  24. Applet Selector vers Shortcuts selects

7.4. Interface publique

Du code extérieur peut utiliser tout ce qui est listé ici. Le projet déclare aussi 36 types publics.

UML Cas d’utilisation
Cas d’utilisation

Chaque acteur est un type d’appelant, relié à ce qu’il peut demander au projet. Rendu avec uml-mcp.

Source PlantUML
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
left to right direction
actor "Client HTTP" as A_http
rectangle "DasherControl" {
  usecase "GET/POST/PUT /api (15 routes)" as U0
  usecase "GET /" as U1
  usecase "GET /json" as U2
  usecase "GET /show_count" as U3
  usecase "GET /count" as U4
  usecase "GET /ip" as U5
}
A_http --> U0
A_http --> U1
A_http --> U2
A_http --> U3
A_http --> U4
A_http --> U5
@enduml

Routes HTTP 21

Mermaid Carte des routes par préfixe
flowchart LR
  api(["HTTP API"])
  g0["/api"]
  api --> g0
  g0r0["GET /api/list"]
  g0 --> g0r0
  g0r1["PUT /api/new"]
  g0 --> g0r1
  g0r2["GET /api/docker_list"]
  g0 --> g0r2
  g0r3["GET /api/create_container"]
  g0 --> g0r3
  g0r4["POST /api/restart/'container_id'"]
  g0 --> g0r4
  g0m["+10"]
  g0 --> g0m
  g1["/"]
  api --> g1
  g1r0["GET /"]
  g1 --> g1r0
  g2["/count"]
  api --> g2
  g2r0["GET /count"]
  g2 --> g2r0
  g3["/ip"]
  api --> g3
  g3r0["GET /ip"]
  g3 --> g3r0
  g4["/json"]
  api --> g4
  g4r0["GET /json"]
  g4 --> g4r0
  g5["/public"]
  api --> g5
  g5r0["GET /public/'file..'"]
  g5 --> g5r0
  g6["/show_count"]
  api --> g6
  g6r0["GET /show_count"]
  g6 --> g6r0
MéthodeCheminSource
GET/api/listsrc/workspaces/handler.rs:29
PUT/api/newsrc/containers/handler.rs:27
GET/api/docker_listsrc/containers/handler.rs:36
GET/api/create_containersrc/containers/handler.rs:43
POST/api/restart/<container_id>src/containers/handler.rs:65
POST/api/stop/<container_id>src/containers/handler.rs:82
GET/src/router.rs:32
GET/jsonsrc/router.rs:38
Afficher 13 routes de plus
GET/show_countsrc/router.rs:47
GET/countsrc/router.rs:55
GET/ipsrc/router.rs:61
GET/public/<file..>src/router.rs:67
GET/api/tokensrc/tenants/handler.rs:11
POST/api/createsrc/workspaces/handler.rs:87
POST/api/loginsrc/tenants/handler.rs:65
POST/api/logoutsrc/tenants/handler.rs:106
GET/api/<workspace_id>src/workspaces/handler.rs:10
POST/api/newsrc/workspaces/handler.rs:47
POST/api/updatesrc/workspaces/handler.rs:57
POST/api/applets/createsrc/workspaces/handler.rs:77
POST/api/delete/<workspace_id>src/workspaces/handler.rs:108

Points d’entrée

7.5. Interface privée

Ces noms sont internes selon les conventions du langage: tiret bas initial, private, static ou pub(crate).

Fonction privée au module
24

7.6. Entités et modèle de données 27

Mermaid Diagramme de classes des entités
classDiagram
  direction LR
  class E0["Applet"] {
    +i32 id
    +String name
    +i32 position_x
    +i32 position_y
    +i32 width
    +i32 height
  }
  class E1["Tenant"] {
    +i32 id
    +String email
    +String name
    +String username
    +String password
    +String role
  }
  class E2["NewApplet"] {
    +String name
    +i32 position_x
    +i32 position_y
    +i32 width
    +i32 height
    +bool editable
  }
  class E3["Claims"] {
    +i64 iat
    +i32 sub
    +i64 exp
    +String xsrf_token
    +String email
    +String username
  }
  class E4["NewTenant"] {
    +String email
    +String name
    +String username
    +String password
    +String role
    +NaiveDateTime created_at
  }
  class E5["NewAppletNoWorkspace"] {
    +String name
    +i32 position_x
    +i32 position_y
    +i32 width
    +i32 height
    +bool editable
  }
  class E6["RegisterTenant"] {
    +String email
    +String name
    +String username
    +String role
    +String password
    +String password_confirmation
  }
  class E7["RegisterTenantNoRole"] {
    +String email
    +String name
    +String username
    +String role
    +String password
    +String password_confirmation
  }
  class E8["Workspace"] {
    +i32 id
    +i32 display_order
    +String name
    +i32 tenant_id
  }
  class E9["WorkspaceWithApplets"] {
    +i32 id
    +i32 display_order
    +String name
    +i32 tenant_id
  }

Une flèche relie un champ à l’entité que son type nomme.

EntitéNaturePremiers champs
AppletEnregistrement ou interfaceid, name, position_x, position_y, width, height, editable, applet_data
TenantEnregistrement ou interfaceid, email, name, username, password, role, created_at, login_session
NewAppletEnregistrement ou interfacename, position_x, position_y, width, height, editable, applet_data
ClaimsEnregistrement ou interfaceiat, sub, exp, xsrf_token, email, username, role
NewTenantEnregistrement ou interfaceid, email, name, username, password, role, created_at
NewAppletNoWorkspaceEnregistrement ou interfacename, position_x, position_y, width, height, editable
NewTenantEnregistrement ou interfaceemail, name, username, password, role, created_at
RegisterTenantEnregistrement ou interfaceemail, name, username, role, password, password_confirmation
Afficher 6 entités de plus
RegisterTenantNoRoleEnregistrement ou interfaceemail, name, username, role, password, password_confirmation
WorkspaceEnregistrement ou interfaceid, display_order, name, tenant_id
WorkspaceWithAppletsEnregistrement ou interfaceid, display_order, name, tenant_id
AuthTenantEnregistrement ou interfaceemail, username, password
ContainerEnregistrement ou interfaceid, name, tenant_id
NewWorkspaceEnregistrement ou interfacedisplay_order, name, tenant_id

7.7. Logique métier

Une fois écartés le code d’interface et les services et entités ci-dessus, ces classes ont le plus de méthodes.

DockerInterface Source principale, 10 méthodes
get_containers, get_images, docker_info, log_container, pull_image, check_image_exist
TenantConfiguration Domaine et règles métier, 3 méthodes
create, all, get
DBJsonType Domaine et règles métier, 2 méthodes
from_sql, to_sql
LoginHistory Domaine et règles métier, 2 méthodes
create, save_login_history
CORS Source principale, 2 méthodes
info, on_response
DbConn Données et infrastructure, 2 méthodes
from_request, deref
MyError Source principale, 2 méthodes
from, fmt

7.8. Base de données et persistance

Tables et collections 7

users tenants workspaces applets containers login_history tenant_configuration

14 migrations

Conteneurs de données

postgres

7.9. Intégrations externes

Clients HTTP

axios

7.10. Stack et dépendances

Rust Cargo.toml 22 à l’exécution

Rust edition 2018

Ouvrir le manifeste

Node.js frontend/package.json 15 à l’exécution, 29 dev

Ouvrir le manifeste

Dépendances externes

65 paquets déclarés (37 à l’exécution, 28 pour le développement) dans Cargo.toml, frontend/package.json.

Tableau des paquets 65
Dépendances externes
PaquetVersionUsageRôleRegistre
rocket0.4.7exécutionCadriciel webcrates.io
rocket_contrib0.4.5exécutionCommunity contributed libraries for the Rocket web framework.crates.io
rocket_codegen0.4.7exécutionProcedural macros for the Rocket web framework.crates.io
serde1.0.104exécutionSérialisationcrates.io
serde_derive1.0.99exécutionSérialisationcrates.io
serde_json1.0.40exécutionSérialisationcrates.io
diesel>=1.4.8exécutionAccès aux donnéescrates.io
chrono0.4.10exécutionDate and time library for Rustcrates.io
dotenv0.15.0exécutionConfigurationcrates.io
jsonwebtoken5.0.1exécutionAuthentification et sécuritécrates.io
bcrypt0.8.0exécutionAuthentification et sécuritécrates.io
csrf0.4.0exécutionCSRF protection primitivescrates.io
shiplift0.7exécutionA Rust interface for maneuvering Docker containerscrates.io
tokio1.4.0exécutionAn event-driven, non-blocking I/O platform for writing asynchronous I/O backed applications.crates.io
tokio-tungstenite0.13.0exécutionTokio binding for Tungstenite, the Lightweight stream-based WebSocket implementationcrates.io
log0.4exécutionA lightweight logging facade for Rustcrates.io
fern0.5exécutionSimple, efficient loggingcrates.io
futures0.3.13exécutionAn implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces.crates.io
futures-util0.3exécutionCommon utilities and extension traits for the futures-rs library.crates.io
uuid0.8.2exécutionA library to generate and parse UUIDs.crates.io
ssh20.9.1exécutionBindings to libssh2 for interacting with SSH servers and executing remote commands, forwarding local ports, etc.crates.io
openssl0.10.33exécutionOpenSSL bindingscrates.io
axios^0.21.1exécutionClient HTTPnpmjs.com
js-cookie3.0.0-rc.1exécutionA simple, lightweight JavaScript API for handling cookiesnpmjs.com
socket.io-client^4.0.1exécutionMessagerie temps réelnpmjs.com
tiptap^1.32.1exécutionA rich-text editor for Vue.jsnpmjs.com
tiptap-extensions^1.35.1exécutionExtensions for tiptapnpmjs.com
vue^2.6.12exécutionInterface utilisateurnpmjs.com
vue-grid-layout^2.3.12exécutionInterface utilisateurnpmjs.com
vuesax^4.0.1-alpha.25exécutionInterface utilisateurnpmjs.com
vuex^3.6.2exécutionInterface utilisateurnpmjs.com
vuex-persistedstate*exécutionInterface utilisateurnpmjs.com
xterm^4.11.0exécutionFull xterm terminal, in your browsernpmjs.com
xterm-addon-attach^0.6.0exécutionAn addon for xterm.js that enables attaching to a web socket. This addon requires xterm.js v4+.npmjs.com
xterm-addon-fit^0.5.0exécutionAn addon for xterm.js that enables fitting the terminal's dimensions to a containing element. This adnpmjs.com
xterm-addon-search^0.8.0exécutionAn addon for xterm.js that enables searching the buffer. This addon requires xterm.js v4+.npmjs.com
xterm-addon-web-links^0.4.0exécutionAn addon for xterm.js that enables web links. This addon requires xterm.js v4+.npmjs.com
@babel/core^7.13.10développementOutils de buildnpmjs.com
@babel/preset-env^7.13.10développementOutils de buildnpmjs.com
babel-loader^8.2.2développementOutils de buildnpmjs.com
clean-webpack-plugin^3.0.0développementOutils de buildnpmjs.com
copy-webpack-plugin^8.0.0développementOutils de buildnpmjs.com
css-loader^5.1.2développementcss loader module for webpacknpmjs.com
eslint-plugin-vue^7.8.0développementAnalyse et formatagenpmjs.com
file-loader^6.2.0développementA file loader module for webpacknpmjs.com
gulp^4.0.2développementThe streaming build system.npmjs.com
gulp-eslint^6.0.0développementAnalyse et formatagenpmjs.com
html-webpack-plugin^5.3.1développementOutils de buildnpmjs.com
image-minimizer-webpack-plugin^2.2.0développementOutils de buildnpmjs.com
imagemin-gifsicle^7.0.0développementImagemin plugin for Gifsiclenpmjs.com
imagemin-jpegtran^7.0.0développementjpegtran imagemin pluginnpmjs.com
imagemin-optipng^8.0.0développementImagemin plugin for OptiPNGnpmjs.com
imagemin-svgo^9.0.0développementSVGO imagemin pluginnpmjs.com
postcss^8.2.8développementOutils de buildnpmjs.com
postcss-loader^5.2.0développementOutils de buildnpmjs.com
rimraf^3.0.2développementA deep deletion module for node (like rm -rf)npmjs.com
sass^1.32.8développementOutils de buildnpmjs.com
sass-loader^11.0.1développementSass loader for webpacknpmjs.com
vue-friendly-iframe^0.20.0développementInterface utilisateurnpmjs.com
vue-loader^15.9.6développementInterface utilisateurnpmjs.com
vue-style-loader^4.1.3développementInterface utilisateurnpmjs.com
vue-template-compiler^2.6.12développementInterface utilisateurnpmjs.com
webpack^5.26.2développementOutils de buildnpmjs.com
webpack-cli^4.5.0développementOutils de buildnpmjs.com
webpack-dev-server^3.11.2développementOutils de buildnpmjs.com

7.11. Pipeline CI/CD

2 workflows GitHub Actions, 2 tâches. Chaque boîte est une tâche ; les boîtes à double bord publient ou déploient, et les flèches suivent les dépendances needs.

Mermaid Déroulement du pipeline
flowchart LR
  subgraph wf0["build"]
    direction LR
    wf0_build["build<br/>ubuntu-latest"]
  end
  subgraph wf1["test"]
    direction LR
    wf1_build["build<br/>ubuntu-latest"]
  end
  t0(["Triggers · the · workflow · on · push · or"])
  t0 --> wf0_build
  t0 --> wf1_build
Workflows, déclencheurs, tâches et cibles
WorkflowDéclencheursTâchesPublie vers
build
.github/workflows/build.yml
Triggers, the, workflow, on, push, or
  • build ubuntu-latest
    Checkout branch · Install ubuntu Dependencies · Install rust · use default .env file · Run cargo build · Install JS
—
test
.github/workflows/tests.yml
Triggers, the, workflow, on, push, or
  • build ubuntu-latest
    Checkout branch · Install ubuntu Dependencies · Install rust · use default .env file · Run cargo build
—

7.12. Déploiement

Mermaid Schéma de déploiement
flowchart LR
  repo[("Dépôt GitHub")]
  ci[["GitHub Actions<br/>2 workflows"]]
  image["Image Docker<br/>FROM jdrouet/rust-nightly:stretch-slim-20201230"]
  repo -->|"push ou demande de fusion"| ci
  ci -->|"docker build"| image
UML Déploiement
Déploiement

Le nœud extérieur est l’endroit où le code s’exécute. Chaque image de base pointe vers ce qu’elle construit, les flèches pleines mènent aux bases de données et les pointillées aux services externes. Rendu avec uml-mcp.

Source PlantUML
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
node "Image Docker" as H {
  artifact "DasherControl" as APP
}
artifact "FROM jdrouet/rust-nightly:stretch-slim…" as IMG0
IMG0 ..> APP : construit
artifact "FROM rust:alpine" as IMG1
IMG1 ..> APP : construit
database "Boîte à outils SQL Rust" as DB0
APP --> DB0
cloud "WebSocket" as E0
APP ..> E0
@enduml

Où il s’exécute

Images Docker de base

jdrouet/rust-nightly:stretch-slim-20201230 rust:alpine

7.13. Supervision

Ce que le code consigne, mesure et expose pour savoir s’il fonctionne.

Vérifications de santé des conteneurs

7.14. Sécurité

Contrôles

Variables d’environnement 1

La page reprend les noms sans leurs valeurs et souligne ceux qui ressemblent à des secrets.

NODE_ENV

7.15. Tests automatisés

Fichiers de test
7
Fichiers source
64
Cas de test, environ
5
Tests unitaires
7

Aucun rapport chiffré de couverture dans les sources analysées.

Où sont les tests

src/tests 6 frontend/tests/unit 1

Intégration continue

test
cargo test
UML Pipeline CI
Pipeline CI

Le workflow GitHub Actions principal suit ces étapes. Les tâches lancées en parallèle sont côte à côte. Rendu avec uml-mcp.

Source PlantUML
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
title test
start
partition "build" {
  :Checkout branch;
  :Install ubuntu Dependencies;
  :Install rust;
  :use default .env file;
  :Run cargo build;
}
stop
@enduml

Rien trouvé pour: Services.

8. Déploiement et exploitation

Les ports, le stockage et les relations de démarrage ci-dessous viennent de la configuration du dépôt. depends_on indique l’ordre de démarrage, pas la disponibilité du service.

Réseau. Bridge network dasher-net linking the DasherControl web app with PostgreSQL.

Carte du déploiement

Topologie Compose des services, ports et dépendances de démarrage documentés.

Vue statique de l’architecture de DasherControl
flowchart LR
  classDef svc fill:#1b3040,stroke:#6fdbd0,color:#edf4fb
  dashercontrol["dashercontrol<br/>8000:8000"]:::svc
  postgres["postgres<br/>5432:5432"]:::svc
  postgres --> dashercontrol
Version texte du diagramme
  • dashercontrol — Build from multi-stage Dockerfile · 8000:8000 → postgres, startup healthcheck
  • postgres — postgres:14-alpine · 5432:5432
ServiceImage ou buildPorts publiésDémarrageStockage
dashercontrolBuild from multi-stage Dockerfile8000:8000postgres, startup healthcheckNamed volume dasher-data
postgrespostgres:14-alpine5432:5432Named volume pgdata

9. Types et structure des fichiers

36 types déclarés, dont 12 dans l’aperçu des relations de base.

Diagramme des types
classDiagram
direction TB
class t883aa4939d84["DockerInterface"] {
  <<struct>>
  new()
  init()
  get_containers()
  get_images()
}
class t6c6e876f9471["NewTenant"] {
  <<struct>>
}
class td007a4775b01["NewTenantConfiguration"] {
  <<struct>>
}
class t9d91c22b8e18["DBJsonType"] {
  <<struct>>
  from_sql()
  to_sql()
}
class t11bf41e6278b["Container"] {
  <<struct>>
  create()
  all()
}
class ta9679a334153["NewContainer"] {
  <<struct>>
}
class tdc82d141f21c["DbConn"] {
  <<struct>>
  from_request()
  deref()
}
class t981fd8c93b75["CORS"] {
  <<struct>>
  info()
  on_response()
}
class te127dc44374a["HitCount"] {
  <<struct>>
}
class t6437f975dc23["TemplateContext"] {
  <<struct>>
}
class tb361ddc722e9["JsonMessage"] {
  <<struct>>
}
class t8722c44b4eb9["MyError"] {
  <<enum>>
  from()
  fmt()
}

Les bases non résolues restent identifiées; les signatures complètes ne sont pas reconstruites.

10. Référence

49 / 49 fichiers admissibles lus (139 dans l’arbre); 0 trop volumineux, 0 échec de lecture et 0 diagnostic de syntaxe.

Ce que couvre l’analyse

Les dossiers connus de dépendances et de compilation, les fichiers d’identifiants et les binaires sont exclus. La collecte couvre les README, les manifestes reconnus et les fichiers source pris en charge.

Les statistiques Linguist couvrent l’ensemble du dépôt et peuvent inclure d’autres langages.

12. Fichiers à lire 3

13. Glossaire

Dépôt

Les fichiers source, la configuration et l’historique versionné d’un projet.

README

Le document d’entrée du dépôt, qui présente généralement son rôle et son installation.

Dépendance

Une bibliothèque, un outil ou un service nécessaire à la compilation ou à l’exécution d’un composant.

API

Une interface par laquelle des composants logiciels échangent des requêtes et des résultats. Une API n’utilise pas nécessairement HTTP.

HTTP

Un protocole de requête et réponse utilisé par les navigateurs et services web. Une requête comprend une méthode, un chemin, des en-têtes et parfois un corps.

Conteneur

Un environnement de processus isolé créé à partir d’une image. Les données persistantes nécessitent un stockage hors de son système de fichiers temporaire.

Volume et montage de dossier

Un volume est un stockage géré par la plateforme de conteneurs ; un montage de dossier expose un chemin de l’hôte dans un conteneur.

Port publié

Un port de l’hôte associé au port d’un service dans un conteneur. Sa publication peut rendre le service accessible hors du réseau des conteneurs.

Interface en ligne de commande

Une interface textuelle où les commandes et arguments choisissent les opérations. Les codes de retour permettent aux scripts de détecter un succès ou un échec.

Compilation

Les étapes qui transforment les sources et dépendances en programme exécutable ou en livrable distribuable.

Base de données

Un système de stockage et d’interrogation de données structurées. Son schéma, ses règles d’accès et sa persistance déterminent comment l’application utilise ces données.

14. Références

  1. antoinebou12. (2026, 5 novembre). DasherControl. [Software repository] github.com.
  2. antoinebou12. (2026, 5 novembre). DasherControl: README. [Repository documentation] github.com.
  3. antoinebou12. (2026, 5 novembre). src/workspaces/handler.rs. [Source file] github.com.
  4. antoinebou12. (2026, 5 novembre). src/containers/docker.rs. [Source file] github.com.
  5. antoinebou12. (2026, 5 novembre). Cargo.toml. [Source file] github.com.
  6. Boucher, A. (2026, 23 octobre). DasherControl : un tableau de bord homelab organisé en espaces de travail. [Project article] antoineboucher.info.
  7. Boucher, A. (2021, 6 septembre). DasherControl. [Project article] antoineboucher.info.
  8. Boucher, A. (2026, 23 octobre). DasherControl : Un tableau de bord et ses trois frontières. [Project article] antoineboucher.info.

Les sources sans date de publication indiquent la date de leur dernière vérification, le 5 novembre 2026. Les liens des fichiers conservent la révision inspectée lorsqu’elle est disponible.