wsl-labs GitHub

🏗️ Arquitectura — WSL Container Center#

Versión: v1 Estado: 🟢 Activo Audiencia: 👥 Técnico, DevOps, administradores de sistemas Objetivo: Visión técnica del workspace y de cómo Windows controla contenedores wslc

📌 Objetivo de arquitectura#

wsl-labs es un panel para levantar y controlar contenedores con wslc, el motor de contenedores nativo de WSL (WSL 2.9+, tipo Docker). Es el equivalente de docker-labs pero usando wslc como motor. La arquitectura busca tres cosas:

📊 Estado arquitectónico#

CapaEstadoRol
🧭 Panel (dashboard-server)🟢 OperativoPuente Windows → wslc.exe y diagnóstico
🪟 Launcher Windows (Go)🟢 OperativoArranque del panel y apertura del navegador
🐳 Motor wslc🟢 OperativoConstruye imágenes y ejecuta contenedores (con redes)
📇 Catálogo (containers.config.json)🟢 Operativo12 casos verificados portados de docker-labs
📦 Instalador (Inno Setup)🟢 OperativoDistribución del launcher en Windows

🧱 Capas del sistema#

La frontera clave es el límite Windows → motor de contenedores. Todo lo que el usuario ve (navegador, launcher, panel) corre en Windows; los contenedores corren en el motor wslc. El panel cruza esa frontera ejecutando wslc.exe como proceso hijo.

flowchart LR
    subgraph WIN["🪟 Windows 11"]
        B["Navegador"]
        L["Launcher .exe (Go)"]
        D["🧭 Panel<br/>Node.js :9092"]
        WSLC["wslc.exe<br/>C:\\Program Files\\WSL"]
    end
    subgraph ENGINE["🐳 Motor de contenedores wslc"]
        subgraph NET["red wslc-pg-net"]
            APP["05 pg-app :8106"]
            PG["postgres"]
        end
        N["06 nginx :8104"]
        J["12 jenkins :8114"]
    end
    L --> D
    B --> D
    D -->|spawn| WSLC
    WSLC --> ENGINE
    APP <--> PG
    D -.->|"health HTTP<br/>IPv4 + IPv6"| ENGINE
Los casos multi-contenedor levantan sus contenedores sobre una red wslc dedicada, de forma que se resuelven entre sí por nombre (p. ej. PG_HOST=wslc-postgres). WSLC reexpone los puertos publicados en el localhost de Windows; el health-check y el acceso del usuario viajan por ese localhost.

🧠 Componentes principales#

1. 🧭 Panel#

AtributoDetalle
Componentedashboard-server/server.js
Puerto9092 (solo 127.0.0.1)
TecnologíaNode.js con módulo http nativo — sin dependencias npm

Responsabilidades:


2. 🪟 Launcher Windows#

AtributoDetalle
Componentelauncher/windows/main.go
TecnologíaGo 1.21+ (stdlib puro, sin dependencias externas)
Salidawsl-labs-launcher.exe

Responsabilidades:


3. 🐳 Motor de contenedores wslc#

AtributoDetalle
Motorwslc — motor de contenedores nativo de WSL (WSL 2.9+, preview)
EjecutableC:\Program Files\WSL\wslc.exe
Obtenciónwsl --update --pre-release

Responsabilidades:


4. 📇 Catálogo containers/containers.config.json#

AtributoDetalle
Componentecontainers/containers.config.json
RolFuente única de verdad del proyecto

Responsabilidades:

CategoríaCasosIntención
🌱 starter01 node · 03 python · 06 nginx · 10 goUn contenedor, imagen custom, arranque simple
🧩 platform02 LAMP · 04 redis · 05 postgres · 09 mongoApp custom + dependencia sobre una red wslc
🏗️ infra07 rabbitmq · 08 prometheus+grafana · 11 elasticsearch · 12 jenkinsImágenes públicas de infraestructura

🔄 Flujo de una acción (Construir / Levantar)#

El corazón del sistema es cómo una pulsación en el navegador termina cambiando el estado de un contenedor. Ejemplo: 📦 Construir → ▶ Levantar el caso 05 API + PostgreSQL.

flowchart TD
    A["Usuario pulsa 'Construir' en el panel"] --> B["dashboard.js → POST /api/wslc/build { id: 05 }"]
    B --> C["server.js valida id contra el catálogo"]
    C --> D["wslc build -t wsl-labs/pg-app:latest containers/05-postgres-api"]
    D --> E["Usuario pulsa 'Levantar' → POST /api/wslc/up"]
    E --> F["wslc network create wslc-pg-net"]
    F --> G["wslc run -d --name wslc-postgres --network wslc-pg-net postgres:15"]
    G --> H["wslc run -d --name wslc-pg-app --network wslc-pg-net -p 8106:8000<br/>-e PG_HOST=wslc-postgres wsl-labs/pg-app:latest"]
    H --> I["Health-check HTTP (IPv4 e IPv6) a localhost:8106"]
    I --> J["Panel muestra 🟢 running"]
Levantar es idempotente: por cada contenedor, el panel hace wslc stop + wslc rm de un contenedor previo con el mismo nombre antes de recrearlo. Así no se duplican contenedores al pulsar ▶ Levantar varias veces.

🩺 Modelo de health-check#

Un contenedor puede publicar el puerto por IPv4 (0.0.0.0) o por IPv6 (::). Un check que solo probara IPv4 marcaría "abajo" un caso que solo escucha por ::1. Por eso los checks prueban ambas familias (127.0.0.1 y ::1), igual que curl localhost. Todos los casos usan healthProtocol: http.

EstadoSignificado
🟢 runningContenedor principal en wslc list y HTTP responde (< 500)
🟡 degradedContenedor presente pero aún no responde (arrancando)
🔴 stoppedImagen lista, contenedor abajo
📦 missingImagen custom sin construir
🚫 unavailablewslc no disponible

🧩 Principios de diseño#

PrincipioDescripción
Fuente única de verdadCasos, imágenes, puertos y redes viven solo en containers.config.json
Cero dependenciasPanel en http nativo, launcher en stdlib de Go
Honestidad de estadoEl panel distingue missing de stopped — no miente sobre lo construido
IdempotenciaLevantar recrea limpio; bajar conserva la imagen para relanzar rápido
Local onlySin Kubernetes ni cloud: contenedores wslc en la máquina del usuario

📚 Documentos relacionados#

Fuente: docs/ARCHITECTURE.md