SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor

Instalar HRConvert2 en un servidor propio

Aprende a desplegar HRConvert2 en tu VPS mediante Docker o Apache. Evita subir archivos confidenciales a servicios externos configurando sandboxing, límites y limpieza.

Por qué alojar un conversor de archivos

Un conversor de archivos autoalojado mantiene el archivo en su propio disco. Esa es la razón principal para ejecutarlo. Un sitio de conversión gratuito recibe la carga y no ofrece ninguna forma de saber qué ocurre con ella después. Si el archivo es un contrato firmado de un cliente o una historia clínica escaneada, la propia carga ya constituye el incidente. HRConvert2 es un servidor de conversión de archivos escrito en PHP y distribuido bajo la licencia GPLv3. Esta guía se ha redactado para la versión 3.7.4, publicada el 18 de agosto de 2026. El proyecto ha avanzado rápidamente desde entonces: la versión más reciente disponible el 13 de octubre de 2026 es v3.9.1, publicada el 6 de septiembre de 2026, y el proyecto afirma admitir 488 formatos.

No tiene base de datos, cuentas ni cookies. Cada usuario dispone de un directorio temporal. Cada conversión la realiza una herramienta local de línea de comandos: LibreOffice para documentos, FFmpeg para audio y vídeo, ImageMagick para imágenes, Tesseract para el reconocimiento óptico de caracteres (OCR) y muchas otras herramientas más pequeñas para el resto. HRConvert2 proporciona la página de carga, la canalización y las tareas de limpieza relacionadas.

Convierte un archivo de un formato a otro. No es una suite ofimática para el navegador. Si lo que necesita es que varias personas editen documentos en una pestaña, compare OnlyOffice y Collabora autoalojados. Tampoco es almacenamiento. El resultado convertido está pensado para eliminarse. Si los archivos deben conservarse en algún lugar, esa tarea corresponde a un gestor de archivos autoalojado.

Lo que necesita

Debian o Ubuntu, Apache 2.4, PHP 8 o posterior y bubblewrap. Bubblewrap (bwrap) es el entorno aislado y no es opcional: un servidor que no puede crear un entorno aislado rechaza la conversión en lugar de ejecutarla sin él. El README del proyecto indica que basta con una Raspberry Pi Model B+, lo cual es cierto para la parte de PHP. Los binarios del conversor determinan los requisitos reales de hardware, que se detallan más adelante.

Hay dos formas de instalarlo. La imagen de Docker funciona esta misma noche. La instalación de Apache y PHP requiere una tarde y muestra exactamente qué hay en el equipo.

Ejecutarlo esta noche con Docker

La imagen incluye todos los binarios de conversión, por lo que es grande: aproximadamente 3 GB en agosto de 2026. Compruebe el espacio libre en disco antes de descargarla.

Las etiquetas son importantes en este caso. Esta guía fija v3.7.2, que era la etiqueta más reciente en Docker Hub el 17 de agosto de 2026 y también la versión más reciente publicada en GitHub ese día. v3.7.4 apareció el 18 de agosto. A fecha del 13 de octubre de 2026, la versión más reciente publicada en GitHub es v3.9.1 (6 de septiembre de 2026), y las etiquetas más recientes de Docker Hub son edge (22 de septiembre de 2026) y latest, que es v3.8.4 (31 de agosto de 2026). La etiqueta latest cambia sin aviso, y esta aplicación tiene una superficie de análisis grande, así que fije una versión y actualícela de forma deliberada.

docker pull zelon88/hrconvert2:v3.7.2
docker run -d --name hrconvert2 \
  -p 127.0.0.1:8080:80 \
  --security-opt seccomp=unconfined \
  zelon88/hrconvert2:v3.7.2
docker ps
curl -I http://127.0.0.1:8080/

Un contenedor en buen estado permanece en el estado Up y curl devuelve HTTP/1.1 200 OK. Si un contenedor se reinicia continuamente, tiene un problema durante el arranque. Consulte docker logs hrconvert2 antes de cambiar cualquier otra cosa.

