Logotipo de Bitdoze

Instalar Docmost con Docker Compose: wiki autoalojada para equipos

Instala Docmost con Docker Compose: wiki autoalojada con PostgreSQL, Redis, SSL, proxy inverso, configuración de WebSocket y solución de problemas.

Dragos

Actualizado Publicado 26 min de lectura

Instalar Docmost con Docker Compose: wiki autoalojada para equipos

Docmost es una plataforma wiki y de documentación colaborativa de código abierto, creada como alternativa autoalojada a Confluence y Notion. Con más de 21.200 estrellas en GitHub y una comunidad activa, se ha convertido en una de las opciones de wiki autoalojada más populares para equipos que quieren ser dueños de sus datos.

Docmost te ofrece un editor colaborativo en tiempo real con formato de texto enriquecido, soporte para Markdown, anidación de páginas, espacios para organizar el contenido por equipo o proyecto, y comentarios en línea. Funciona con TypeScript, PostgreSQL y Redis, lo que hace que la instalación con Docker Compose sea sencilla. Tres contenedores y ya está en marcha.

Esta guía recorre una instalación completa de Docmost con Docker Compose en un VPS Linux: la configuración de compose actualizada, las variables de entorno, SSL con proxy inverso y los detalles con los que la gente suele tropezar (cabeceras WebSocket, longitud de APP_SECRET, contraseñas de base de datos).

Si quieres monitorizar los recursos del servidor como CPU, memoria y espacio en disco después del despliegue, consulta cómo monitorizar los recursos del servidor y de Docker.

Si buscas otras aplicaciones autoalojadas de documentación y notas, consulta también:

¿Qué es Docmost? Una alternativa autoalojada a Confluence

Docmost se posiciona directamente contra Confluence y Notion. La diferencia: lo alojas tú mismo, eres dueño de los datos y la Community Edition es gratuita bajo la licencia AGPL 3.0.

El proyecto está respaldado por una empresa comercial que vende funciones Enterprise (SSO, MFA, chat con IA) sobre el núcleo de código abierto. La Community Edition cubre todo lo que la mayoría de equipos necesita para un wiki compartido: edición en tiempo real, espacios, permisos, historial de páginas, adjuntos y búsqueda.

Funciones clave (Community vs Enterprise)

Community Edition (gratuita, AGPL 3.0):

  • Editor colaborativo de texto enriquecido en tiempo real (tablas, matemáticas LaTeX, callouts)
  • Espacios para organizar el contenido por equipo, proyecto o departamento
  • Permisos y controles de acceso para usuarios y grupos
  • Comentarios en línea en las páginas
  • Historial de páginas con seguimiento de versiones y reversión
  • Páginas anidadas con reordenación por arrastrar y soltar
  • Búsqueda de texto completo con PostgreSQL
  • Adjuntos con controladores de almacenamiento S3, Azure Blob y local
  • Backlinks y bloques sincronizados (transclusión)
  • Etiquetas de página, tags y favoritos
  • Seguimiento de espacios para notificaciones de actualización
  • Incrustación de PDF y reproductor de audio
  • Traducciones a más de 10 idiomas

Enterprise Edition (de pago):

SSO (SAML, OIDC, LDAP), MFA (TOTP), chat con IA compatible con MCP, flujos de verificación de páginas, aprovisionamiento SCIM, importación de PDF, exportación DOCX, búsqueda con Typesense, registros de auditoría y controles de seguridad.

Nota sobre el precio Enterprise

La Business Edition cuesta 3,50 $ por usuario al mes con un mínimo de 10 usuarios (420 $/año). SSO y MFA son exclusivos del nivel Business, lo que ha generado críticas en la comunidad de self-hosting. Especialmente el MFA, ya que es una función de seguridad básica. Hay licencias de prueba gratuitas disponibles en customers.docmost.com.

Guía de instalación de Docmost con Docker Compose

Esta es la guía completa paso a paso para instalar Docmost con Docker Compose. El archivo compose de abajo se basa en la plantilla oficial del repositorio de Docmost (v0.95.0, julio de 2025).

