Mise-en-place: tu primera IDP local

Objetivos del capítulo
  • Preparar el entorno de trabajo (Node, pnpm, Docker).

  • Hacer bootstrap de Backstage con @backstage/create-app.

  • Arrancar la cocina en local y ver la sala en el navegador.

  • Cargar la primera entidad del catalog.

Antes de empezar: mise-en-place

El :apéndice C es nuestro recetario del cocinero. Aquí asumimos que ya tienes Node 20+, pnpm 9+ y Docker 24+ funcionando. Si no, vuelve al :apéndice A y prepara el mise-en-place desde cero.

Verificación rápida

Abre una terminal y verifica:

node --version        # v20.x o superior
pnpm --version        # 9.x o superior
docker --version      # 24.x o superior
docker compose version  # v2.x

Si todo responde, estás listo. Si no, vuelve al :apéndice A.

Bootstrap: el asistente de cocina

Backstage trae un asistente de bootstrap llamado @backstage/create-app. Es el equivalente al instalador del restaurante: deja lista la cocina con la vajilla, los fogones y los cuchillos de serie. No necesitas entender cada rincón para empezar, pero conviene saber qué deja y por qué.

Lo que vamos a ejecutar:

Unresolved directive in chapters/cap-03-mise-en-place-primera-idp-local.adoc - include::../../chapters/chapter-03-bootstrap/scripts/01-create-app.sh[tag=bootstrap-script]
Lo que crea el bootstrap
  • Una carpeta backstage-sazon/ con un monorepo pnpm.

  • Tres paquetes: packages/app (frontend), packages/backend (backend), plugins/ (vacío al inicio).

  • Un app-config.yaml con valores por defecto.

  • Un README que cuenta lo mínimo para arrancar.

Acerca de la versión

Fijamos BACKSTAGE_VERSION a una release estable en :apéndice A. El bootstrap clona el template con ese tag. Si más adelante actualizas, basta con un git pull del upstream y resolver los conflictos (ver :cap-15).

El monorepo: estructura

El template de Bootstrap genera un monorepo pnpm con esta forma:

Estructura del monorepo
Failed to generate image: Could not find the 'mmdc' executable in PATH; add it to the PATH or specify its location using the 'mmdc' document attribute
flowchart TB
  Root[backstage-sazon/] --> PkgApp[packages/app/]
  Root --> PkgBackend[packages/backend/]
  Root --> Plugins[plugins/]
  Root --> PkgConfig[packages/app-config/]
  Root --> Tsconfig[tsconfig.json]
  Root --> Pkg[package.json]
  Root --> Catalog[examples/]
  • packages/app/ — el frontend React con Material UI.

  • packages/backend/ — el backend Node con Express.

  • plugins/ — donde crearás tus plugins propios.

  • examples/ — entidades de ejemplo que el template deja.

  • packages/app-config/ — opcional, para separar configs.

Arrancar la cocina

Una vez generado, entramos y arrancamos:

Unresolved directive in chapters/cap-03-mise-en-place-primera-idp-local.adoc - include::../../chapters/chapter-03-bootstrap/package.json[tag=dev-script]

El frontend abre en http://localhost:3000 y el backend en http://localhost:7007. En el navegador verás la sala del restaurante vacía: el shell, el menú lateral, sin componentes en el catálogo todavía.

No te asustes si durante el primer arranque el backend tarda unos segundos en responder: está aplicando migraciones de la base de datos en SQLite. Cuando la cocina termina de preparar la mise-en-place, sirve en el puerto 7007.

La primera entidad del catalog

Antes de seguir, vamos a poblar el catálogo con un único Component. Esto demuestra que el catálogo está vivo y que cualquier cosa que registremos en él aparecerá en la sala.

¿Qué es una entidad?

Una entidad es un objeto JSON/YAML que describe algo del mundo del developer: un Component (servicio), un API, un Resource (DB), un System (agrupación), un Domain, etc. La estructura sigue el formato de :code:`Entity` de backstage.io. Se almacena en el catalog y se ingesta desde archivos locales, GitHub o APIs externas.

La primera entidad es un Component que representa la web de Sazón Foods:

Unresolved directive in chapters/cap-03-mise-en-place-primera-idp-local.adoc - include::../../chapters/chapter-03-bootstrap/entities/sazon-web/catalog-info.yaml[tag=first-entity]
¿Qué acabas de hacer?
  • Has creado el metadata.yaml con el name, title, description y tags.

  • Has añadido el spec.type: website para que el catalog lo renderice como web.

  • Has declarado el spec.system: sazon-restaurant (lo crearemos en el :cap-04).

  • Has marcado el owner (que es una entidad Group que el template ya creó por defecto).

Para que la entidad entre en el catálogo, basta con referenciarla en app-config.yaml:

catalog:
  locations:
    - type: file
      target: ../../examples/sazon-web/catalog-info.yaml

Tras reiniciar el backend, refresca la UI y verás sazon-web en el menú Catalog.

¿Por qué usamos el catálogo desde el primer momento?

Tres razones:

  1. Es la superficie visible del producto: lo primero que ven los developers.

  2. Da contexto al resto de plugins: notificaciones, scaffolder, techdocs se anclan a entidades.

  3. Es el lugar donde aterrizan los datos: si algo no está en el catálogo, no existe.

Example 3. Receta del capítulo
  1. Verifica Node 20+, pnpm 9+, Docker 24+.

  2. Ejecuta npx @backstage/create-app@<version> --path backstage-sazon.

  3. Entra al directorio y arranca con pnpm install && pnpm dev.

  4. Carga el catalog con tu primer Component.

  5. Verifica que la sala muestra sazon-web y su System.

Resumen

  • El bootstrap te da un monorepo pnpm con tres paquetes base.

  • El primer arranque aplica migraciones y tarda unos segundos.

  • Una entidad Component se registra en el catalog mediante un archivo YAML.

  • El catalog es la superficie visible de Backstage y la pieza central.

Glosario del capítulo

bootstrap

Asistente que genera un monorepo Backstage listo para arrancar.

monorepo

Repositorio único con varios paquetes coordinados por pnpm.

entidad

Objeto JSON/YAML que describe un Component, API, Resource, System, etc.

SQLite

DB embebida que usa Backstage en dev por defecto. Producción: Postgres.

Próximo capítulo

Catalog en serio: estructura, relaciones y discovery —de la primera entidad a un catálogo entero: cinco componentes, relaciones, e ingesta desde GitHub.