Dos opciones son especialmente importantes. -p 127.0.0.1:8080:80 publica el puerto sólo en loopback, por lo que ninguna conexión llega al conversor hasta que coloque un proxy delante de él de forma deliberada. El ejemplo actual del proyecto asigna -p 8080:80, que escucha en todas las interfaces, incluida la interfaz pública. --security-opt seccomp=unconfined es necesario porque bubblewrap crea su sandbox mediante llamadas al sistema de espacios de nombres de usuario y montajes que el perfil seccomp predeterminado de Docker bloquea. Los comentarios de 3.7 config.php añaden que algunos hosts también necesitan --security-opt apparmor=unconfined. Sin esta opción, las conversiones fallan y la aplicación indica el motivo: A sandbox blocks the required syscalls unless it was started with the correct options.

Esta opción implica una decisión real. Relaja el filtro de llamadas al sistema del contenedor para que la aplicación pueda crear dentro de él un sandbox más restrictivo. Los dos ajustes que determinan el comportamiento son $RequireSandbox y $RequireSandboxOnDocker en Resources/config.php. La versión v3.7.4 los incluye como TRUE y FALSE. La etiqueta v3.7.2 fijada aquí incluye ambos como FALSE, porque sus comentarios indican que un contenedor debe mantener $RequireSandbox desactivado y dejar que $RequireSandboxOnDocker decida. Como el requisito de Docker está desactivado de forma predeterminada, un contenedor sin la opción seccomp puede realizar conversiones sin ningún sandbox. Una vez añadida la opción, establezca $RequireSandboxOnDocker = TRUE; para recuperar el comportamiento de rechazo dentro del contenedor.

Las imágenes más recientes se inician de otra forma. El proyecto cambió su proceso de Docker en v3.8.0 (25 de agosto de 2026). Su README actual y su página de Docker Hub ejecutan el contenedor con --cap-add SYS_ADMIN en lugar de la opción seccomp e indican que las conversiones se rechazan sin ella. Si cambia la versión fijada a una etiqueta 3.8 o 3.9, use las opciones que documente esa imagen. Esta capacidad es amplia, así que mantenga la asignación de puerto 127.0.0.1.

Si Docker es nuevo en esta máquina, configure primero el daemon. Ejecutar Docker en un VPS explica la instalación, el controlador de almacenamiento y la forma en que Docker escribe sus propias reglas de firewall.

Instalarlo con Apache y PHP

Hasta la versión v3.7.4, el archivo Documentation/INSTALLATION_INSTRUCTIONS.txt del repositorio describía una instalación manual en nueve pasos, y esta sección sigue ese procedimiento. Desde la versión v3.8.0, el mismo archivo describe un script de configuración. Ejecute sudo bash Documentation/Build/hrconvert2-setup.sh desde el repositorio clonado. El script instala las dependencias, escribe la configuración de PHP en un archivo drop-in en lugar de editar php.ini y amplía el perfil de AppArmor para bubblewrap. Después, php convertCore.php -v y --status verifican el resultado. La ruta manual tarda más, pero permite saber exactamente qué se instaló en el sistema. Esta es su estructura. Empiece por el servidor web, el lenguaje y el sandbox:

sudo apt update
sudo apt install -y apache2 php libapache2-mod-php php-all-dev php8.3-zip php8.3-gd bubblewrap

Los nombres de php8.3-* corresponden a Ubuntu 24.04. Ejecute php -v y use el prefijo que corresponda a su versión, porque esos nombres de paquetes cambian con cada versión de PHP y el prefijo incorrecto produce Unable to locate package.

Después, instale los conversores. Esto cubre documentos, imágenes, audio, vídeo y OCR, que es la mayoría de las conversiones habituales:

sudo apt install -y imagemagick ffmpeg libreoffice-common libreoffice-java-common \
  default-jre ghostscript poppler-utils libgxps-utils tesseract-ocr inkscape \
  xvfb clamav curl tar libxcb-cursor0