Requisitos previos para el despliegue con Docker

Antes de empezar, asegúrate de tener:

Los precios de los VPS subieron en todos los proveedores en 2026 — si estás reconsiderando un servidor alquilado, mira qué cambió y cuándo un mini PC sale ganando.

La RAM importa aquí

PostgreSQL, Redis y la aplicación Node.js compiten por la memoria. En un VPS de 2 GB probablemente sufrirás cierres por falta de memoria (OOM) con cualquier carga real. Empieza con un mínimo de 4 GB para uso en producción.

Si quieres gestionar tus contenedores Docker con una interfaz web, consulta Dockge: gestor de Docker Compose para self-hosting.

Configuración de Docker Compose

Docker Compose (vars en línea)

Este es el enfoque que recomienda la documentación oficial: todas las variables de entorno en línea dentro del archivo compose. Un solo archivo, sin .env que sincronizar.

yaml
services:
  docmost:
    image: docmost/docmost:latest
    depends_on:
      - db
      - redis
    environment:
      APP_URL: 'https://docs.example.com'
      APP_SECRET: 'REPLACE_WITH_LONG_SECRET'
      DATABASE_URL: 'postgresql://docmost:STRONG_DB_PASSWORD@db:5432/docmost?schema=public'
      REDIS_URL: 'redis://redis:6379'
    ports:
      - "3000:3000"
    restart: unless-stopped
    volumes:
      - docmost:/app/data/storage

  db:
    image: postgres:18
    environment:
      POSTGRES_DB: docmost
      POSTGRES_USER: docmost
      POSTGRES_PASSWORD: STRONG_DB_PASSWORD
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql

  redis:
    image: redis:8
    command: ["redis-server", "--appendonly", "yes", "--maxmemory-policy", "noeviction"]
    restart: unless-stopped
    volumes:
      - redis_data:/data

volumes:
  docmost:
  db_data:
  redis_data:

Con archivo .env

Si prefieres separar los secretos del archivo compose, el enfoque con .env sigue funcionando. Reemplaza STRONG_DB_PASSWORD con tu contraseña real tanto en el archivo compose como en el archivo .env.

yaml
services:
  docmost:
    image: docmost/docmost:latest
    depends_on:
      - db
      - redis
    environment:
      APP_URL: "${APP_URL}"
      APP_SECRET: "${APP_SECRET}"
      DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public"
      REDIS_URL: "redis://redis:6379"
    ports:
      - "3000:3000"
    restart: unless-stopped
    volumes:
      - docmost:/app/data/storage

  db:
    image: postgres:18
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql

  redis:
    image: redis:8
    command: ["redis-server", "--appendonly", "yes", "--maxmemory-policy", "noeviction"]
    restart: unless-stopped
    volumes:
      - redis_data:/data

volumes:
  docmost:
  db_data:
  redis_data:

Y el archivo .env correspondiente:

bash
APP_URL=https://docs.example.com
APP_SECRET=REPLACE_WITH_GENERATED_SECRET
POSTGRES_DB=docmost
POSTGRES_USER=docmost
POSTGRES_PASSWORD=STRONG_DB_PASSWORD

Problema de fuente única de verdad

La contraseña en DATABASE_URL y POSTGRES_PASSWORD debe coincidir exactamente. Si cambias una sin la otra, obtendrás un error password authentication failed difícil de depurar. Este es el problema más común del enfoque con .env.

Tres servicios:

  1. docmost: la aplicación. Mapea el puerto 3000 del host. Monta un volumen con nombre para los adjuntos en /app/data/storage.
  2. db: PostgreSQL 18. Almacena todo el contenido del wiki, los usuarios y los metadatos. Usa un volumen con nombre para la persistencia de datos.
  3. redis: Redis 8. Gestiona la caché y el estado de las sesiones. Se ejecuta con appendonly yes para persistencia y noeviction para evitar pérdida de datos bajo presión de memoria.

Cambios clave respecto a guías antiguas de Docmost con Docker Compose: postgres:18 (sin Alpine, imagen más grande pero más compatible), redis:8 con política de memoria explícita, volúmenes con nombre en lugar de bind mounts, y sin la línea version: "3" (obsoleta en Docker Compose v2).

