Saltar al contenido
pcreative Commerce

Instalación

pcreative Commerce se descarga en un .zip desde pcreativecommerce.dev y se instala en tu servidor.

pcreative Commerce se descarga en un .zip desde pcreativecommerce.dev y se instala en tu servidor. Arrancar y configurar son cosas distintas: arrancar es un comando; configurar se hace siempre en el asistente del navegador, sin terminal.

Lo que necesitas: una máquina Linux con Docker y Docker Compose (el instalador los pone si faltan), 2 GB de RAM y al menos 12 GB libres de disco — con menos, el instalador no sigue. Con menos de 4,5 GB de RAM y sin swap, crea un fichero de intercambio de 4 GB (/swapfile) antes de arrancar, porque el pico de la construcción no tiene otro sitio donde caer. No funciona en hosting compartido: hace falta Node y PostgreSQL, y esos hostings no dan ninguno de los dos.


Instalar

Junto al paquete se descarga el instalador. En tu servidor:

sh instalar.sh pcreative-commerce-*.zip

Comprueba la huella del paquete si el fichero .sha256 está al lado, comprueba la máquina, instala lo que falte (Docker incluido), descomprime el paquete en su carpeta, crea el .env a partir de .env.docker.example con una contraseña aleatoria para la base de datos y arranca cinco piezas: Postgres, el backend, el panel, el panel del vendedor y la tienda. Al terminar te dice dónde entrar y te avisa de que termines la instalación ya.

Los programas vienen ya construidos: tu máquina no compila nada. La primera vez tarda unos minutos porque descarga las dependencias del backend; después arranca en unos diez segundos. El backend crea el esquema si la base está vacía —o aplica lo que falte si no— y prepara la tienda en cada arranque, sin miedo a repetirse. Lanzar el instalador por segunda vez no borra datos: actualiza lo que ya está en marcha.

A mano

Si prefieres no usar el instalador, dentro de la carpeta descomprimida:

cp .env.docker.example .env
# pon POSTGRES_PASSWORD en el .env (solo letras y números)
docker compose up -d --build

En el paquete el fichero se llama docker-compose.yml; en el repositorio de código ese mismo fichero es docker-compose.full.yml, así que allí cada orden lleva -f docker-compose.full.yml.

Instálala en cuanto arranque

Al abrir el panel te recibe el asistente directamente. No hay código que escribir ni nada que desbloquear: pcreative Commerce es gratis, y la primera pantalla no va a hacer como si no lo fuera.

Lo que eso significa conviene decirlo claro. Mientras no haya ninguna cuenta de administrador, la primera persona que llegue al asistente es la que se queda la tienda. Es el mismo trato que en cualquier otro programa de tienda que se instala desde el navegador, y lo único que cierra esa ventana es terminar el asistente: a partir de ahí, las cinco rutas de instalación contestan «esta tienda ya está instalada» y nada más. Así que instálala en cuanto termine el instalador, no mañana.

Si entre arrancarla y sentarte delante del navegador va a pasar un rato, no dejes el panel a la vista de internet hasta haber terminado: el instalador ya deja todos los puertos en 127.0.0.1, así que llega por un túnel SSH (ssh -L 7001:localhost:7001 tuusuario@tuservidor) en lugar de publicarlo antes e instalar después. Si quieres estar seguro del todo, corta la ruta en tu proxy hasta haber creado tu cuenta.

El asistente son las comprobaciones, el nombre de la tienda, tu cuenta y, si quieres, un catálogo de ejemplo para ver el circuito completo funcionando.

Si esa ventana te inquieta —y en un servidor con nombre público debería—, sáltate el asistente entero con lo que viene justo debajo.

Instalarla sin asistente (lo recomendado con Docker)

Mejor que darse prisa es no tener ventana en la que darse prisa. Pon el administrador en la configuración y la tienda se instala sola en el primer arranque: crea la cuenta, le pone a la tienda el nombre de STORE_NAME y cierra la instalación antes de que haya nada escuchando a ningún navegador. El asistente ya ni se abre, y lo dice.

PCC_ADMIN_CORREO=tu@tudominio.com
PCC_ADMIN_CONTRASENA=al-menos-diez-caracteres
PCC_ADMIN_NOMBRE=Ana
PCC_ADMIN_APELLIDOS=Ruiz

La contraseña, en un fichero y no en el .env. Cada una de esas variables tiene una gemela _FILE que lleva la RUTA de un fichero del que se lee el valor, que es para lo que están los secretos de Docker. Lo que está en el .env está también en docker inspect; lo que está en un secreto, no:

secrets:
  clave_admin:
    file: ./secretos/clave-admin
services:
  backend:
    secrets: [clave_admin]
    environment:
      PCC_ADMIN_CONTRASENA_FILE: /run/secrets/clave_admin

El backend borra la contraseña de su propio entorno en cuanto la ha leído, para que no la vea ninguna extensión que se cargue después, y no la escribe en el registro jamás, ni un trozo.

Qué pasa en los casos raros, para que no haya sorpresas:

  • Ya estaba instalada. No se toca nada y no se dice nada. Puedes dejar las variables en el .env para siempre.
  • Mal puestas —una dirección que no es un correo, una contraseña de menos de diez caracteres, una variable y su gemela _FILE a la vez, o un _FILE que apunta a algo que no se puede leer—: el backend se niega a arrancar y dice por qué. Ni instala a medias ni sigue en silencio dejando el asistente abierto, que es justo lo que venías a evitar.
  • Arrancar dos veces. El segundo arranque no crea nada: hay un administrador, no dos.
  • Un arranque que se cayó a medias, con la cuenta creada y la instalación sin cerrar: el siguiente la cierra y no crea a nadie.

País y moneda

El asistente no los pregunta. En su primer arranque el backend crea la región de la tienda con el país de PCC_PAIS y la moneda de PCC_MONEDA, que por defecto son es y eur. Si tu tienda vende en otra moneda, pon las dos en el .env antes del primer arranque (por ejemplo PCC_PAIS=us y PCC_MONEDA=usd); cuando la región ya existe, cambiarlas no la reescribe.

Si te quedas fuera del panel

rescate crea o arregla accesos al panel desde la consola del servidor. Dentro de Docker:

docker compose exec backend node dist/src/propio/cli.js rescate
docker compose exec backend node dist/src/propio/cli.js rescate alta tu@tudominio.com

Sin orden, enseña quién tiene acceso; alta, clave y cerrar están explicadas en la referencia del CLI. Fuera de Docker es npm run rescate en apps/backend, que lee su .env por su cuenta.

Los puertos solo se abren en tu máquina

La tienda, los paneles y el backend escuchan en 127.0.0.1, no en internet. Es a propósito: Docker abre sus puertos por delante del cortafuegos del sistema, así que un puerto publicado «para todos» queda abierto aunque ufw diga lo contrario.

Si instalas en un servidor remoto, para usar el asistente basta un túnel desde tu ordenador (el instalador te escribe la orden para el panel y la tienda; añade el panel del vendedor si también quieres verlo):

ssh -L 7001:localhost:7001 -L 3000:localhost:3000 -L 7002:localhost:7002 usuario@tu-servidor

Para seguir el arranque:

docker compose logs -f backend

Publicarlo de verdad

Pon delante un proxy inverso con HTTPS. Con Caddy, que saca los certificados solo, el Caddyfile es esto:

tienda.tudominio.com {
    reverse_proxy 127.0.0.1:3000
}

panel.tudominio.com {
    redir / /admin
    reverse_proxy 127.0.0.1:7001
}

vendedores.tudominio.com {
    reverse_proxy 127.0.0.1:7002
}

api.tudominio.com {
    reverse_proxy 127.0.0.1:9000
}

Y en el .env que creó el instalador:

  1. Los dominios (TIENDA_URL, PANEL_URL, VENDEDORES_URL, BACKEND_URL), con https://. De ahí salen los CORS y los enlaces de los correos; VENDEDORES_URL es a donde apunta el correo de bienvenida de un autor o vendedor aceptado.
  2. TRUST_PROXY=1, porque ahora hay un proxy delante (abajo, el porqué).

La contraseña de la base ya es aleatoria y la base vive en una red interna de Docker: solo la ve el backend.

Cambias el .env, reinicias, y ya:

docker compose up -d

Nada de esto obliga a reconstruir nada. El panel y el backend leen la configuración al arrancar. El backend lee el .env entero, así que cualquier variable de apps/backend/.env.example —correo, IA, carriles de pago…— también funciona con Docker. Solo TEMA e IMAGE_HOSTS obligan a reconstruir la tienda.

Los contenedores de la aplicación corren sin permisos de administrador y sin poder ganarlos después.

Los secretos, y por qué importa datos

