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-*.zipComprueba 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.
- Tienda → http://localhost:3000
- Panel → http://localhost:7001/admin
- Panel del vendedor (autores y vendedores del mercado) → http://localhost:7002
- Backend → http://localhost:9000
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 --buildEn 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=RuizLa 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_adminEl 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
.envpara siempre. - Mal puestas —una dirección que no es un correo, una contraseña de menos de
diez caracteres, una variable y su gemela
_FILEa la vez, o un_FILEque 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.comSin 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-servidorPara seguir el arranque:
docker compose logs -f backendPublicarlo 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:
- Los dominios (
TIENDA_URL,PANEL_URL,VENDEDORES_URL,BACKEND_URL), conhttps://. De ahí salen los CORS y los enlaces de los correos;VENDEDORES_URLes a donde apunta el correo de bienvenida de un autor o vendedor aceptado. 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 -dNada 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(oPCC_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 dedatos(como mínimo desecretos.env), o pon túPCC_CLAVE_CIFRADOy 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=1Si 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:
| Volumen | Qué hay |
|---|---|
db | La base de datos. Todo. |
static | Las imágenes subidas desde el panel. |
privado | Los ficheros que suben los clientes al personalizar un producto, y los de los productos descargables. No se sirven en público. |
datos | Los secretos generados (secretos.env) y la clave publicable. Sin los secretos, lo cifrado en la base no se puede leer. |
temas | Los temas: los de fábrica y los que instales desde el panel. |
temas-en-marcha | Lo 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.