Variables de entorno explicadas

Variable Obligatoria Por defecto Notas
APP_URL Sí - URL completa con protocolo https://. Ver aviso abajo.
APP_SECRET Sí - Mín. 32 caracteres. Genera con openssl rand -hex 32
DATABASE_URL Sí - Cadena de conexión PostgreSQL. El nombre del servicio debe coincidir (db, no docmost-db)
REDIS_URL Sí - Cadena de conexión Redis
PORT No 3000 Puerto de escucha de la app
JWT_TOKEN_EXPIRES_IN No 30d Caducidad del token JWT
FILE_UPLOAD_SIZE_LIMIT No 50mb Tamaño máximo de subida de archivos
FILE_IMPORT_SIZE_LIMIT No 100mb Tamaño máximo de importación
DISABLE_TELEMETRY No - Ponlo en true para desactivar la telemetría anónima

Genera el APP_SECRET:

bash
openssl rand -hex 32

Esto produce una cadena hexadecimal de 64 caracteres (muy por encima del mínimo de 32).

APP_SECRET debe tener al menos 32 caracteres

Desde v0.80.0 (abril de 2025), Docmost exige un mínimo de 32 caracteres para APP_SECRET. Si tu secreto es demasiado corto, la aplicación no arranca y muestra: “minLength”:“APP_SECRET must be longer than or equal to 32 characters”. El antiguo comando openssl rand -base64 puede producir cadenas más cortas. Usa siempre openssl rand -hex 32.

APP_URL debe incluir https://

Docmost establece el flag secure de la cookie de autenticación según el protocolo de APP_URL. Si usas docs.example.com sin https://, las cookies de autenticación no funcionarán detrás de un proxy inverso que termine TLS. Usa siempre la URL completa: https://docs.example.com.

Para secretos de producción, considera gestionar de forma segura los secretos de Docker Compose en lugar de escribirlos directamente en el archivo compose.

Configuración de SMTP

Para activar las notificaciones por correo electrónico (invitaciones, restablecimiento de contraseñas), añade estas variables de entorno al servicio docmost:

yaml
MAIL_DRIVER: smtp
SMTP_HOST: smtp.example.com
SMTP_PORT: "587"
SMTP_USERNAME: your_username
SMTP_PASSWORD: your_password
SMTP_SECURE: "false"
MAIL_FROM_ADDRESS: [email protected]
MAIL_FROM_NAME: Docmost

Pon SMTP_SECURE en false para STARTTLS en el puerto 587, o true para TLS implícito en el puerto 465. Consulta la referencia completa en variables de entorno de Docmost.

Configuración de almacenamiento S3 / Azure

Para despliegues en producción, descargar los adjuntos a S3 o Azure Blob es mejor que almacenarlos en el disco del VPS.

Almacenamiento compatible con S3:

yaml
STORAGE_DRIVER: s3
AWS_S3_ACCESS_KEY_ID: "your-key"
AWS_S3_SECRET_ACCESS_KEY: "your-secret"
AWS_S3_REGION: "auto"
AWS_S3_BUCKET: "docmost-attachments"
AWS_S3_ENDPOINT: "https://your-s3-endpoint.com"  # for non-AWS providers
AWS_S3_FORCE_PATH_STYLE: "true"  # required for most S3-compatible providers

Azure Blob Storage:

yaml
STORAGE_DRIVER: azure
AZURE_STORAGE_ACCOUNT_NAME: "your-account"
AZURE_STORAGE_ACCOUNT_KEY: "your-key"
AZURE_STORAGE_CONTAINER: "docmost-attachments"

Pon STORAGE_DRIVER en local (por defecto) si no necesitas almacenamiento externo.

Desplegar el stack

Cuando tengas listo el archivo compose (y el archivo .env si usas ese enfoque), despliega con:

bash
docker compose up -d

Esto descarga las imágenes, crea los contenedores y los inicia en segundo plano. El primer arranque tarda entre 60 y 90 segundos porque Docmost ejecuta las migraciones de base de datos antes de aceptar conexiones.