JWT_SECRET y COOKIE_SECRET puedes dejarlos vacíos: el contenedor genera un par la primera vez y lo guarda en el volumen datos (secretos.env).

Lo que no puedes es dejar los valores de ejemplo. El apps/backend/.env.example reparte JWT_SECRET=cambia-esto, y esa cadena está en el repositorio, o sea que la tiene todo el mundo. Con ella, quien la conozca puede leer todo lo que esta tienda cifra. Así que el backend se niega a arrancar con ella y te dice cómo generar una de verdad:

✗ [arranque] JWT_SECRET tiene el valor de ejemplo, que viene escrito en el
  `.env.example` y por tanto lo conoce cualquiera.

Es a propósito y no es un aviso. Una tienda funcionando con una clave publicada va perfectamente hasta el día que no, y para entonces tiene dentro credenciales de pasarela y cuentas de cobro de verdad. Negarse a arrancar convierte un agujero mudo en un error que se lee en el primer despliegue, cuando cuesta una orden:

JWT_SECRET=$(openssl rand -hex 32)
COOKIE_SECRET=$(openssl rand -hex 32)

La comparación es exacta y solo contra esos valores publicados: un secreto que hayas escrito tú arranca sin problema, por feo que sea. Vacío no es lo mismo: sin ninguna clave no se guarda ni se lee nada delicado, el panel te lo dice a la cara, y la tienda arranca igual.

Las sesiones del panel y de los clientes no dependen de ellos: son fichas aleatorias guardadas en la base de datos. Lo que sí depende de ellos es el cifrado. JWT_SECRET —o PCC_CLAVE_CIFRADO, si la pones— es la clave que cifra lo que la tienda guarda en la base: las claves de las pasarelas de pago guardadas desde el panel, las claves y códigos digitales que vendes y las cuentas de cobro de los vendedores. También firma los enlaces de descarga privados y las licencias. Eso tiene dos consecuencias:

  • Varias réplicas del backend tienen que compartir el mismo valor. Pon JWT_SECRET (o PCC_CLAVE_CIFRADO) a mano: con secretos distintos, una réplica no puede leer lo que cifró otra.
  • Si pierdes el volumen datos, el siguiente arranque genera secretos nuevos y todo lo cifrado se vuelve ilegible. Haz copia de datos (como mínimo de secretos.env), o pon tú PCC_CLAVE_CIFRADO y guárdala en lugar seguro. Mira Copias de seguridad.

Los datos fiscales de las facturas

Se ponen en el panel, en Ajustes → Facturación. Lo que se guarda ahí manda, tanto en el panel como en la factura que el cliente descarga desde la tienda. Las variables COMPANY_* del .env son solo el respaldo mientras no se haya guardado nada.

Si tiras de ese respaldo, el prefijo del número de factura es INVOICE_PREFIX, el mismo nombre para el panel, el backend y Docker. Los nombres que tuvo antes (COMPANY_INVOICE_PREFIX en el backend, NEXT_PUBLIC_INVOICE_PREFIX en el panel) se siguen leyendo, así que un .env ya escrito sigue valiendo.

Con la tienda instalada, corta la ruta también en el proxy

Con la tienda instalada, las cinco rutas de /setup contestan 409 y no hacen nada. El panel te lo comprueba: en el escritorio repasa «el asistente de instalación (en este servidor)» y, si alguna de ellas contestara con normalidad, lo dice en rojo. Ten claro cuánto vale esa comprobación: pregunta a este servidor, por su propia dirección local. Demuestra que la puerta está echada en el backend; no dice nada de si esa dirección se alcanza desde internet, porque desde dentro de la máquina no hay forma honesta de saberlo.

Esa parte es tuya, y cuesta un bloque en el proxy inverso:

location /setup { return 404; }
<LocationMatch "^/setup">
  Require all denied
</LocationMatch>

Hazlo cuando ya hayas creado tu cuenta. No cambia nada del funcionamiento de la tienda y quita la ruta de internet para siempre.

Si pones un proxy delante, avisa

En cuanto le pongas un dominio con HTTPS vas a tener delante un proxy inverso —Apache, nginx, Cloudflare, Traefik—. Cuando lo hagas, pon esto en el .env:

TRUST_PROXY=1

Si el backend se ve directamente desde fuera, déjalo vacío.

Parece un detalle y no lo es. El backend cuenta varias cosas por IP: las entradas al panel y a la tienda (30 intentos cada 15 minutos), las altas de cuenta (10 por hora), las peticiones para restablecer la contraseña, los las llamadas al asistente de instalación y los mensajes del formulario de contacto (cinco cada diez minutos). La pregunta es de dónde sale esa IP.

