Este tutorial continúa la guía FileBrowser Quantum en la nube. En esta segunda parte incorporaremos OnlyOffice Document Server (Docs) como motor de edición online, permitiendo trabajar con documentos compatibles con Microsoft Office directamente desde el navegador, sin modificar la configuración ni el branding definidos en el capítulo anterior sobre Filebrowser.
En este tutorial desplegaremos únicamente OnlyOffice Document Server, que actuará como editor dependiente de FileBrowser Quantum. FileBrowser continuará siendo el responsable de la autenticación, la gestión de permisos y el almacenamiento de los archivos.
Es altamente recomendable haber completado previamente el tutorial "FileBrowser Quantum en la nube. Parte 1", ya que partimos de la base de que el servicio TallerDrive se encuentra ya desplegado. Esto implica que ya existe el directorio raíz del proyecto con su estructura de directorios y permisos correctos, así como el subdominio del servicio FileBrowser, el certificado SSL y la configuración del reverse proxy.
Partiendo de los archivos existentes docker-compose.yml y
config.yaml, en este tutorial se
modificarán para añadir
el nuevo servicio OnlyOffice y levantar ambos contenedores
de forma conjunta.
Para facilitar la resolución de posibles errores, siempre es recomendable levantar primero un servicio y comprobar que funciona correctamente antes de continuar ampliando la arquitectura con nuevos componentes. Si hemos conseguido levantar el servicio de FileBrowser, tendremos el camino un poco más fácil para completarlo con la edición y creación de archivos en OnlyOffice.
En el tutorial anterior primero se desplegó el servicio sobre una dirección IP y posteriormente se adaptó para funcionar mediante subdominios y proxy inverso. En este caso comenzaremos directamente con una configuración más cercana a un entorno de producción, utilizando subdominios desde el inicio.
Por tanto, el primer paso será crear el subdominio correspondiente, configurar su registro DNS y preparar el sitio web en el panel para poder aplicar posteriormente el Reverse Proxy.
Creamos un nuevo subdominio, tal como se explicó en el tutorial anterior. Desde el panel del registrador de dominios que estemos utilizando, accedemos a la opción para crear un nuevo registro DNS de tipo A. Este procedimiento es prácticamente idéntico en la mayoría de los registradores de dominios.
El nombre del registro será office y el valor del TTL (Time To Live) se establecerá en 300 segundos.
Tras unos segundos o minutos, el subdominio debería comenzar a resolverse correctamente. Puedes comprobarlo ejecutando el siguiente comando desde la terminal, que debería devolver la dirección IP asociada al dominio.
ping office.tallerdeapps.com
Al igual que en el tutorial anterior, primero se crea el sitio web básico sin proxy, ya que es un requisito previo para la emisión del certificado SSL. Desde aaPanel, en el menú Website, pulsamos el botón Add Site y rellenamos los campos:
Con esto se crea una web mínima accesible desde http://office.tallerdeapps.com, con archivos que nunca serán utilizados por el servicio. Estos sirven únicamente para configurar una web HTTP y poder emitir el certificado SSL. Una vez emitido el certificado, el acceso se realizará mediante HTTPS. Posteriormente, mediante el proxy inverso, este enlace apuntará a la ubicación real donde se esté ejecutando OnlyOffice.
Para crear el certificado SSL con aaPanel, el proceso es el mismo que seguimos en el capítulo anterior. Debemos acceder a:
A continuación, en el menú horizontal, seleccionamos la pestaña Let’s Encrypt.
Configura Let’s Encrypt con los siguientes valores:
La siguiente captura resume claramente esta secuencia de configuración:
Una vez emitido el certificado tras pulsar el botón Apply, se muestran la clave privada y el certificado.
A continuación, cambiamos a la pestaña Current Certs y activamos la opción de forzar HTTPS para que el servidor redirija automáticamente las peticiones realizadas por HTTP hacia HTTPS:
Finalmente, pulsamos el botón Save para guardar la configuración.
En este punto, ya deberíamos tener acceso a la web mínima a través de HTTP (nota: aún sin HTTPS).
Con esto completado, podemos avanzar al siguiente paso: la creación del proxy inverso.
Nota: Normalmente no es necesario reiniciar el servicio web, ya que aaPanel aplica automáticamente el certificado SSL. Sin embargo, si los cambios no se reflejan correctamente, puedes reiniciar el servicio (Nginx o Apache, según tu sea tu sistema) manualmente.
Una vez configurado el certificado SSL, se procede a crear el proxy inverso, que permitirá redirigir el tráfico HTTPS hacia el servicio interno del contenedor, evitando exponer directamente el puerto de la aplicación.
Desde aaPanel:
Website → office.tallerdeapps.com → Reverse Proxy → botón Add Reverse Proxy
Configuración:
La siguiente captura muestra la configuración del proxy inverso:
aaPanel genera automáticamente la siguiente configuración:
#PROXY-START/
<IfModule mod_proxy.c >
ProxyRequests Off
SSLProxyEngine on
ProxyPass / http://127.0.0.1:8081/
ProxyPassReverse / http://127.0.0.1:8081/
</IfModule >
#PROXY-END/
Esta configuración permite acceder a la pantalla de bienvenida de ONLYOFFICE Docs desde el navegador, ahora ya sí a través de HTTPS, lo que indica que el servicio se ha instalado correctamente y está en funcionamiento.
Sin embargo, al integrarlo con FileBrowser, pueden aparecer errores al crear o editar documentos.
Para solucionar estos errores, es necesario modificar la configuración del proxy para añadir las cabeceras adecuadas:
#PROXY-START/
<IfModule mod_proxy.c >
ProxyRequests Off
SSLProxyEngine on
# añadir estas 3 líneas
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Ssl "on"
#
ProxyPass / http://127.0.0.1:8081/
ProxyPassReverse / http://127.0.0.1:8081/
</IfModule >
#PROXY-END/
Estas cabeceras permiten a ONLYOFFICE validar correctamente la petición.
Desde aaPanel, el camino más limpio para llegar a la configuración del proxy es:
Pulsamos en Website del menú lateral:
→ enlace "Conf" a la derecha del nombre del sitio web (en este caso:
office.tallerdeapps.com).
→ opción Reverse Proxy del menú lateral.
→ opción Modify a la derecha del nombre del "reverse proxy" de ONLYOFFICE.
→ Finalmente, se abrirá un campo de texto con la configuración inicial del reverse proxy, que debemos editar añadiendo las 3 líneas comentadas.
El punto de entrada del sistema continúa siendo el mismo que en el tutorial anterior:
https://drive.tallerdeapps.com
Sin embargo, aunque desde el navegador parezca una única aplicación, internamente el sistema está dividido en varias capas que trabajan coordinadamente. Comprender esta arquitectura es fundamental para entender cómo se comunican FileBrowser y OnlyOffice.
Desde el navegador existen dos subdominios diferenciados:
Ambos funcionan bajo HTTPS y están protegidos mediante certificado SSL. Para el usuario, todo forma parte de la misma plataforma, aunque realmente son servicios independientes.
Cuando se abre un documento compatible:
Apache no ejecuta las aplicaciones directamente. Actúa como intermediario, redirigiendo cada subdominio al contenedor Docker correspondiente.
Usuario
│
▼
HTTPS
│
▼
aaPanel (Proxy inverso)
│
├── drive.tallerdeapps.com ──→ FileBrowser (127.0.0.1:8080)
│
└── office.tallerdeapps.com ──→ OnlyOffice (127.0.0.1:8081)
Gracias a este diseño:
Dentro de Docker, los servicios no se comunican mediante dominios públicos, sino mediante los nombres definidos en docker-compose.yml. Docker proporciona resolución DNS interna automática.
FileBrowser ──→ http://onlyoffice:81
OnlyOffice ──→ http://tallerdrive:80
Esta comunicación es privada y nunca sale al exterior, por lo que no requiere HTTPS.
Cada contenedor cumple una función específica:
1> Usuario accede a https://drive.tallerdeapps.com
2> Se autentic
3> Abre un documento compatible
4> FileBrowser genera configuración firmada (JWT)
5> OnlyOffice descarga el documento
6> Se inicia la sesión de edición
7> Al guardar, OnlyOffice envía un callback
8> FileBrowser actualiza el archivo almacenado
El subdominio office.tallerdeapps.com no es una aplicación independiente. Solo funciona cuando recibe una configuración válida desde FileBrowser.
En esta arquitectura existen dos tipos de comunicación claramente diferenciados:
Cuando el usuario pulsa Guardar, OnlyOffice no escribe directamente en el disco.
El guardado se realiza mediante un mecanismo de callback:
1> OnlyOffice finaliza la edición
2> Envía una petición HTTP a externalUrl
3> FileBrowser valida el token JWT
4> Descarga el contenido actualizado
5> Sobrescribe el archivo original
Este diseño aporta varias ventajas:
La URL configurada en externalUrl
apunta a drive.tallerdeapps.com,
lo que permite que el callback pase nuevamente
por el proxy inverso y mantenga la coherencia del entorno HTTPS.
Partiendo de la estructura creada en el tutorial anterior, añadimos un nuevo subdirectorio destinado a almacenar los datos persistentes del contenedor OnlyOffice mediante un volumen Docker.
sudo mkdir -p /www/drivetallerdeapps/onlyoffice
sudo chmod 755 /www/drivetallerdeapps/onlyoffice
Este directorio se vinculará al contenedor OnlyOffice como volumen, lo que permite conservar su configuración y datos internos aunque el contenedor sea eliminado o recreado.
Sin esta persistencia, cada reinicio implicaría perder configuración, claves internas y archivos temporales necesarios para el funcionamiento del editor.
La estructura completa del proyecto debería quedar similar a la siguiente:
ubuntu@ubuntusrv1:/www/drivetallerdeapps$ tree
.
├── branding
│ ├── logo.png
│ └── logoletrasPQ.png
├── config.yaml
├── data
│ └── ejemplo_midocumento.pdf
├── database
│ ├── database.db
│ └── database.db.bak
├── docker-compose.yml
└── onlyoffice
├── wopi_private.key
└── wopi_public.key
Cada elemento cumple una función específica dentro del sistema:
Los archivos wopi_private.key y wopi_public.key son generados automáticamente por OnlyOffice durante la inicialización del contenedor. No forman parte del certificado SSL ni están relacionados con el secreto JWT definido en la integración con FileBrowser.
Forman parte del mecanismo interno de seguridad del protocolo WOPI (Web Application Open Platform Interface), que es el estándar utilizado por editores online para comunicarse con aplicaciones que almacenan documentos.
En esta arquitectura:
Estas claves se utilizan internamente para firmar y validar las comunicaciones del editor. No deben modificarse manualmente ni confundirse con la configuración JWT del archivo docker-compose.yml.
Esta organización mantiene claramente separados:
Separar responsabilidades facilita el mantenimiento, las copias de seguridad y futuras migraciones del sistema.
En el capítulo anterior únicamente teníamos un servicio: tallerdrive (FileBrowser Quantum). Ahora añadimos un segundo servicio: onlyoffice, que permite la creación y edición de documentos de ofimática en los formatos más comunes (.docx, .xlsx, .pptx).
Ambos contenedores deben:
El archivo completo quedará así:
services:
tallerdrive:
image: gtstef/filebrowser:stable
container_name: drivetallerdeapps
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
volumes:
- /www/drivetallerdeapps/data:/folder
- /www/drivetallerdeapps/database:/home/filebrowser/database
- /www/drivetallerdeapps/branding:/home/filebrowser/branding:ro
- ./config.yaml:/home/filebrowser/config.yaml:ro
environment:
- FILEBROWSER_ONLYOFFICE_SECRET=clave_larga_secreta
networks:
- drivetallerdeapps_net
depends_on:
- onlyoffice
onlyoffice:
image: onlyoffice/documentserver:latest
container_name: onlyoffice
restart: unless-stopped
ports:
- "127.0.0.1:8081:80"
environment:
- JWT_ENABLED=true
- JWT_SECRET=clave_larga_secreta
volumes:
- /www/drivetallerdeapps/onlyoffice:/var/www/onlyoffice/Data
networks:
- drivetallerdeapps_net
networks:
drivetallerdeapps_net:
name: drivetallerdeapps_net
depends_on para que Docker
inicie OnlyOffice antes que
FileBrowser (aunque no garantiza que el servicio esté listo).drivetallerdeapps_net.
El bloque environment activa la validación
mediante token JWT:
environment:
- JWT_ENABLED=true
- JWT_SECRET=CAMBIA_ESTE_SECRETO_SUPER_LARGO
OnlyOffice solo aceptará solicitudes firmadas con ese secreto. Este mismo valor debe configurarse también en config.yaml. Si no coinciden, el editor puede abrir pero mostrará errores de autenticación como Download failed.
El valor de JWT_SECRET debe ser
idéntico en docker-compose.yml y en config.yaml.
Puedes generar un JSON Web Token (JWT) largo, aleatorio y seguro (clave secreta de 32 bytes en formato hexadecimal) con el siguiente comando:
root@ubuntusrv1:~# openssl rand -hex 32
6409c7cdc0098f1e7c9b75dc1884da9e779dd25d643c17611be4fec92ce23deb
Cada servicio publica su puerto interno 80 en un puerto distinto del host:
En Docker la sintaxis es:
HOST:CONTENEDOR
Ambos contenedores utilizan el puerto 80 internamente, pero no existe conflicto porque cada uno dispone de su propio namespace de red aislado.
El uso de 127.0.0.1 garantiza que los
servicios
no queden expuestos directamente a Internet,
delegando el acceso público al proxy inverso (Apache).
Se crea una red tipo bridge:
networks:
drivetallerdeapps_net:
name: drivetallerdeapps_net
Esto permite que ambos contenedores se comuniquen internamente por nombre de servicio. Por ejemplo, FileBrowser accede a OnlyOffice usando:
http://onlyoffice:80
Docker proporciona resolución DNS interna automática. No es necesario conocer la IP del contenedor.
OnlyOffice necesita un volumen para almacenar archivos temporales, configuración interna y claves generadas durante la ejecución (como las claves WOPI).
volumes:
- /www/drivetallerdeapps/onlyoffice:/var/www/onlyoffice/Data
Sin este volumen, la información se perdería cada vez que el contenedor fuese eliminado o recreado. La persistencia garantiza estabilidad en reinicios y actualizaciones.
Este archivo es el punto donde se conecta FileBrowser con OnlyOffice. Aquí definimos:
server:
database: "database/database.db"
port: 80
externalUrl: "https://drive.tallerdeapps.com" # URL pública usada por OnlyOffice para callbacks
internalUrl: "http://tallerdrive:80" # Comunicación interna Docker
sources:
- path: /folder
config:
defaultEnabled: true
frontend:
name: "TallerDrive"
description: "Almacenamiento seguro de archivos en el servidor de Tallerdeapps.com"
favicon: "/home/filebrowser/branding/logo.png"
loginIcon: "/home/filebrowser/branding/logo.png"
integrations:
office:
url: "https://office.tallerdeapps.com"
internalUrl: "http://onlyoffice:80"
secret: "clave_larga_secreta"
viewOnly: false # false = permite edición / true = solo visualización
Aquí se definen los parámetros principales del servicio:
Es importante entender la diferencia:
Si estas URLs no están correctamente configuradas, pueden aparecer errores como Download failed o problemas al guardar documentos.
Este bloque activa la integración con OnlyOffice.
JWT_SECRET
definido en docker-compose.yml.
La diferencia entre url e internalUrl es fundamental:
Navegador ──→ https://office.tallerdeapps.com
Docker ──→ http://onlyoffice:80
Callback ──→ https://drive.tallerdeapps.com
Si estas tres rutas están correctamente definidas y el secreto JWT coincide, la integración funcionará sin errores.
Una vez configurados docker-compose.yml y
config.yaml,
podemos iniciar el entorno completo.
cd /www/drivetallerdeapps
sudo docker compose pull
sudo docker compose up -d
Estos comandos realizan lo siguiente:
Podemos comprobar el estado de los contenedores con:
sudo docker ps
Deberían aparecer al menos:
También podemos revisar los logs en caso de error:
sudo docker logs drivetallerdeapps
sudo docker logs onlyoffice
Si todo ha arrancado correctamente:
Este fue uno de los problemas más complicados de detectar durante la integración de ONLYOFFICE. El error "Download failed" aparecía al intentar abrir o editar documentos.
Después de varias pruebas, se descubrió que la causa no era ONLYOFFICE en sí, sino una mala configuración del proxy reverse, concretamente la falta de cabeceras HTTP necesarias para HTTPS.
Para diagnosticar este tipo de errores, es fundamental revisar los logs del contenedor de ONLYOFFICE:
sudo docker logs onlyoffice-documentserver
Si no conoces el nombre exacto del contenedor, puedes listarlos con:
sudo docker ps
En los logs se pueden observar errores relacionados con la descarga de archivos o validación de URLs, lo que normalmente indica un problema con las cabeceras del proxy reverse.
En este caso, la solución fue añadir correctamente las siguientes cabeceras en el proxy:
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Ssl "on"
Una vez aplicados estos cambios, el error desapareció y la integración funcionó correctamente.
En instancias con poca memoria (1 GB o menos), ONLYOFFICE puede consumir una cantidad considerable de recursos durante la conversión y edición de documentos.
Si observas errores por falta de memoria o reinicios inesperados del contenedor, puedes añadir memoria swap como medida preventiva para evitar que el sistema se quede sin RAM.
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
En instancias con 2 núcleos y suficiente memoria (por ejemplo, 8 GB o más), normalmente no es necesario aplicar este ajuste. En el caso práctico de este proyecto, desplegado en una instancia de OCI con 2 núcleos y 12 GB de RAM, no ha sido necesario implementar memoria swap.
Para evitar que los logs crezcan de forma ilimitada en el servidor, es recomendable limitar su tamaño en Docker. Esto es especialmente útil en contenedores como onlyoffice y drivetallerdeapps, donde el volumen de logs puede aumentar rápidamente.
En este sistema, Docker aún no tiene una configuración personalizada, por lo que el archivo de configuración se encuentra vacío:
{}
Para controlar el tamaño de los logs, editamos el archivo de configuración de Docker:
sudo nano /etc/docker/daemon.json
Y sustituimos su contenido por la siguiente configuración:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "3m",
"max-file": "2"
}
}
Con esta configuración:
Esto significa que Docker mantiene una “pila” de logs formada por:
container.log (log actual)
container.log.1 (anterior)
container.log.2 (más antiguo)
Cuando se genera un nuevo archivo de rotación, el más antiguo se elimina automáticamente, manteniendo siempre un número controlado de logs sin crecimiento ilimitado en disco.
Una vez guardado el archivo, es necesario reiniciar Docker para aplicar los cambios:
sudo systemctl restart docker
Tras este reinicio, la limitación de logs quedará activa para todos los contenedores, incluidos onlyoffice y drivetallerdeapps.
Ahora dispones de FileBrowser Quantum con edición online integrada, protegido mediante HTTPS y autenticación JWT, y desplegado bajo una arquitectura distribuida y segura.