Los formatos de archivo, los modelos 3D, los ebooks y las imágenes ISO arrancables necesitan más paquetes. Algunos se encuentran en el componente multiverse de Ubuntu. En v3.7.4, el paso 3 de las instrucciones oficiales incluía la lista completa de apt y el paso 5 incluía las compilaciones desde el código fuente. La guía actual no contiene listas de paquetes. El instalador lee el manifiesto Resources/Engine/Contract/depends.php, y php convertCore.php --setup --check-depends muestra la lista actual y su estado. También se pueden compilar dos dependencias desde el código fuente. El repositorio incluye Documentation/Build/ffmpeg-build.sh para los codificadores que faltan en el FFmpeg empaquetado y Documentation/Build/build-imagemagick-v7.sh para ImageMagick 7 en Ubuntu 22.04 o 24.04, que todavía empaquetan la rama 6.9. Ubuntu 25.10 y 26.04 LTS empaquetan ImageMagick 7.1. El soporte para ebooks procede del instalador propio de calibre, que las instrucciones de 3.7 proporcionaban en una sola línea:

sudo -v && wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sudo sh /dev/stdin

Es un script del proveedor que se canaliza a un shell como root. Es el método del proyecto original y es opcional: si lo omite, sólo perderá la conversión de ebooks.

A continuación, configure los límites de PHP. Las conversiones son lentas y los archivos son grandes, por lo que los valores predeterminados son demasiado bajos. Las instrucciones de 3.7 establecían estos valores en php.ini:

max_execution_time = 1200
max_input_time = 90
memory_limit = 512M
post_max_size = 5000M
upload_max_filesize = 5000M
max_file_uploads = 100
display_errors = Off
zlib.output_compression = On

Esos valores presuponen que el equipo tiene recursos suficientes. Redúzcalos antes de usarlos en un VPS pequeño, porque upload_max_filesize = 5000M con max_file_uploads = 100 describe una sola petición que puede escribir mucho más de lo que admite un disco de 40 GB. Reinicie Apache y confirme qué configuración cargó realmente PHP:

sudo service apache2 restart
php -i | grep -E "upload_max_filesize|post_max_size|memory_limit"

Ahora configure el directorio de trabajo. $ConvertLoc en Resources/config.php lo define, y el valor predeterminado es /DATA/HRConvert2. El usuario del servidor web debe ser su propietario:

sudo mkdir -p /DATA/HRConvert2
sudo chmod -R 0755 /DATA/HRConvert2
sudo chown -R www-data:www-data /DATA/HRConvert2

Descomprima la versión en el document root de Apache. La distribución predeterminada la coloca en una carpeta HRProprietary/HRConvert2, y $InstLoc en Resources/config.php debe indicar la ubicación donde realmente la instaló. Después, ejecute el diagnóstico integrado. Es la forma más rápida de detectar una dependencia ausente antes de que lo haga un usuario:

sudo php /path/to/HRConvert2/convertCore.php -v

-v revisa toda la instalación: versiones del núcleo, comprobaciones de dependencias, estado del sandbox y paquetes de idiomas. Las conversiones de archivos no son compatibles desde la línea de comandos, por lo que este conjunto de argumentos sólo sirve para tareas administrativas.

¿Por qué falla toda conversión en una instalación nueva de Ubuntu 24.04?

La causa es el sandbox. Este es el problema inicial más frecuente. Ubuntu 24.04 restringe de forma predeterminada los espacios de nombres de usuario sin privilegios mediante AppArmor. Bubblewrap necesita un espacio de nombres de usuario para crear su sandbox, por lo que bwrap no puede iniciarse. Como la aplicación no permite convertir sin un sandbox, todos los trabajos fallan.

Compruébelo directamente:

bwrap --ro-bind / / --dev /dev /bin/true && echo sandbox ok

Un error de permiso denegado indica que se bloqueó el espacio de nombres. La solución consiste en crear un perfil de AppArmor para el binario bwrap. Primero, muestre los archivos ABI y anote el número más alto disponible:

ls /etc/apparmor.d/abi/

Después, escriba /etc/apparmor.d/bwrap y sustituya 4.0 por ese número:

abi <abi/4.0>,
include <tunables/global>

profile bwrap /usr/bin/bwrap flags=(unconfined) {
  userns,
  include if exists <local/bwrap>
}

Cárguelo:

sudo apparmor_parser -r /etc/apparmor.d/bwrap

Si no se muestra ninguna salida, el perfil se cargó correctamente. Vuelva a ejecutar la comprobación de bwrap. Debería mostrar sandbox ok. A partir de ese momento, las conversiones funcionan.

