Saltar al contenido
pcreative Commerce

Copias de seguridad y qué hacer cuando algo se cae

El backend solo usa Postgres (no hay Redis) y unas cuantas carpetas en disco.

Qué hay que salvar

El backend solo usa Postgres (no hay Redis) y unas cuantas carpetas en disco. En Docker cada una es un volumen. Las órdenes de esta página se lanzan desde la carpeta de la instalación, donde el fichero del paquete se llama docker-compose.yml; en el repositorio de código ese mismo fichero es docker-compose.full.yml, así que allí añade -f docker-compose.full.yml detrás de docker compose.

VolumenQué tieneSi lo pierdes
dbLa base de datos: pedidos, clientes, productos, ajustesLo has perdido todo
datossecretos.env (el JWT_SECRET y el COOKIE_SECRET generados en el primer arranque) y la clave publicableSe generan secretos nuevos y todo lo guardado cifrado queda ilegible: claves de pasarela guardadas desde el panel, códigos digitales, cuentas de cobro
privadoFicheros que el cliente nunca descarga directamente: descargas digitales, ficheros de personalización, piezas de autoresEsos ficheros desaparecen; los pedidos siguen apuntando a ellos
staticLas imágenes subidas desde el panelFichas sin fotos, y no se regeneran
temasLos temas instalados (los de fábrica vuelven con la imagen)Reinstalas los temas que añadiste
temas-en-marchaCopias construidas de los temas activosNada: al reactivar el tema se reconstruye

db, datos y privado son los tres imprescindibles. Si pones tú PCC_CLAVE_CIFRADO (o JWT_SECRET) en el .env, guarda ese valor con el mismo cuidado que la base: es la llave de los datos cifrados.

Fuera de Docker lo mismo es la base de DATABASE_URL, tu .env y las carpetas privado/ y static/ del backend.

Copia de la base

En Docker la base no publica ningún puerto, así que pg_dump desde la máquina no llega. Se ejecuta dentro del contenedor db, desde la carpeta de la instalación (usuario y base son POSTGRES_USER y POSTGRES_DB del .env; por defecto comercio y pcreative_commerce):

docker compose exec -T db \
  pg_dump -Fc -U comercio pcreative_commerce > tienda-$(date +%F).dump

Fuera de Docker:

pg_dump -Fc "$DATABASE_URL" > tienda-$(date +%F).dump

Formato comprimido (-Fc) porque permite restaurar partes sueltas.

Mételo en un cron diario y sácalo del servidor. Una copia en la misma máquina no protege del caso que más pasa: perder la máquina.

Restaurar:

docker compose exec -T db \
  pg_restore --clean --no-owner -U comercio -d pcreative_commerce < tienda-2026-08-04.dump
# fuera de Docker
pg_restore --clean --no-owner -d "$DATABASE_URL" tienda-2026-08-04.dump

Copia de los volúmenes

Compose antepone el nombre del proyecto, pcreative-commerce-full, a los volúmenes. Un comprimido por volumen:

for v in datos privado static temas; do
  docker run --rm -v pcreative-commerce-full_$v:/v:ro -v "$PWD":/copia alpine \
    tar czf /copia/$v-$(date +%F).tgz -C /v .
done

datos lleva secretos: guarda esa copia donde solo tú puedas leerla.

Antes de cada migración

Cualquier actualización que toque la base merece una copia justo antes, aunque tengas la diaria. La diaria es de esta madrugada; la migración es de ahora.

set -a; . ./.env; set +a  # pg_dump necesita DATABASE_URL en la terminal
pg_dump -Fc "$DATABASE_URL" > pre-migracion-$(date +%F-%H%M).dump
npm run preparar          # aplica lo que falte del esquema y prepara la tienda

En Docker no hay nada que ejecutar a mano: el contenedor del backend ejecuta preparar cada vez que arranca. Haz la copia (con el docker compose … exec de arriba) antes de docker compose up -d --build.

preparar lleva un cerrojo en Postgres: dos servidores arrancando a la vez no se pisan aplicando la misma migración. Y no borra nada: si algo falla, la base se queda como estaba y la copia sigue ahí por si acaso.

Las imágenes viven fuera del código

Las fotos que se suben desde el panel van a la carpeta static/, que en el contenedor es un volumen aparte. Es a propósito: si vivieran junto al código, cada actualización se las llevaría por delante. Cuando hagas copia, copia también ese volumen — la base de datos guarda las URLs, no las imágenes.

Vigilar que sigue en pie

Un backend caído de madrugada no avisa solo. Un comprobador cada pocos minutos que mire si la tienda responde y la reinicie si no, cuesta diez líneas y evita la llamada del cliente preguntando por qué su web lleva horas dando error.

Dos cosas que ayudan si usas pm2:

  • Espera creciente entre reinicios. Si la base de datos se reinicia —las actualizaciones automáticas del sistema lo hacen de madrugada—, el backend se cae y sin espera se relanza en bucle decenas de veces por incidente.
  • Rotación de logs, o el fichero crece sin tope hasta llenar el disco.

Lo que casi nadie mira hasta que duele

  • ¿Se restaura de verdad la copia? Una copia que nunca se ha probado no es una copia, es un fichero.
  • ¿Está fuera del servidor?
  • ¿Cuánto tiempo de datos aceptas perder? Eso decide si la copia es diaria o cada hora.