Saltar al contenido principal

Copias de seguridad y actualizaciones

Qué copiar​

QuéDónde (compose.yml de ejemplo)Cómo
La base de datosel volumen pgdatapg_dump, cada noche
Archivos subidosel volumen uploads o tu bucket de S3copia el volumen; con S3, versionado o replicación del bucket
Configuración.env y compose.ymlguarda una copia en tu gestor de contraseñas o almacén de secretos

Guarda APP_ENCRYPTION_KEY por separado de las copias de seguridad de la base de datos: una copia y la clave juntas exponen los secretos cifrados que contiene.

Copia de seguridad de la base de datos​

Un volcado coherente mientras la app sigue funcionando:

cd /srv/sol2flow
docker compose exec -T db pg_dump -U sol2flow -Fc sol2flow > "backup/sol2flow-$(date +%F).dump"

Ejecútalo cada noche (cron o un temporizador de systemd), copia los volcados fuera del servidor y borra los antiguos pasado un tiempo.

Copia de seguridad de los archivos​

Con el driver local, archiva el volumen uploads:

docker run --rm -v sol2flow_uploads:/data:ro -v "$PWD/backup":/backup alpine \
tar czf "/backup/uploads-$(date +%F).tar.gz" -C /data .

(El nombre del volumen es <project>_uploads; docker volume ls lo muestra.) Con S3, activa el versionado del bucket o replícalo en otro.

Restaurar​

  1. Detén la app y deja la base de datos en marcha: docker compose stop app.

  2. Restaura la base de datos en una vacía:

    docker compose exec -T db dropdb -U sol2flow sol2flow
    docker compose exec -T db createdb -U sol2flow sol2flow
    docker compose exec -T db pg_restore -U sol2flow -d sol2flow --no-owner < backup/sol2flow-2026-09-27.dump
  3. Restaura los archivos en el volumen uploads (o en el bucket) desde el mismo momento y dáselos al usuario de la app (uid 1001):

    docker run --rm -v sol2flow_uploads:/data -v "$PWD/backup":/backup alpine \
    sh -c 'tar xzf /backup/uploads-2026-09-27.tar.gz -C /data && chown -R 1001:1001 /data'
  4. Arranca con la misma APP_ENCRYPTION_KEY y el mismo AUTH_SECRET que antes: docker compose up -d.

Prueba una restauración en una máquina de repuesto de vez en cuando: una copia de seguridad que nunca has restaurado es una esperanza, no una copia de seguridad.

Actualizar​

  1. Lee las novedades de las versiones entre la tuya y la nueva; indican los pasos manuales que haya.

  2. Haz una copia de seguridad de la base de datos.

  3. Pon la nueva versión en .env (SOL2FLOW_VERSION=1.3.0) y luego:

    docker compose pull
    docker compose up -d
    docker compose logs -f app

Las migraciones de la base de datos se ejecutan automáticamente al arrancar. No se puede volver a una versión anterior: para volver atrás, restaura la copia de seguridad que hiciste antes de actualizar, junto con la versión antigua de la imagen.

Actualizar desde una imagen de prelanzamiento

Las imágenes de prelanzamiento se ejecutaban con un usuario de id aleatorio. Ahora la app se ejecuta con uid y gid 1001, así que cambia una vez el propietario de los archivos que escribe, antes de arrancar la versión nueva:

docker compose run --rm --no-deps -u root --entrypoint chown app -R 1001:1001 /data/uploads
# un directorio del host en lugar de un volumen:
sudo chown -R 1001:1001 /srv/sol2flow/uploads

Actualizar PostgreSQL​

sol2flow es compatible con PostgreSQL 16, 17 y 18; se recomienda la 18, que es la que ejecuta el compose.yml de ejemplo. Una instalación en 16 o 17 sigue funcionando, así que cambia cuando te convenga. Una versión mayor nueva no puede abrir un directorio de datos más antiguo: deja tu servicio db como está (imagen y montaje /var/lib/postgresql/data) hasta que muevas los datos con un volcado y una restauración.

  1. Detén la app y haz un volcado de la base de datos:

    cd /srv/sol2flow
    docker compose stop app
    docker compose exec -T db pg_dump -U sol2flow -Fc sol2flow > backup/sol2flow-before-pg18.dump
    docker compose down
  2. En compose.yml, cambia el servicio db a la 18 con un volumen nuevo, montado en /var/lib/postgresql (desde la 18 la imagen guarda sus datos en /var/lib/postgresql/18/docker, ya no en …/data):

    db:
    image: postgres:18-alpine
    volumes: [pgdata18:/var/lib/postgresql]
    volumes: { pgdata: {}, pgdata18: {}, uploads: {} }
  3. Arranca primero solo la base de datos, restaura el volcado y luego arranca todo:

    docker compose up -d --wait db
    docker compose exec -T db pg_restore -U sol2flow -d sol2flow --no-owner < backup/sol2flow-before-pg18.dump
    docker compose up -d

El volumen antiguo pgdata queda intacto: para volver atrás, restaura las líneas antiguas del servicio db. Elimínalo cuando la 18 funcione bien (docker volume rm sol2flow_pgdata).

  • pg_upgrade es más rápido con bases de datos grandes, pero necesita los binarios de ambas versiones. PostgreSQL 18 activa las sumas de verificación de datos en los clústeres nuevos; si el antiguo no las tiene (lo normal hasta la 17), crea el nuevo con initdb --no-data-checksums.
  • En un servidor PostgreSQL 18 propio, las contraseñas MD5 están obsoletas: usa SCRAM (password_encryption = scram-sha-256, lo predeterminado desde la 14) y vuelve a definir la contraseña si estaba guardada como MD5.

Rotar la clave de cifrado​

APP_ENCRYPTION_KEY protege los secretos guardados en la base de datos. Cámbiala solo si ha quedado expuesta, y ten en cuenta lo que ocurre:

  • Los secretos de cliente del inicio de sesión único quedan ilegibles: vuelve a introducir el secreto de cliente de cada proveedor.
  • Los secretos y códigos de recuperación de la verificación en dos pasos dejan de ser válidos: las personas afectadas necesitan que el staff restablezca su verificación en dos pasos (Usuarios y registro).
  • Las claves de API dejan de funcionar: cada persona crea claves nuevas.
  • Los secretos de firma de los webhooks quedan ilegibles: rótalos.

Para rotarla:

  1. Crea una clave nueva: openssl rand -base64 32.
  2. Asígnala a APP_ENCRYPTION_KEY en .env y ejecuta docker compose up -d.
  3. En Administración → Autenticación, edita cada proveedor OIDC y vuelve a introducir su secreto de cliente.
  4. Avisa a tus usuarios de que deben volver a crear las claves de API y rotar los secretos de los webhooks, y restablece la verificación en dos pasos de quien lo pida.

Logs​

La app escribe líneas JSON en la salida estándar: docker compose logs app. Ajusta el nivel de detalle con LOG_LEVEL. Los secretos, como contraseñas y tokens, se eliminan de las entradas del log.

Para guardar el log también en archivos, define LOG_FILE=/data/logs/app.log con el volumen logs del ejemplo: la app escribe un archivo por día (app-2026-09-30.log, días UTC) y conserva los diez últimos (ajustes). Síguelo con docker compose exec app tail -F /data/logs/app.log, o haz una copia del volumen como la de los archivos subidos. Para enterarte de los errores sin leer logs, activa el seguimiento de errores.