Debian 12 no presenta este problema. Su kernel permite los espacios de nombres de usuario sin privilegios y el paquete bubblewrap establece kernel.unprivileged_userns_clone en 1 durante el arranque. Por eso, la comprobación anterior funciona allí sin un perfil. En v3.8.0 y versiones posteriores, el script de configuración amplía automáticamente el perfil de AppArmor de bubblewrap de la distribución.

Un convertidor público es un analizador expuesto a desconocidos

Esta es la razón de ser del resto del artículo. Un convertidor de archivos accesible desde Internet acepta un archivo arbitrario de una persona anónima y se lo entrega a LibreOffice, ImageMagick, FFmpeg o Ghostscript. Son bases de código grandes escritas en C y C++, con un historial extenso de errores en analizadores. La persona que sube el archivo elige el formato. Por tanto, también elige qué analizador se ejecuta y qué ruta de código interna utiliza.

La respuesta de HRConvert2 consiste en ejecutar cada dependencia dentro de un espacio de nombres de bubblewrap. Cada conversión ve dos directorios: el que contiene la entrada, montado como de solo lectura, y el que recibe la salida. La red no se comparte, lo que, según las palabras del proyecto, closes every URL handler in every dependency at once. Esto es más importante de lo que parece. ImageMagick y Ghostscript aceptan referencias que obtienen una URL. Así es como un convertidor se convierte en una herramienta de falsificación de peticiones del lado del servidor (SSRF) para acceder a un endpoint de metadatos de la nube desde el interior de la red. Sin red en el espacio de nombres, la obtención no puede realizarse.

El rechazo es la otra mitad: A server that cannot build a sandbox refuses the conversion rather than quietly running without one. Una herramienta que falla de forma segura vale más que una que muestra una advertencia en un registro que nadie lee. Esta es también la razón por la que el paso de AppArmor anterior no es opcional y por la que $RequireSandboxOnDocker merece una revisión antes de exponer el contenedor.

Refuerce ImageMagick con policy.xml

El archivo de políticas de ImageMagick añade una segunda capa bajo el sandbox y conviene configurarlo. En Ubuntu 24.04 con ImageMagick 6, el archivo es /etc/ImageMagick-6/policy.xml. Muestre la configuración activa:

identify -list policy

El proyecto incluye una política en Documentation/Build/policy.xml que sirve como buen modelo. Deniega los codificadores PS, PS2, PS3, EPS, XPS y MVG. También deniega los delegates URL, HTTPS, HTTP y gs, pero permite PDF:

<policy domain="coder" rights="none" pattern="PS" />
<policy domain="coder" rights="none" pattern="MVG" />
<policy domain="delegate" rights="none" pattern="URL" />
<policy domain="delegate" rights="none" pattern="gs" />
<policy domain="coder" rights="read|write" pattern="PDF" />

La línea gs es la importante. ImageMagick no analiza PostScript directamente. Ejecuta Ghostscript mediante un proceso externo. En ese delegate se encuentran las vulnerabilidades conocidas de ejecución remota de código de ImageMagick. Si deniega el delegate, ImageMagick no entregará el archivo subido a gs, independientemente del tipo que declare el archivo.

La misma política establece límites de recursos. Así se evita que una sola imagen creada con ese fin consuma toda la máquina:

<policy domain="resource" name="memory" value="256MiB"/>
<policy domain="resource" name="map" value="512MiB"/>
<policy domain="resource" name="disk" value="1GiB"/>
<policy domain="resource" name="width" value="16KP"/>
<policy domain="resource" name="height" value="16KP"/>
<policy domain="resource" name="area" value="128MP"/>

Una bomba de descompresión es un archivo pequeño que declara dimensiones enormes. Los límites width, height y area lo rechazan antes de realizar la asignación de memoria. El proceso termina en lugar de que el kernel mate otro proceso.

También existe un problema en la dirección contraria. La política predeterminada de Ubuntu deniega directamente el codificador PDF. Por eso, en un sistema sin modificar, las operaciones con PDF fallan con attempt to perform an operation not allowed by the security policy 'PDF'. Ese mensaje indica que la política está funcionando. Volver a permitir el codificador es una decisión deliberada. Al hacerlo, debe mantener denegado el delegate gs.

El coste de la cadena de dependencias en un VPS pequeño