Con un proxy delante, todas las visitas le llegan al backend desde la misma dirección: la del proxy. Si no le dices que está ahí, tu tienda entera comparte un solo contador y la sexta persona que escriba en diez minutos se lleva un bloqueo sin haber hecho nada. Un límite mal puesto es peor que no tener ninguno.

Y al revés también duele. La IP real del visitante viaja en una cabecera (X-Forwarded-For) que el propio visitante puede escribir. Si no hay proxy que la reemplace, cualquiera se inventa una distinta en cada petición y el límite deja de existir: comprobado aquí, con el límite en cinco, ocho peticiones rotando esa cabecera pasaban las ocho. Por eso hay que decirlo, y por eso lo seguro es lo que sale por defecto.

TRUST_PROXY=1 solo se fía de proxies en redes privadas (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 y sus equivalentes en IPv6), que es lo que cubre un proxy en la misma máquina o en la red de Docker. Un proxy con dirección pública —Cloudflare es el caso típico— hay que ponerlo en PCC_PROXIES_DE_CONFIANZA, separado por comas, como direcciones o rangos (173.245.48.0/20,…). Si no, el backend toma la dirección de Cloudflare por la del visitante.

Con Docker no tienes que hacer nada más: el backend lee las dos variables del .env.

Cambiar de tema

Desde el panel, en Temas. El paquete trae cuatro de fábrica —base, mascotas, cinematografico y dulce-obrador—, todos en inglés y español, con /en y /es en la dirección e inglés por defecto. Puedes subir otros en .zip. Al activar uno, el panel lo construye en tu servidor sin cortar la tienda: activar un tema es el único momento en que tu máquina compila, y ahí conviene tener 4 GB de RAM o espacio de intercambio.

Las fotos del escaparate

Se ven siempre. El escaparate que viene en el paquete no recorta ni convierte las fotos a WebP por su cuenta, porque para hacerlo tendría que aceptar imágenes de cualquier servidor, y eso permite usar tu tienda para descargar lo que otro le pida. Si quieres optimización, sirve las fotos desde un CDN que la haga.

Qué se guarda y dónde

Los volúmenes, y conviene saber cuál es cuál antes de borrar alguno:

VolumenQué hay
dbLa base de datos. Todo.
staticLas imágenes subidas desde el panel.
privadoLos ficheros que suben los clientes al personalizar un producto, y los de los productos descargables. No se sirven en público.
datosLos secretos generados (secretos.env) y la clave publicable. Sin los secretos, lo cifrado en la base no se puede leer.
temasLos temas: los de fábrica y los que instales desde el panel.
temas-en-marchaLo que el panel construye y arranca de cada tema, y qué tema está activo.

Los dos de temas son volúmenes con nombre y el panel escribe en ellos: por eso lo que instalas sobrevive a reconstruir la imagen. La primera vez, Docker siembra temas con los temas que trae la imagen. Si borras temas-en-marcha, no pierdes ningún tema instalado, pero sí lo construido y cuál estaba activo: toca volver a activarlo.

Detrás de un gestor de procesos o un balanceador

El servidor tiene dos puertas de salud, y no son la misma cosa:

  • /salud → 200 mientras el proceso responda. Para «¿está vivo?».
  • /listo → 200 solo si puede atender clientes. Pasa a 503 en cuanto empieza a cerrarse, y también si algún plugin no cargó al arrancar — un servidor que vende a otro precio no está listo.

El gestor de procesos mira /salud para decidir si reinicia; el balanceador mira /listo para decidir si manda tráfico. Al revés se pierden peticiones: un balanceador que mira /salud sigue mandando clientes a un servidor que ya se está yendo, y un gestor que mira /listo mata el proceso mientras termina un cobro. Con PCC_MARGEN_CIERRE_MS=5000 el servidor espera ese margen entre avisar por /listo y cerrar el puerto, para que el balanceador se aparte.


Lo que aún no hay

  • Botones de despliegue para Coolify, Railway o DigitalOcean.
  • Instalar sin Docker. Se puede, pero todavía no está documentado ni probado.
  • Hosting compartido. Y esto no va a llegar: Node no está instalado en los hostings de 3 € donde vive medio WooCommerce. Es la desventaja estructural frente a PHP y no se arregla con un instalador mejor.