liquidstack / base
Proyecto base neutro para iniciar stacks consumidores de LiquidStack.
Package info
github.com/LiquidArtDevelopers/LIQUIDSTACK-BASE
Language:JavaScript
Type:project
pkg:composer/liquidstack/base
Requires
- php: >=8.1
- ext-dom: *
- ext-pdo_mysql: *
- liquidstack/blog: *
- liquidstack/commerce: *
- liquidstack/core: ^1.35
- liquidstack/webadmin: *
- phpmailer/phpmailer: ^6.9
- vlucas/phpdotenv: ^5.6
Requires (Dev)
- phpunit/phpunit: ^10.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v1.4.7
- v1.4.6
- v1.4.5
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.1
- v1.1.0
- v1.0.1
- v1.0.0
- dev-codex/create-webgl-scroll-animation-section-rkzdg2
- dev-revert-19-codex/create-webgl-scroll-animation-section-6ptzde
- dev-codex/create-webgl-scroll-animation-section-6ptzde
- dev-revert-17-codex/create-webgl-scroll-animation-section-lo42d8
- dev-codex/create-webgl-scroll-animation-section-lo42d8
- dev-revert-15-codex/create-webgl-scroll-animation-section-8qp130
- dev-codex/create-webgl-scroll-animation-section-8qp130
- dev-revert-13-codex/create-webgl-scroll-animation-section-zk6npy
- dev-codex/create-webgl-scroll-animation-section-zk6npy
- dev-revert-11-codex/create-webgl-scroll-animation-section-8s7mwd
- dev-codex/create-webgl-scroll-animation-section-8s7mwd
- dev-revert-9-codex/create-webgl-scroll-animation-section-6bj3lw
- dev-codex/create-webgl-scroll-animation-section-6bj3lw
- dev-revert-7-codex/create-webgl-scroll-animation-section-ulledj
- dev-codex/create-webgl-scroll-animation-section-ulledj
- dev-revert-5-codex/create-webgl-scroll-animation-section-8c8vaa
- dev-codex/create-webgl-scroll-animation-section-8c8vaa
- dev-revert-3-codex/create-webgl-scroll-animation-section-xqht81
- dev-codex/create-webgl-scroll-animation-section-xqht81
- dev-revert-1-codex/create-webgl-scroll-animation-section
- dev-codex/create-webgl-scroll-animation-section
This package is auto-updated.
Last update: 2026-09-24 14:48:59 UTC
README
BASE es el starter neutro para crear proyectos LiquidStack. Contiene la
estructura que pertenece al proyecto consumidor y selecciona, por defecto, el
paquete físico liquidstack/core junto con WebAdmin, Blog y Commerce.
CORE aporta y actualiza la parte común; BASE aporta una aplicación dummy lista para personalizar. AIWA, ARRO y los proyectos futuros deben poder nacer de este repositorio sin copiar código privado de otro cliente.
Qué contiene BASE
- La aplicación PHP/Vite, rutas y vistas públicas iniciales.
- Los shells personalizables del índice y del artículo de Blog.
- Los shells públicos de Commerce y sus recursos visuales gestionados.
- La configuración no secreta de WebAdmin, Blog y Commerce.
- Recursos, idiomas y showroom neutros para empezar un proyecto.
.env.examplecon valores de desarrollo deliberadamente públicos.example_liquidstack_dev.sql, un snapshot demostrativo de la base modular.- Pruebas de contrato propias del starter.
La base de datos, usuarios, correo, dominios, branding, navegación, copy y credenciales reales siempre pertenecen al proyecto consumidor. CORE no los inventa ni los toma de AIWA o ARRO.
Requisitos
- PHP 8.1 o posterior.
- Composer 2.
- Node
^20.19.0o>=22.12.0. - MySQL/MariaDB para el snapshot de ejemplo y para los módulos en este starter.
Los requisitos se separan por superficie:
- el runtime base debe satisfacer
composer check-platform-reqs --no-dev; - BASE exige
ext-domporque activa Blog yext-pdo_mysqlporque configura WebAdmin/Blog/Commerce sobre MySQL/MariaDB; Composer los comprueba al instalar; - WebAdmin necesita además el preflight PHP descrito abajo;
- Media añade sus propios codecs,
fileinfo, Imagick/AVIF y límites de subida; - las pruebas de desarrollo requieren las extensiones de PHPUnit indicadas por
composer check-platform-reqs, entre ellas DOM, JSON, libxml, tokenizer y XMLWriter; composer test:create-projecty el gate de release necesitanext-zippara inspeccionar el paquete real. Estos requisitos de tooling no deben confundirse con los del panel base en producción.
Preflight de PHP en Windows
XAMPP puede estar ejecutando MariaDB aunque Composer o npm run lad estén
resolviendo otro PHP desde PATH. Antes de instalar o diagnosticar, comprueba
el binario y su configuración efectivos:
where.exe php where.exe composer php --ini php -r 'echo PHP_BINARY, PHP_EOL;' php -r 'echo implode('','', PDO::getAvailableDrivers()), PHP_EOL;' php -r 'echo ini_get(''zend.exception_ignore_args'') ? ''On'' : ''Off'', PHP_EOL;' php -r 'echo in_array(''argon2id'', password_algos(), true) ? ''Argon2id disponible'' : ''Argon2id ausente'', PHP_EOL;' composer --version node --version npm --version
WebAdmin sobre MySQL/MariaDB necesita, como mínimo:
pdo_mysql;- soporte de Argon2id;
zend.exception_ignore_args=On.
Los requisitos de Media son adicionales: fileinfo, Imagick con AVIF y límites
de subida adecuados. Que falte uno de ellos no significa que haya que ejecutar
migraciones. Si php no es el binario correcto, se puede indicar al supervisor
sin imponer una ruta universal:
$env:LIQUIDSTACK_DEV_PHP_BINARY = 'C:\ruta\al\php.exe' npm run lad
C:\xampp\php\php.exe es solo un ejemplo frecuente. Tras cambiar de binario o
php.ini, reinicia npm run lad y repite composer liquidstack:doctor.
Crear un proyecto
La vía estable, con una etiqueta publicada y el paquete disponible en Packagist, es:
composer create-project liquidstack/base mi-proyecto --prefer-dist --remove-vcs
Si Packagist no está disponible o se necesita validar una etiqueta directamente desde GitHub, se puede declarar el repositorio VCS de forma explícita sin añadirlo al proyecto resultante:
composer create-project liquidstack/base mi-proyecto ` --repository='{"type":"vcs","url":"https://github.com/LiquidArtDevelopers/LIQUIDSTACK-BASE.git"}' ` --prefer-dist --remove-vcs
Al no indicar una versión, ambas órdenes eligen la etiqueta estable más
reciente. No añadas ^1.0 al comando en Windows: al atravesar composer.bat
puede llegar como 1.0 y fijar por error la release antigua v1.0.0.
dev-main queda reservado para probar cambios de BASE antes de una release y
no es una versión estable para proyectos de cliente.
El paquete distribuido no incluye el composer.lock interno de BASE.
create-project resuelve la versión más reciente de CORE compatible con la
restricción declarada, activa los selectores lógicos de WebAdmin, Blog y Commerce y genera
un composer.lock propio para el nuevo proyecto. El inicializador de BASE
desvincula además la identidad de la plantilla a partir del nombre de la carpeta.
No crea .env, no instala paquetes npm, no conecta con la DB, no migra, no crea
cuentas y no ejecuta onboarding. Después sigue este orden:
-
Entra en el directorio y revisa la identidad generada en
composer.jsonypackage.json. Inicializa el Git del cliente, añade su remoto y completa dominio,homepageysupportcuando existan; el inicializador no los inventa. -
Conserva versionados el
composer.lockrecién generado ypackage-lock.json; forman parte del punto de partida reproducible. Antes de configurar servicios, valida la instalación concomposer validate --strict --no-check-publish --no-check-allycomposer check-platform-reqs --no-dev. -
Crea el entorno privado de forma explícita:
Copy-Item -LiteralPath '.env.example' -Destination '.env'
-
Sustituye todos los valores demo, incluida la clave de seguridad. Elige una única conexión
LIQUIDSTACK_DB_*para WebAdmin/Blog/Commerce y configura SMTP antes del onboarding. Si vas a importar el snapshot, conserva sus dos emails bootstrap hasta reconciliar las cuentas por primera vez. -
Instala las dependencias frontend, incluido el paquete público de GSAP:
npm ci
GSAP no necesita token ni registro privado.
.npmrcpermanece ignorado como protección genérica por si un proyecto usa otro registro del operador.auth.jsontambién está ignorado y excluido del paquete: si Composer exige autenticación para otra dependencia, usaCOMPOSER_AUTHo el almacén global del operador. Nunca copies.npmrcoauth.jsonal repositorio ni al archive del cliente. -
Decide el destino antes de operar: DB local o remota segura, y snapshot de demo o DB vacía. Sigue exactamente una de las dos rutas documentadas abajo.
-
Ejecuta en orden
doctor, plan y dry-run. Si hay migraciones pendientes, detente, crea un backup y aplica solo el plan revisado; repite el dry-run hasta obtener cero pendientes. -
Sigue el cierre común documentado abajo: inicializa Media, arranca
npm run lad, usa el origen real que anuncie LAD para el onboarding, abre las dos invitaciones y realiza el smoke de/admin, Blog, Commerce y web pública. -
Ejecuta
composer test,npm run build, revisagit status/git diffy solo entonces crea el primer commit del proyecto personalizado.
El primer repositorio del cliente se prepara, sustituyendo la URL de ejemplo, con:
git init git branch -M main git remote add origin https://github.com/organizacion/mi-proyecto.git
Antes del primer git add, confirma que los secretos y outputs siguen
ignorados. git check-ignore debe devolver las tres rutas:
git check-ignore .env .npmrc public/.vite/manifest.json git status --short --ignored
Tras completar el smoke y revisar el lote:
git add -A git diff --cached --check git status --short git commit -m "chore: initialize client project" git push -u origin main
Desvincular la identidad de la plantilla
El hook one-shot de create-project usa el nombre de la carpeta para:
- sustituir
liquidstack/baseporliquid-art-developers/<slug-del-proyecto>; - crear una descripción neutra de proyecto de cliente y conservar la licencia
proprietary; - retirar
homepageysupportde BASE, porque todavía no conoce el dominio ni el repositorio del cliente; - cambiar
nameenpackage.jsony en las dos entradas raíz depackage-lock.json, sin volver a resolver dependencias; - retirar los scripts, herramientas y pruebas que sirven exclusivamente para publicar nuevas releases de BASE.
El inicializador falla cerrado si el directorio no produce un slug de paquete
válido y nunca crea .env, remoto Git, dominio, DB ni cuentas. Revisa después
el nombre humano y la descripción, añade homepage y support cuando conozcas
las URLs reales y configura el nuevo remoto Git. Después del primer smoke,
adapta README/CHANGELOG a la documentación del cliente, conservando en ella el
runbook operativo que siga necesitando el proyecto. No dejes enlaces de soporte
hacia BASE.
El nombre liquidstack/base identifica únicamente el artefacto de origen; no
es una dependencia de runtime ni debe conservarse como identidad del proyecto.
La vía normal no necesita flags adicionales. Si una creación excepcional se
hizo con --no-install --no-scripts, la identidad sigue siendo la de BASE
porque el hook no pudo ejecutarse. La recuperación segura y explícita es:
composer install --no-scripts composer project:init composer validate --strict --no-check-publish --no-check-all
project:init se elimina a sí mismo al terminar. No ejecutes create-project
solo con --no-install: el callback PHP necesita primero el autoload generado
por Composer.
Si se obtiene BASE mediante un clon manual para mantener la propia plantilla,
se usa composer install con su lock versionado. Para iniciar un cliente con
las versiones más recientes debe usarse create-project; así el lock interno
de BASE no se hereda accidentalmente.
Ownership y ciclo de vida
BASE es una plantilla de nacimiento, no una dependencia de ejecución. Tras crear el proyecto:
- el nuevo repositorio no depende de BASE ni recibe posteriores etiquetas de BASE;
- vistas, rutas,
.env, configuración de módulos, identidad, navegación, footer, copy, idiomas, datos y branding pasan a ser propiedad del proyecto; - CORE sigue siendo la dependencia actualizable y distribuye únicamente su
contrato gestionado mediante
composer update liquidstack/core; - los lockfiles se actualizan conscientemente en el proyecto consumidor y se revisan como cualquier otro cambio versionado;
- no se debe mezclar, copiar o fusionar una BASE nueva sobre un proyecto ya personalizado para intentar actualizarlo.
Así, una nueva etiqueta de BASE mejora los proyectos que nazcan después, pero no sustituye archivos project-owned de AIWA, ARRO ni de otros consumidores.
Valores demo: cambiar antes de desplegar
.env.example incluye estos defaults públicos para que BASE sea reproducible
en local:
El orden de sus grupos y el comentario breve Función + Ejemplo situado
justo encima de cada variable forman la plantilla canónica. create-project
los entrega sin pasos adicionales a todo proyecto nuevo. Un consumidor antiguo
puede conservar al final bloques project-owned o legacy, pero no debe alterar
el orden ni la explicación de las variables comunes.
| Variable | Valor demo |
|---|---|
LIQUIDSTACK_DB_NAME |
example_liquidstack_dev |
LIQUIDSTACK_DB_USER |
example_user |
LIQUIDSTACK_DB_PASSWORD |
example_pass |
LIQUIDSTACK_WEBADMIN_SECURITY_KEY |
clave pública marcada EXAMPLE_ONLY... |
| superadmin de sistema | aranaz@webda.eus |
| admin del sitio | aranaz@gmail.com |
La contraseña de DB y la clave WebAdmin no son secretos válidos de producción.
Cada proyecto debe rotarlas en su .env, que está ignorado por Git. Para crear
una clave base64url aleatoria de 43 caracteres con el PHP efectivo:
php -r '$b=random_bytes(32); echo rtrim(strtr(base64_encode($b), ''+/'', ''-_''), ''=''), PHP_EOL;'
También deben cambiarse RAIZ, DOMAIN, DOMAIN_URL, todos los MAIL_*, los
datos legales VITE_BUSINESS_*, CookieLad y cualquier ruta privada antes de un
despliegue real. https://example.com es un origen reservado, no un dominio de
producción.
Referencia rápida del entorno
El bloque SMTP canónico lo comparten los formularios y WebAdmin:
| Variable | Función | ¿Puede quedar vacía? |
|---|---|---|
MAIL_HOST |
Servidor SMTP | No, si se enviará correo |
MAIL_PORT |
Puerto SMTP, normalmente 465 o 587 | No |
MAIL_ENCRYPTION |
smtps o starttls |
No |
MAIL_USERNAME |
Cuenta autenticada y dirección From | No |
MAIL_PASSWORD |
Credencial SMTP | No |
MAIL_FROM_NAME |
Nombre visible del remitente | No |
MAIL_ADMIN |
Destinatario principal de formularios públicos | No, si hay formularios |
MAIL_LAD |
Copia oculta técnica opcional de formularios | Sí |
MAIL_LAD_BIS |
Segunda copia oculta técnica opcional | Sí |
MAIL_WEB |
Compatibilidad con código project-owned antiguo | Sí; BASE no la usa |
WebAdmin nunca usa MAIL_ADMIN, MAIL_LAD, MAIL_LAD_BIS o MAIL_WEB como
destinatarios de invitaciones o recuperaciones. Envía únicamente a la identidad
validada por cada flujo. BASE declara
LIQUIDSTACK_WEBADMIN_MAIL_TRANSPORT=smtp; el runtime mantiene el valor vacío
como compatibilidad y ambos usan el bloque anterior. local_capture_smtp se reserva a un
capturador loopback de desarrollo; solo en ese modo se completan
LIQUIDSTACK_WEBADMIN_SMTP_HOST, ..._PORT y los dos ..._MAIL_FROM_*.
Ejemplo local, suponiendo que ya existe un capturador externo escuchando solo en loopback y sin relay:
DEV_MODE=1 RAIZ=http://localhost:1309 LIQUIDSTACK_WEBADMIN_MAIL_TRANSPORT=local_capture_smtp LIQUIDSTACK_WEBADMIN_SMTP_HOST=127.0.0.1 LIQUIDSTACK_WEBADMIN_SMTP_PORT=1025 LIQUIDSTACK_WEBADMIN_MAIL_FROM_ADDRESS=no-reply@localhost.test LIQUIDSTACK_WEBADMIN_MAIL_FROM_NAME="WebAdmin local"
CORE no instala ni arranca ese capturador. Si no hay un proceso escuchando en el puerto indicado, las invitaciones y recuperaciones no se entregarán.
LIQUIDSTACK_WEBADMIN_SECURITY_KEY es un secreto permanente del proyecto, no
una contraseña de usuario. Debe ser única, aleatoria y estable. El sentinel
EXAMPLE_ONLY... tiene un formato aceptable, pero es deliberadamente público e
inseguro; hay que sustituirlo antes de cualquier uso real. Las
variables LIQUIDSTACK_WEBADMIN_SYSTEM_SUPERADMIN_EMAIL y
LIQUIDSTACK_WEBADMIN_SITE_ADMIN_EMAIL son dos identidades distintas usadas
una sola vez por el onboarding inicial. Reciben invitaciones para crear sus
contraseñas; escribirlas en .env no activa las cuentas ni convierte esos
correos en destinatarios automáticos de recuperación.
COOKIE_LAD_KEY identifica la configuración remota de consentimiento del
proyecto; si está vacía, el loader no se monta. COOKIE_LAD_COLOR personaliza
su color hexadecimal. El widget sigue siendo la fuente de verdad de las
preferencias y el proyecto no debe cargar analítica, marketing o embeds antes
del consentimiento correspondiente.
LIQUIDSTACK_WEBADMIN_MEDIA_STORAGE_ROOT puede quedar vacía en loopback, pero
si se usa Media en producción debe señalar un directorio absoluto, privado y
persistente fuera del release. LIQUIDSTACK_BLOG_SITEMAP_CACHE_ROOT solo es
obligatoria si se activa expresamente sitemap_cache.enabled=true; con la
caché desactivada puede quedar vacía. Git ignore evita versionar esos datos,
pero no impide que un despliegue borre una ruta mal situada: DB y storage deben
respaldarse, trasladarse y restaurarse como una unidad.
Commerce reutiliza esa misma biblioteca Media. No tiene un segundo storage.
LIQUIDSTACK_COMMERCE_INQUIRY_RECIPIENT es el buzón que recibe cada solicitud
de información; debe configurarse antes de activar la superficie pública.
LIQUIDSTACK_COMMERCE_PRIVACY_VERSION identifica el texto legal aceptado y se
guarda junto a la solicitud. Cambiar el aviso legal exige avanzar ese valor.
LIQUIDSTACK_COMMERCE_DEVELOPMENT_FIXTURES=1 habilita datos ficticios solo con
DEV_MODE=1; debe permanecer en 0 para cualquier uso real.
Elegir módulos
CORE es el único paquete físico publicado. WebAdmin, Blog y Commerce son selectores lógicos de esa misma versión:
| Selección directa | Resultado |
|---|---|
liquidstack/core |
CORE sin módulos internos |
liquidstack/webadmin |
CORE + WebAdmin |
liquidstack/blog |
CORE + WebAdmin + Blog |
liquidstack/commerce |
CORE + WebAdmin + Commerce |
Comandos de selección:
composer require liquidstack/core composer require liquidstack/webadmin composer require liquidstack/blog composer require liquidstack/commerce
El composer.json de BASE ya selecciona Blog y Commerce; ambos reutilizan el
mismo WebAdmin. Composer distribuye código, configuración inicial y recursos,
pero nunca aplica migraciones, inicializa Media, crea usuarios ni habilita la
tienda pública automáticamente.
README.LIQUIDSTACK.md, gestionado y actualizado por CORE, es el manual
operativo canónico del proyecto resultante. Separa los recorridos DB local a
producción, desarrollo contra una DB productiva vacía y activación posterior
de Blog o Commerce. Las secciones siguientes documentan además las
particularidades de BASE, su snapshot y su primer arranque.
Conexión de base de datos
| Escenario | DB | Media |
|---|---|---|
| Desarrollo local y promoción posterior | Trabaja en local y exporta la DB al destino. | Trabaja en local y copia el storage al destino junto con la DB. |
| Desarrollo contra DB remota | El .env apunta a la DB remota. |
Sigue siendo filesystem local: cópialo también al servidor. |
| Producción | Usa la conexión visible desde el hosting. | Configura una ruta absoluta, privada y persistente fuera del release. |
| DB heredada de otra instalación | Composer y las migraciones conservan sus datos demo anteriores. | El instalador demo solo copia ficheros; no crea assets ni referencias en la DB. |
BASE configura WebAdmin, Blog y Commerce con el perfil liquidstack en sus
ficheros App/config/modules/*.php. Los tres módulos comparten una sola
conexión y leen exclusivamente:
LIQUIDSTACK_DB_HOST=127.0.0.1 LIQUIDSTACK_DB_PORT=3306 LIQUIDSTACK_DB_NAME=example_liquidstack_dev LIQUIDSTACK_DB_USER=example_user LIQUIDSTACK_DB_PASSWORD=example_pass LIQUIDSTACK_DB_CHARSET=utf8mb4
liquidstack significa «DB de los módulos», no «DB de producción». El valor de
LIQUIDSTACK_DB_HOST determina el destino visible desde el proceso actual:
127.0.0.1olocalhostcuando la DB está en la misma máquina;- el extremo local de un túnel SSH/VPN cuando la DB está en otra red;
- un hostname interno del proveedor cuando el stack ya se ejecuta en producción.
Nombre, usuario, contraseña y charset se escriben una sola vez en el .env
privado. Los perfiles .env.development y .env.production pueden sustituir
el host y, si el endpoint lo exige, el puerto al ejecutar npm run lad o
npm run build; así no se duplican las credenciales. Revisa siempre el mensaje
de swap-env antes de ejecutar un comando que pueda escribir en DB.
Por ejemplo, si el desarrollo accede mediante una red privada y el hosting ve su propia DB en loopback, solo cambia esta clave entre perfiles:
# .env.development: endpoint accesible por VPN o red privada desde el equipo. LIQUIDSTACK_DB_HOST=db-proyecto.red-privada.test LIQUIDSTACK_DB_PORT=3307 # .env.production: PHP y MariaDB viven en el mismo hosting. LIQUIDSTACK_DB_HOST=127.0.0.1 LIQUIDSTACK_DB_PORT=3306
Una DB de producción vacía sigue la opción B. Si ya contiene el esquema y los
datos promovidos desde local, no se importa el snapshot ni se adopta por
intuición: se valida con doctor y migrate --dry-run antes de escribir.
CORE no configura todavía opciones PDO de TLS/CA. No conectes el portátil directamente a un MySQL/MariaDB público sin una red confiable y cifrada. Para trabajar contra producción desde local usa preferentemente VPN o túnel SSH y limita el usuario SQL; rota cualquier credencial temporal después del corte.
El perfil alternativo shared y las variables BBDD_* existen solo por
compatibilidad con aplicaciones antiguas que tienen una zona privada de negocio
propia. No representan desarrollo/producción. Un proyecto que conserve esa zona
puede tener ambos bloques porque son dos dominios de datos distintos; BASE no
incluye esa aplicación legacy. Nunca pongas la misma DB modular en ambos
namespaces.
La creación de la DB y del usuario SQL se hace fuera del repositorio. BASE no
incluye CREATE USER, contraseñas del servidor ni GRANT. Al crear una DB que
recibirá el snapshot, usa utf8mb4 con cotejamiento
utf8mb4_unicode_ci; el propio SQL declara ese contrato en sus tablas.
Opción A: importar el snapshot demo
El fichero raíz example_liquidstack_dev.sql contiene:
- el esquema resultante del catálogo incluido en esta release de BASE;
- roles, capacidades y semillas técnicas;
- las dos cuentas iniciales en estado de invitación, sin contraseña;
- categorías, etiquetas y cuatro artículos Matrix de ejemplo, cada uno en español y euskera, con composición V2, imágenes y vídeo.
No contiene datos de sesiones, tokens de invitación, outbox, rate limits, analítica, auditoría o credenciales. También excluye cestas, solicitudes, contactos y agregados sociales de Commerce. Tampoco contiene hashes de contraseña, usuarios SQL ni permisos del servidor. Sus tablas vacías sí forman parte del esquema. El SQL es una fotografía reproducible para BASE; las migraciones de CORE siguen siendo la fuente canónica. Impórtalo únicamente en una DB de desarrollo vacía: el dump reconstruye sus tablas y no debe ejecutarse sobre datos que se quieran conservar.
Volver a ejecutar create-project, actualizar CORE, aplicar migraciones o
instalar los AVIF demo no refresca una DB importada anteriormente. Si reutilizas
una DB de una versión previa de BASE, conservará su snapshot antiguo. Para
obtener los posts y referencias Media actuales, sustituye solo una DB vacía o
desechable —después de respaldarla— importando el example_liquidstack_dev.sql
de esta misma versión. El comando liquidstack:demo-blog-media:install copia
ficheros, pero no crea assets ni referencias en la DB.
Ejemplo de importación desde PowerShell, suponiendo que mysql.exe está en
PATH:
$env:MYSQL_PWD = 'example_pass' mysql.exe --host=127.0.0.1 --user=example_user ` --database=example_liquidstack_dev ` --execute='SOURCE example_liquidstack_dev.sql' Remove-Item Env:MYSQL_PWD
Si se usa XAMPP, C:\xampp\mysql\bin\mysql.exe puede ser la ruta local, pero
no es un requisito universal.
Después de importar, valida primero que el snapshot coincide con el catálogo instalado:
composer liquidstack:doctor --format=json composer liquidstack:migrate --plan --format=json composer liquidstack:migrate --dry-run --format=json
No continúes con Media ni onboarding mientras el dry-run muestre pendientes o bloqueadores. Si CORE es posterior al snapshot, revisa el plan, crea un backup, aplica únicamente las migraciones nuevas con el comando confirmado de la opción B y repite el dry-run hasta obtener cero pendientes. Entonces sigue el cierre común.
Las cuentas del snapshot no tienen acceso utilizable y el bootstrap permanece
deliberadamente en estado pending. Durante esta primera reconciliación, las
variables bootstrap deben conservar exactamente aranaz@webda.eus y
aranaz@gmail.com. onboard completa las filas técnicas, genera las
invitaciones y contacta el SMTP: puede enviar mensajes reales. Abre ambos
enlaces y establece las contraseñas. Hasta entonces «He olvidado mi contraseña»
no envía correo porque una identidad invited todavía no tiene credencial que
recuperar.
No sustituyas este paso por bootstrap + dispatcher salvo en una recuperación
operativa deliberada. Después de activar las dos cuentas, la DB es la fuente de
verdad y las identidades se administran desde WebAdmin, no editando el snapshot
ni cambiando las variables bootstrap.
Opción B: comenzar con una DB vacía local o de producción
Con una DB vacía y el .env ya configurado, usa este orden:
composer liquidstack:doctor --format=json composer liquidstack:migrate --plan --format=json composer liquidstack:migrate --dry-run --format=json
Después de revisar el plan y crear un backup verificable de la DB, aplica las migraciones seguras:
composer liquidstack:migrate --apply --yes --format=json composer liquidstack:migrate --dry-run --format=json
Solo si el plan identifica realmente migraciones destructivas, repite el
--apply autorizado añadiendo --allow-destructive --backup-confirmed. No
uses esos flags de forma preventiva.
No continúes hasta que el segundo dry-run confirme cero pendientes y ningún
bloqueador. migrate --apply es una mutación y exige autorización consciente;
Cuando sea necesario, --backup-confirmed declara que el backup ya existe, no
lo crea. La ausencia
de un driver PHP o de una directiva de runtime no se corrige migrando. En
diagnóstico no se modifican automáticamente php.ini, .env, PATH ni la DB.
Las migraciones crean esquema e infraestructura, no artículos de ejemplo. Esos datos solo proceden del snapshot demo o de entradas creadas desde WebAdmin. Cuando el esquema esté al día, sigue el cierre común.
Cierre común: Media, onboarding y smoke
Con el dry-run a cero, inicializa el storage privado de Media:
composer liquidstack:media:init --yes --format=json
Solo si importaste example_liquidstack_dev.sql, instala a continuación los
cuatro assets que referencia su Blog demo:
composer liquidstack:demo-blog-media:install
El instalador es explícito e idempotente: valida los AVIF versionados, exige un storage Media ya inicializado y no conecta a la DB ni sobrescribe assets. No lo ejecutes sobre una DB vacía, que no contiene los posts demo. Si una misma DB remota se sirve desde desarrollo y producción, ejecuta el comando una vez en cada entorno: comparten filas, pero cada uno conserva su propio storage.
Arranca el proyecto en una primera consola y conserva el proceso abierto:
npm run lad
LAD busca puertos libres; por eso no hay que asumir 1309. Copia el origen PHP
exacto que anuncie, abre una segunda consola y úsalo temporalmente al crear los
enlaces de activación. Sustituye 1310 por el puerto real:
$env:RAIZ = 'http://localhost:1310' composer liquidstack:webadmin:onboard --yes --format=json composer liquidstack:doctor --format=json
Mantén esa segunda consola abierta. El override solo la afecta a ella y evita
generar invitaciones hacia un puerto distinto. Los enlaces localhost solo se
abren en esa misma máquina.
En una instalación ya desplegada, el onboarding debe usar el origen HTTPS real
y accesible del proyecto, no un puerto local ni el valor example.com.
Abre las dos invitaciones, define las contraseñas y comprueba /admin, Blog y
la web pública. En la segunda consola, repite onboard; al verificar el par
2/2 no debe duplicar usuarios ni invitaciones. Deja entonces vacías las dos
variables bootstrap en el .env privado, ejecuta el doctor final y retira el
override:
composer liquidstack:webadmin:onboard --yes --format=json composer liquidstack:doctor --format=json Remove-Item Env:RAIZ
La DB pasa a ser la fuente de verdad. Un bootstrap_ready=false posterior
puede ser una advertencia no bloqueante sobre la capacidad de iniciar otra DB;
no invalida el 2/2 ya verificado.
media:init y onboarding son mutaciones deliberadas. No se ejecutan desde
composer install, composer update ni desde una tarea de diagnóstico.
Producción: DB vacía o promoción con datos
- Para una DB productiva nueva y vacía, configura el perfil de producción y sigue la opción B en el entorno que realmente vaya a servir la aplicación.
- Para trasladar contenido existente, respalda y restaura conjuntamente la DB
completa —incluida
ls_module_migrations— y el storage Media. CambiarLIQUIDSTACK_DB_*o la ruta de storage no mueve ni adopta datos. - Antes de escribir en el destino, verifica credenciales, origen HTTPS,
storage persistente,
doctor, plan y dry-run. Conserva una copia recuperable hasta terminar el smoke. - El despliegue debe preservar el storage fuera del release;
.gitignoreno protege frente a limpiezas, extracciones o sincronizaciones con borrado.
Desarrollo local
npm run lad
El supervisor busca el primer puerto PHP libre desde 1309 y el primer puerto
Vite libre desde 5173. Si otro stack ocupa esos puertos, avanza a 1310,
5174, etc. No persiste el número elegido y separa las cookies privadas por una
identidad opaca del proyecto; varios stacks pueden permanecer autenticados a la
vez aunque los puertos cambien.
Overrides opcionales:
LIQUIDSTACK_DEV_APP_PORT: fuerza un puerto PHP exacto y falla si está ocupado.LIQUIDSTACK_DEV_VITE_PORT: fuerza un puerto Vite exacto y falla si está ocupado.LIQUIDSTACK_DEV_PHP_BINARY: elige el PHP del supervisor.
En producción la separación se deriva del dominio/proyecto, no de un puerto.
Los perfiles .env.development y .env.production solo deben incluir claves
que cambian entre entornos. scripts/swap-env.mjs fusiona esas claves en
.env; no borra las credenciales privadas que ya existen. BASE incluye
LIQUIDSTACK_DB_HOST=127.0.0.1 en ambos como default seguro. Si desarrollo debe
usar una DB remota mediante túnel/VPN, cambia únicamente el host del perfil de
desarrollo; conserva el endpoint visto desde el hosting en producción. El
script informa de las claves aplicadas y no selecciona una DB por DEV_MODE.
El cambio de perfil es físico: npm run build aplica .env.production sobre
.env y deja esos valores activos al terminar. Antes de volver a ejecutar
doctor, migraciones o comandos editoriales desde local, recupera el perfil
esperado con npm run lad o node scripts/swap-env.mjs development y verifica
en el mensaje del script y en doctor que el host es el previsto.
Blog público y WebAdmin
BASE deja preparados:
/adminpara WebAdmin;/es/blogy/eu/blogpara el índice público;App/views/blog.phpcomo shell project-owned del índice;App/views/blog-article.phpcomo shell project-owned de cada artículo;App/config/modules/blog.phppara paths, paginación, sitemap y vista pública;src/scss/blog.scssysrc/js/blog.jspara la presentación del proyecto.
Las rutas privadas de los módulos pertenecen a los providers de CORE y no se
duplican en App/config/routes/get.php. Las rutas privadas propias del proyecto
deben declarar 'sitemap' => false.
CookieLad permanece desactivado mientras COOKIE_LAD_KEY esté vacío. El shell
de artículo usa los includes globales del proyecto, de modo que navegación,
footer y consentimiento pueden mantenerse coherentes con el resto de la web.
Commerce: activo por defecto
BASE instala el selector liquidstack/commerce y sus 29 ficheros canónicos,
con App/config/modules/commerce.php en public.enabled=true. Por ello Tienda
aparece en la navegación de un proyecto nuevo; cada consumidor puede cambiarlo
a false si decide no usar el módulo público. Los paths de catálogo y lista de
interés se derivan de App/config/langs.php: hay
segmentos propios para español, euskera e inglés y un fallback neutral para
otros locales. No dupliques esas rutas en App/config/routes/get.php ni en
App/config/rutas.js; el provider de CORE las resuelve después de las rutas
estáticas del proyecto.
El showroom incorpora la categoría /es/showroom/commerce (y su equivalente
por idioma) con los tres recursos públicos y veinte prendas ficticias inspiradas
en Matrix. Son fixtures de presentación declaradas exclusivamente en
App/views/showroom/_commerce.php: sirven para probar tarjetas, búsqueda,
taxonomías, ficha y lista de interés, pero nunca se insertan en la DB, aparecen
en WebAdmin ni alimentan el catálogo público. Al crear productos reales no hay
que ocultarlas ni borrarlas porque ambas fuentes están totalmente separadas.
La navegación sigue siendo propiedad del proyecto. BASE compone sus enlaces en
App/config/public-navigation.php: Blog se muestra siempre y Tienda se añade
solo cuando commerce.php tiene public.enabled=true, usando sin reconstruir
el path exacto de public_paths para el locale activo. Un proyecto consumidor
ya existente debe adoptar expresamente ese helper y sus claves localizadas en
sus propios _nav.php, _footer.php y catálogos; actualizar CORE no sobrescribe
automáticamente menús ya personalizados.
Commerce comparte con WebAdmin la conexión LIQUIDSTACK_DB_*, el transporte
SMTP y la biblioteca Media. Las tres migraciones iniciales son
0001_commerce_catalog, 0002_commerce_inquiries y
0003_commerce_capabilities. Revísalas y aplícalas con el flujo común de
migraciones anterior; no necesitan un procedimiento distinto para Commerce:
composer liquidstack:doctor --format=json composer liquidstack:migrate --plan --format=json composer liquidstack:migrate --dry-run --format=json # Crea y verifica el backup de DB + Media antes de autorizar la escritura. composer liquidstack:migrate --apply --yes --format=json composer liquidstack:migrate --dry-run --format=json
Añade --allow-destructive --backup-confirmed únicamente si el plan real
informa migraciones destructivas. Esos flags no crean el backup ni deben
usarse por defecto.
Después configura el destinatario de consultas, la versión de privacidad y
SMTP; inicializa Media por el procedimiento común y crea productos, categorías,
etiquetas, atributos y sus variantes de idioma desde WebAdmin. El modo inicial
es exclusivamente inquiry: la venta/pago permanece visible como capacidad
futura, pero no es seleccionable. La lista de interés usa una cookie necesaria
HttpOnly, no localStorage, y envía dos correos desde un outbox propio: acuse al
visitante y aviso al destinatario administrativo.
En producción programa el dispatcher one-shot desde el scheduler del hosting, con una frecuencia acorde al proyecto:
composer liquidstack:commerce-mail-dispatch --limit=20
El comando procesa un lote y termina; Composer no instala cron ni envía correo
durante install o update. Antes de publicar valida traducciones, URLs,
política de privacidad, catálogo, ficha, lista de interés, correos y sitemap.
Cambiar public.enabled a false mantiene cerrada toda la superficie pública
aunque el módulo siga disponible en WebAdmin. El contador
«X solicitudes de información» también nace desactivado: habilita
social_proof.enabled=true solo como opt-in tras decidir que ese dato debe ser
público y revisar su umbral minimum_count.
Qué personalizar en cada proyecto
Como mínimo:
.env, perfiles y dominios;- idiomas y slugs públicos;
App/config/routes/get.php,post.phpyrutas.js;App/config/modules/blog.php,webadmin.phpycommerce.php;- navegación, footer, logos, favicon y datos legales;
- copy y metadatos de cada idioma;
src/scss/_config.scss,_global.scssy estilos de página;- correo, CookieLad, usuarios, medios y contenido;
- estrategia de backup, cron/dispatcher y despliegue.
src/scss/_config.scss conserva el contrato completo de colores. Los recursos
estándar de CORE usan color00 a color03; color04 y posteriores quedan
disponibles para el tema del consumidor.
Actualizar CORE en un consumidor
Para actualizar todo el código físico LiquidStack ya seleccionado:
composer require "liquidstack/core:^1.35" --with-all-dependencies
No hace falta actualizar Blog, WebAdmin o Commerce por separado: comparten la
versión de CORE. El caret se conserva para recibir las siguientes releases
estables 1.x. composer update sin paquete también puede actualizar PHPMailer,
Dotenv, PHPUnit y cualquier otra dependencia; úsalo solo cuando quieras revisar
todo el lock.
Para separar la resolución de dependencias de la escritura de ficheros gestionados y revisar el lote antes de aplicarlo:
composer require "liquidstack/core:^1.35" --with-all-dependencies ` --no-plugins --no-scripts composer liquidstack:sync --plan composer liquidstack:sync --dry-run --format=json composer liquidstack:sync --apply --plan-hash=sha256:... --yes composer install
El hash solo sirve para el estado exacto que produjo el dry-run. Si CORE, un
destino o el estado cambian, sync.plan_changed obliga a revisar un plan nuevo.
El composer install final ejecuta las fases deliberadamente separadas del
sync de ficheros: contrato SCSS, Vite, dependencias frontend y skills.
La sincronización de CORE es aditiva y se apoya en
.liquidstack/core/managed-files.json:
- añade ficheros nuevos;
- actualiza copias canónicas reconocidas;
- conserva personalizaciones locales desconocidas;
- no elimina de forma global ficheros del consumidor;
- fusiona catálogos de idioma sin sustituir valores locales existentes.
El manifiesto gestionado debe versionarse en cada consumidor. Tras actualizar:
npm install composer liquidstack:doctor composer liquidstack:migrate --plan composer liquidstack:migrate --dry-run composer test npm run build git diff --check git status --short
Revisa siempre el diff sincronizado antes de aplicar migraciones o publicar.
Build y comprobación final
Antes del primer build sustituye el dominio reservado de .env.production.
Después:
npm run build composer test
El build genera el sitemap multilingüe y los assets en public/assets; no crea
una carpeta dist adicional. El starter se distribuye sin
public/.vite/manifest.json ni bundles compilados para no fijar hashes
obsoletos: después de instalar las dependencias con npm ci, ejecuta
npm run build. Hasta entonces doctor puede avisar de que falta el manifest;
no es una razón para migrar la DB.
El cierre funcional de un proyecto con Blog/WebAdmin/Commerce debe comprobar como usuario real, al menos:
- home, navegación, footer, cookies y cambio de idioma;
- login, logout y concurrencia con otros stacks;
- listado, creación, edición, publicación y previsualización de posts;
- categorías, etiquetas, SEO, index/follow y acciones del listado;
- biblioteca de medios y límites del servidor;
- índice y artículo públicos, metadatos, sitemap y 404;
- gestión Commerce, catálogo, ficha, filtros, lista de interés, emails y
contador de solicitudes, cuando
public.enabled=true; - responsive y consola/red del navegador sin errores inesperados.
Releases de BASE
Esta sección se aplica únicamente al checkout mantenedor de BASE. El inicializador la conserva como referencia documental, pero elimina del proyecto cliente los scripts, herramientas y tests citados aquí; no intentes publicar un cliente con el release gate de la plantilla.
BASE tiene un ciclo SemVer independiente de CORE. Sus etiquetas describen el punto de partida de proyectos nuevos; no se instalan ni se mezclan sobre proyectos ya nacidos.
Publicar BASE: bloque corto para PowerShell
Después de confirmar los cambios y dejar el árbol limpio, ejecuta únicamente:
composer release
Antes de pegarlo, mueve las notas de Unreleased a una única sección fechada
## [X.Y.Z] - AAAA-MM-DD, confirma los cambios con Git y comprueba que
git status --short no muestre nada. Igual que en CORE, composer release
detecta la versión desde el changelog y solicita confirmación y descripción.
Si falta una versión pendiente o hay varias, se detiene antes del gate.
El gate exige el árbol limpio, comprueba rama, remoto, changelog, locks y
etiqueta; después valida Composer, ejecuta las pruebas y crea un consumidor
temporal, instala npm, audita y construye el archive. Solo al terminar publica
main y la etiqueta con un push atómico. La descripción solicitada pertenece
al tag y no reescribe el commit. No hace falta ejecutar git push por separado;
si ya lo hiciste, el gate también lo admite. Nunca copies aquí la versión de CORE:
por ejemplo, BASE v1.2.0 y CORE v1.32.0 son releases independientes.
composer test:create-project usa el archive local antes de publicar. Tras
crear la etiqueta se puede repetir contra GitHub y, cuando el paquete esté
registrado, contra Packagist:
composer test:create-project -- --source=vcs composer test:create-project -- --source=packagist
Ambos modos externos ejecutan un create-project real con --prefer-dist y
--remove-vcs; el fallback VCS usa el remoto canónico de BASE. Si no se indica
--version, omiten ese argumento y Composer prueba la última release estable.
--version=v1.4.2 permite comprobar una etiqueta exacta. No ejecutan
migraciones, Media ni onboarding.
Para diagnosticar sin publicar se puede usar
composer release -- --dry-run. No es un paso obligatorio:
repite el gate completo y puede tardar varios minutos.
El alta inicial de liquidstack/base en Packagist es un paso externo y
separado del gate Git. Tras registrarlo, Packagist descubre las etiquetas del
repositorio; el fallback VCS documentado en «Crear un proyecto» permite validar
GitHub de forma independiente.
Marcar además el repositorio como GitHub Template es compatible y opcional: no
cambia el paquete ni el flujo create-project.
Fuente de verdad operativa
Las instrucciones especializadas se distribuyen en .codex/skills. Para
desarrollo, módulos y promociones hacia CORE deben usarse las skills
dev-stack, liquidstack-module-operations y
liquidstack-resource-migration; este README explica el arranque del starter y
no sustituye sus contratos de trabajo.