En reposo, nada de esto es costoso. Apache y PHP ocupan unas pocas decenas de megabytes y los binarios de conversión no se están ejecutando. Todo el coste aparece de una vez cuando llega un archivo.

Una conversión de documentos inicia LibreOffice, que a su vez inicia un runtime de Java. Una conversión de imágenes asigna a ImageMagick 256 MiB de memoria y un mapa de memoria de 512 MiB según la política anterior. Una conversión de vídeo asigna a FFmpeg todos los núcleos disponibles, porque así funciona FFmpeg con el vídeo. El propio memory_limit de PHP está configurado en 512M en el proyecto. Esas cantidades se acumulan durante un único trabajo, además de la memoria del sistema operativo y del servidor web.

Por eso, un VPS de 1 GB empieza a usar swap con el primer documento real y después entra en thrashing. Cuando se agota la memoria, el OOM killer del kernel termina el proceso con el mayor tamaño residente. Normalmente es soffice.bin, y el usuario ve una conversión fallida sin ningún mensaje útil. A veces es apache2 y todo el sitio deja de funcionar. Confírmelo después con dmesg -T | grep -i "killed process".

Esto es una recomendación de dimensionamiento, no una prueba de rendimiento: 4 GB de RAM y dos núcleos ofrecen un margen cómodo para un equipo pequeño, y 2 GB con un archivo de swap funcionan si la carga consiste en documentos e imágenes y acepta la espera. Un archivo de swap no acelera una conversión. Hace que un pico de carga sea lento en lugar de fatal. Esa es la diferencia entre una página bloqueada y una interrupción del servicio. Asigne al disco más espacio del que parezca necesario, porque la imagen de 3 GB, un límite de carga grande y el resultado convertido pueden llenar el disco mucho antes de que se agote cualquier otro recurso.

Las conversiones generan picos de carga por naturaleza. Dos personas que carguen vídeo al mismo tiempo usarán todos los núcleos, y la siguiente petición tendrá que esperar. No hay una cola de trabajos delante de este proceso, por lo que el único control disponible son los límites.

Establezca límites para impedir que una sola carga llene el disco

Reduzca primero los valores de PHP. upload_max_filesize = 512M, post_max_size = 512M y max_file_uploads = 20 son un punto de partida razonable para un servidor compartido de 4 GB. Tenga en cuenta que max_execution_time = 1200 permite que una petición de PHP se ejecute durante veinte minutos. Ese tiempo puede ser necesario para convertir un vídeo largo, pero también implica que una carga lenta mantiene ocupado un worker durante veinte minutos.

Aplique después los límites de tamaño y velocidad en el proxy, antes de que la petición llegue a PHP:

limit_req_zone $binary_remote_addr zone=convert:10m rate=6r/m;