Nota: el comando es docker compose (plugin v2, sin guion). El antiguo docker-compose (v1) todavía funciona como alias en la mayoría de sistemas, pero la documentación oficial usa la sintaxis v2.

Verificar la instalación

Después de docker compose up -d, ejecuta estas comprobaciones:

bash
# All 3 services should show "Up"
docker compose ps

Salida esperada:

text
NAME                IMAGE                  STATUS
docmost-app-1       docmost/docmost:latest Up
docmost-db-1        postgres:18            Up
docmost-redis-1     redis:8                Up

Revisa los logs de la aplicación para ver el progreso de las migraciones:

bash
docker compose logs -f docmost

Cuando veas que la app escucha en el puerto 3000, prueba el endpoint de salud:

bash
curl http://localhost:3000/api/health

Debería devolver OK. Después abre tu APP_URL en un navegador. Deberías ver la página de configuración para crear tu cuenta de administrador.

La página de configuración significa éxito

Si ves la página de creación de cuenta en tu navegador, Docmost está funcionando correctamente. Crea tu cuenta de administrador y ya puedes empezar.

Monitorización después del despliegue

Una vez que Docmost esté en marcha, deberías configurar la monitorización con Beszel y Uptime Kuma para seguir el uso de recursos y la disponibilidad.

Proxy inverso y SSL para Docmost

Docmost necesita un proxy inverso para la terminación TLS y el enrutamiento del dominio. Hay un requisito crítico que pilla a la mayoría de la gente:

Se requiere soporte WebSocket

El editor colaborativo en tiempo real de Docmost usa conexiones WebSocket. Si tu proxy inverso no reenvía las cabeceras Upgrade y Connection de WebSocket, el editor de páginas cargará pero será de solo lectura. Este es el problema n.º 1 reportado. Todas las configuraciones de proxy inverso de abajo incluyen las cabeceras WebSocket necesarias.

Configuración de Cloudflare Tunnel con soporte WebSocket

Los túneles de Cloudflare admiten conexiones WebSocket por defecto. No hace falta configuración adicional. Este es el enfoque SSL más sencillo.

Ve a Access > Tunnels en el panel de Cloudflare, elige tu túnel y añade un hostname:

  • Hostname: docs.yourdomain.com
  • Service: http://127.0.0.1:3000
Configuración de Cloudflare Tunnel para el despliegue de Docmost con Docker Compose

URL de origen de Cloudflare Tunnel

Si cloudflared se ejecuta en el host (no dentro de Docker), usa 127.0.0.1:3000 como origen — no docmost:3000. El hostname docmost solo se resuelve dentro de la red de Docker. Si cloudflared se ejecuta en un contenedor en la misma red de Docker, entonces docmost:3000 funciona.

También puedes usar el proxy inverso de CloudPanel con Docker como otro enfoque.

Configuración de proxy inverso con Nginx

Para Nginx con SSL de Let’s Encrypt (vía certbot), crea este bloque de servidor:

nginx
server {
    listen 80;
    server_name docs.example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Luego obtén el certificado SSL con certbot:

bash
certbot --nginx -d docs.example.com

Las líneas proxy_http_version 1.1, Upgrade y Connection "upgrade" son las cabeceras WebSocket obligatorias. Sin ellas, el editor carga en modo de solo lectura.

Integración con Traefik mediante etiquetas Docker

Si usas Traefik (v3.6+), añade estas etiquetas al servicio docmost en tu archivo compose. Traefik admite WebSockets de forma nativa — no hace falta configuración adicional.

yaml
  docmost:
    image: docmost/docmost:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.docmost.rule=Host(`docs.example.com`)"
      - "traefik.http.routers.docmost.entrypoints=websecure"
      - "traefik.http.routers.docmost.tls.certresolver=letsencrypt"
      - "traefik.http.services.docmost.loadbalancer.server.port=3000"
    # ... rest of service config

Para una configuración completa de Traefik con Docker, consulta Traefik como proxy inverso en Docker.

Actualizar tu instalación de Docmost con Docker

Si ejecutas una versión antigua de Docmost, actualizar suele ser sencillo:

bash
cd ~/docmost
docker compose pull
docker compose up -d

Esto descarga las imágenes más recientes y reinicia los contenedores. Docmost gestiona las migraciones de base de datos automáticamente al arrancar.

Longitud mínima de APP_SECRET (v0.8.0+)

Si actualizas desde una versión anterior a v0.80.0 (abril de 2025), tu APP_SECRET debe tener al menos 32 caracteres. Si es más corto, la aplicación no arrancará y mostrará un error de validación. Regenera con openssl rand -hex 32, actualiza tu archivo compose o .env y reinicia.

Migrar desde el formato antiguo de Docker Compose

Si tu instalación actual usa el formato antiguo de compose (nombres de servicio docmost-db/docmost-redis, bind mounts como ./docmost-db, postgres:16-alpine), tendrás que actualizar:

  1. Nombres de servicio: DATABASE_URL hace referencia a db (antes era docmost-db). Actualiza el hostname en tu cadena de conexión.

  2. Ruta de datos de PostgreSQL: el formato antiguo montaba ./docmost-db:/var/lib/postgresql/data:rw. La nueva imagen postgres:18 usa /var/lib/postgresql (sin el sufijo /data). Si migras volúmenes, puede que necesites mover el directorio de datos.

  3. Volúmenes con nombre vs bind: el nuevo formato usa volúmenes con nombre (db_data, docmost, redis_data). Si quieres conservar tus datos existentes en bind mounts, puedes convertirlos a volúmenes con nombre o mantener los bind mounts — ambos funcionan.

  4. Política de memoria de Redis: la nueva configuración añade --maxmemory-policy noeviction. Algunos hosts también necesitan vm.overcommit_memory=1 configurado en el host: sysctl vm.overcommit_memory=1.

Antes de hacer cambios, haz una copia de seguridad de la base de datos (ver la sección de backups abajo).

Copia de seguridad y restauración de tu wiki autoalojada

No te saltes las copias de seguridad

Un wiki de documentación solo es valioso si puedes recuperarlo. Configura copias de seguridad automatizadas desde el primer día.

Copia de seguridad de la base de datos:

bash
docker compose exec db pg_dump -U docmost docmost > docmost-backup-$(date +%Y%m%d).sql

Automatízala con un cron (diaria a las 3 AM):

bash
0 3 * * * cd /path/to/docmost && docker compose exec db pg_dump -U docmost docmost > /backups/docmost-$(date +\%Y\%m\%d).sql

Copia de seguridad de los adjuntos:

Si usas almacenamiento local (el predeterminado), los adjuntos están en el volumen con nombre docmost. Haz la copia con:

bash
docker run --rm -v docmost_docmost:/data -v /backups:/backup alpine tar czf /backup/docmost-files-$(date +%Y%m%d).tar.gz -C /data .

Si usas almacenamiento S3 o Azure, tus adjuntos ya están fuera del servidor — solo asegúrate de que tu bucket tenga el versionado activado.

Restaurar la base de datos:

bash
docker compose exec -T db psql -U docmost docmost < docmost-backup-20250708.sql

Almacenamiento fuera del servidor: copia tus backups a otro servidor o a un almacenamiento compatible con S3. Una copia de seguridad en el mismo disco no es una copia de seguridad.

Solución de problemas comunes de Docmost con Docker

El editor carga pero es de solo lectura — corrige las cabeceras WebSocket

Síntoma: puedes ver las páginas pero no editarlas. El editor aparece pero escribir no hace nada.

Causa: tu proxy inverso no está reenviando las cabeceras WebSocket Upgrade y Connection.

Solución: añade estas cabeceras a la configuración de tu proxy inverso (ver las secciones de Nginx y Traefik arriba):

nginx
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Usuarios de Cloudflare Tunnel: los WebSockets están admitidos por defecto. Si el editor sigue siendo de solo lectura, comprueba que tu URL de origen sea correcta (127.0.0.1:3000 para cloudflared en el host).

Errores de longitud de APP_SECRET tras actualizar

Síntoma: la aplicación no arranca. Los logs muestran "minLength":"APP_SECRET must be longer than or equal to 32 characters".

Causa: tu APP_SECRET se generó con openssl rand -base64 (la recomendación antigua) y tiene menos de 32 caracteres.

Solución:

bash
openssl rand -hex 32
# Copy the output, replace APP_SECRET in your compose file or .env
docker compose up -d
Problemas de conexión y contraseña de la base de datos

Síntoma: DATABASE_URL must be a valid postgres connection string o password authentication failed.

Causa: caracteres especiales en la contraseña sin codificar para URL, o la contraseña de DATABASE_URL no coincide con POSTGRES_PASSWORD.

Solución:

  1. Usa una contraseña alfanumérica (sin caracteres especiales) para evitar problemas de codificación URL.
  2. Asegúrate de que la misma contraseña aparezca tanto en DATABASE_URL como en POSTGRES_PASSWORD.
bash
# Check logs for the exact error
docker compose logs db
docker compose logs docmost

Si la contraseña se cambió después de crear el volumen, la base de datos sigue teniendo la contraseña antigua. Opción nuclear (pérdida de datos — solo si tienes copia de seguridad):

bash
docker compose down -v  # WARNING: deletes all data volumes
# Fix the password in your compose file
docker compose up -d

Nunca uses down -v sin una copia de seguridad

docker compose down -v elimina todos los volúmenes con nombre. Toda tu base de datos y los adjuntos desaparecerán. Úsalo solo si tienes una copia de seguridad reciente o si es una instalación nueva.

502 Bad Gateway detrás del proxy inverso

Síntoma: el navegador muestra 502 Bad Gateway.

Causa: el contenedor de Docmost no está en ejecución o no ha terminado de arrancar.

Solución:

bash
docker compose ps       # Check if docmost is "Up"
docker compose logs docmost  # Check for startup errors

El primer arranque tarda entre 60 y 90 segundos por las migraciones de base de datos. Si el contenedor se reinicia en bucle, revisa los logs para ver los errores concretos.

Si te falta espacio en disco y los contenedores no arrancan, puede que necesites recuperar espacio en disco limpiando overlay2 de Docker.

Cloudflare Tunnel no alcanza el servicio

Síntoma: el túnel está configurado pero el dominio devuelve un error.

Causa: URL de origen incorrecta. La URL depende de dónde se ejecute cloudflared.

Solución:

  • cloudflared en el host (instalado vía apt/systemd): usa http://127.0.0.1:3000 como URL del servicio. El puerto 3000 del contenedor está mapeado al host.
  • cloudflared en Docker (en la misma red de Docker): usa http://docmost:3000 como URL del servicio. Los nombres de contenedor se resuelven dentro de las redes de Docker.

Revisa los logs de cloudflared en busca de errores de conexión:

bash
journalctl -u cloudflared -f

Conclusión

Docmost es una sólida plataforma de wiki y documentación autoalojada. Con más de 21.200 estrellas en GitHub, desarrollo activo (versión actual v0.95.0) y un conjunto de funciones real para la colaboración en equipo, es una de las mejores alternativas a Confluence que puedes ejecutar por tu cuenta.

La instalación con Docker Compose son tres contenedores — la app, PostgreSQL y Redis. Los principales detalles a tener en cuenta son:

  • APP_SECRET debe tener 32+ caracteres (genéralo con openssl rand -hex 32)
  • APP_URL debe incluir https:// para que funcionen las cookies de autenticación
  • Las cabeceras WebSocket deben configurarse en tu proxy inverso o el editor será de solo lectura
  • Las contraseñas de base de datos deben coincidir entre DATABASE_URL y POSTGRES_PASSWORD

Configura las copias de seguridad desde el primer día. Un cron con pg_dump no cuesta nada y te salva cuando algo sale mal.

Para más contenedores Docker autoalojados para tu servidor doméstico, consulta la lista completa de contenedores Docker para servidor doméstico.

Explora más contenedores Docker