server {
    listen 443 ssl;
    server_name convert.example.com;

    client_max_body_size 512M;
    client_body_timeout 300s;

    location / {
        limit_req zone=convert burst=4 nodelay;
        proxy_pass http://127.0.0.1:8080;
        proxy_read_timeout 1200s;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

client_max_body_size debe ser como mínimo igual al tamaño del archivo más grande que quiera convertir. De lo contrario, nginx responde con 413 Request Entity Too Large y PHP nunca recibe la carga. proxy_read_timeout debe superar la duración de la conversión más larga. De lo contrario, un trabajo que se ejecuta correctamente detrás del proxy devuelve 504 Gateway Time-out al navegador. El resto de ese bloque de servidor, incluida la terminación de TLS (transport layer security), se explica en una configuración de reverse proxy de nginx explicada línea por línea.

Eliminar los archivos convertidos

Cada conversión deja una copia de un archivo sensible en un directorio que el servidor web puede leer. La limpieza es lo que distingue un conversor de un archivo con todo lo que alguien haya convertido en él.

$DeleteThreshold en Resources/config.php indica la antigüedad, en minutos, a partir de la cual una sesión caduca, y su valor predeterminado es 60. Redúzcalo a 15 cuando el contenido sea sensible. La limpieza se ejecuta mediante un argumento de línea de comandos del núcleo:

sudo -u www-data php /path/to/HRConvert2/convertCore.php -c
sudo -u www-data php /path/to/HRConvert2/convertCore.php -c=15

-c elimina las sesiones caducadas de ambas ubicaciones de datos usando el umbral configurado. -c=15 usa quince minutos sólo durante esa ejecución. -c=now elimina todas las sesiones, independientemente de su antigüedad, incluida la sesión que un usuario esté usando para convertir un archivo en ese momento, por lo que debe reservarse para tareas de mantenimiento. Los mismos argumentos funcionan dentro del contenedor mediante docker exec.

Programe la limpieza con un temporizador para que nunca dependa de que alguien cargue una página. Basta con una línea en /etc/cron.d/hrconvert2:

*/10 * * * * www-data php /path/to/HRConvert2/convertCore.php -c

Compruébelo unos minutos después con ls /DATA/HRConvert2 y observe cómo desaparecen los directorios de sesión antiguos. Como el usuario del servidor web es el propietario de ese directorio, esa es exactamente la cuenta que obtendría un atacante si explotara el analizador. Por tanto, no debería ser propietaria de ningún otro recurso valioso. Cuentas de usuario con privilegios mínimos en un VPS es el patrón general, y aquí se aplica más que de costumbre.

Colóquelo detrás de autenticación, salvo que deba ser público

La instalación predeterminada no tiene cuentas, por diseño. Cualquiera que pueda acceder a la página puede subir un archivo y ejecutar los binarios del conversor. Los límites de tasa sólo ralentizan el proceso. Por eso, determine en qué situación se encuentra.

Si es para usted y algunos compañeros, no lo exponga. Enlace el contenedor a loopback como se muestra arriba y acceda a él mediante una red privada o un túnel SSH. Ningún sistema de Internet público podrá enviarle un archivo. Esto elimina toda la superficie de ataque en lugar de limitarla mediante filtros. Si esos compañeros necesitan abrirlo en un navegador sin que publique un nombre de host ni abra un puerto, servirlo como servicio onion v3 mantiene el conversor enlazado a loopback y les proporciona una dirección que pueden visitar.

Si debe ser accesible desde un navegador, coloque la autenticación delante del proxy. Basic auth requiere dos comandos y mantiene el formulario de carga alejado de personas no autorizadas:

sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd alice
location / {
    auth_basic "Converter";
    auth_basic_user_file /etc/nginx/.htpasswd;
    proxy_pass http://127.0.0.1:8080;
}

Recargue nginx y cargue la página. Si aparece una solicitud de autenticación, funciona correctamente. Si no aparece, el bloque location que editó no es el que gestiona la solicitud. Para usar cuentas reales en lugar de una contraseña compartida, termine la autenticación en un proveedor de inicio de sesión único: un servidor SSO Authentik autohospedado proporciona autenticación delegada delante de una aplicación que no tiene su propio inicio de sesión.

Si el objetivo es un conversor realmente público, acepte las implicaciones y planifíquelo. Suponga que se probará el sandbox. Mantenga fijada la etiqueta de la imagen, mantenga estricta la política de ImageMagick, mantenga bajos los límites de carga y ejecútelo en un VPS que no aloje ningún otro recurso importante.

Modos de fallo y mensajes que verá

Todas las conversiones fallan inmediatamente. No se puede crear el sandbox. En una instalación normal de Ubuntu 24.04, la causa es el perfil de AppArmor. En la imagen de Docker 3.7 fijada, falta --security-opt seccomp=unconfined. La aplicación lo indica: A sandbox blocks the required syscalls unless it was started with the correct options. y señala See --Require Sandbox-- & --Require Sandbox On Docker-- in config.php.

Sólo fallan las conversiones de imágenes. Bubblewrap is missing or non functional, so this image conversion cannot be isolated! significa que bwrap no existe o no se puede alcanzar mediante la ruta disponible para el usuario del servidor web.

Falla un formato y el resto funciona. Falta un binario, como indica claramente el mensaje: ImageMagick may not be installed, or may not be reachable on the system path used by the web server user. El mismo mensaje aparece para FFmpeg y LibreOffice. Ejecute convertCore.php -v para comprobar qué encuentra la instalación y recuerde que el PATH del proceso de Apache no es el mismo que el PATH de su shell de inicio de sesión.

El procesamiento de PDF falla con un error de política. attempt to perform an operation not allowed by the security policy 'PDF' procede de policy.xml de ImageMagick, no de HRConvert2.

Las cargas grandes devuelven 413. client_max_body_size de nginx es inferior al tamaño del archivo. Hay tres límites en la cadena: uno en nginx y dos en PHP. Se aplica el menor.

Las conversiones se detienen y no ha cambiado nada evidente. The device where data is stored has an insufficient amount of storage space available. Compruebe el espacio libre y confirme que la limpieza programada se está ejecutando realmente.

La limpieza genera mensajes de error en el registro. Could not clean the temporary location! y Could not clean the convert location! son problemas de propiedad. El usuario del servidor web debe ser el propietario del directorio indicado por $ConvertLoc.

FAQ

¿Es seguro exponer a Internet un conversor de archivos autoalojado?

Sólo es suficientemente seguro si lo trata como un analizador expuesto a usuarios desconocidos. Cada archivo subido se entrega a LibreOffice, ImageMagick, FFmpeg o Ghostscript, y quien realiza la carga elige cuál se utiliza. HRConvert2 ejecuta esas herramientas dentro de un espacio de nombres de bubblewrap sin red y con un directorio de entrada de sólo lectura. Además, rechaza cualquier conversión que no pueda aislar en un sandbox, lo que proporciona un valor predeterminado sólido. Aun así, es preferible exigir autenticación, mantener pequeños los límites de carga y ejecutarlo en un VPS que no contenga ningún otro dato importante.

¿Por qué falla toda conversión en una instalación nueva de Ubuntu 24.04?

Ubuntu 24.04 restringe los espacios de nombres de usuario sin privilegios mediante AppArmor, y bubblewrap necesita uno para crear su sandbox. Como la aplicación rechaza las conversiones sin sandbox, fallan todos los trabajos en lugar de fallar sólo algunos. Escriba un perfil de AppArmor para /usr/bin/bwrap con flags=(unconfined), cárguelo con sudo apparmor_parser -r /etc/apparmor.d/bwrap y confirme el resultado con bwrap --ro-bind / / --dev /dev /bin/true. Debian 12 permite de forma predeterminada los espacios de nombres de usuario sin privilegios y no necesita este paso.

¿Por qué fallan las conversiones en Docker pero funcionan en una instalación normal?

El perfil seccomp predeterminado de Docker bloquea las llamadas al sistema que utiliza bubblewrap, por lo que el sandbox no puede crearse dentro del contenedor. Para la imagen 3.7 fijada aquí, iníciela con --security-opt seccomp=unconfined, tal como indican los comentarios de config.php para esa versión. A partir de v3.8.0, el proyecto documenta --cap-add SYS_ADMIN. Tenga en cuenta que $RequireSandboxOnDocker es FALSE de forma predeterminada, por lo que un contenedor sin esa opción puede realizar conversiones sin ningún sandbox. Establézcalo en TRUE una vez aplicada la opción seccomp.

¿Cuánta RAM necesita un servidor de conversión de archivos?

En reposo consume poca memoria, pero una conversión activa consume bastante más. LibreOffice inicia un entorno de ejecución de Java, ImageMagick utiliza 256 MiB de memoria y un mapa de 512 MiB según la política incluida, y el límite propio de PHP es 512M. En un VPS de 1 GB, esa combinación provoca swapping y el killer de falta de memoria termina soffice.bin o apache2. Planifique 4 GB y dos núcleos para un equipo pequeño, y compruebe dmesg -T | grep -i "killed process" siempre que una conversión termine sin mostrar ningún mensaje.

¿Dónde se guardan los archivos convertidos y cuándo se eliminan?

Se guardan en el directorio de trabajo indicado por $ConvertLoc en Resources/config.php, cuyo valor predeterminado es /DATA/HRConvert2. $DeleteThreshold establece la antigüedad, en minutos, a partir de la cual caduca una sesión, y su valor predeterminado es 60. La limpieza se ejecuta desde la línea de comandos: php convertCore.php -c elimina las sesiones caducadas y -c=now elimina inmediatamente todas las sesiones, incluidas las activas. Añada -c a una entrada de cron o a un temporizador de systemd para que la eliminación no dependa de que alguien visite el sitio.