Tutorial completo: Montar tu blog writefreely federado en tu vps

Por Calvo Barba Blanca | 11 Octubre 2026

Tabla de Contenidos

  1. Contexto y Decisión
  2. Requisitos Previos
  3. Preparación del DNS
  4. Conexión al VPS
  5. Estructura de Directorios
  6. docker-compose.yml
  7. Asistente de Configuración
  8. Permisos y Claves
  9. Entrypoint vs Command
  10. Integración con Caddy
  11. Verificación Final
  12. Errores y Soluciones
  13. Recursos y Enlaces

1. Contexto y Decisión

Este tutorial documenta la instalación de WriteFreely en mi VPS de OVH, autoalojada, bajo mi dominio https://blog.calvobarbablanca.es. La decisión vino de la mano del cierre de Listed (mi plataforma anterior) el 31 de diciembre de 2026. Lanzé una encuesta en Mastodon y mi comunidad eligió WriteFreely sobre Mataroa (13 votos), apostando por el autoalojamiento en mi propio servidor.

Lo que obtendrás al final:

Un blog federado con ActivityPub Accesible desde cualquier instancia del Fediverso SSL automático con Let's Encrypt SQLite como base de datos (ligero) Total control sobre tus datos

Lo que no encontrarás aquí:

Una instalación “perfecta de libro” — esta es la instalación real, con todos los errores incluidos. Aquí lo que tienes es el paso a paso estructurado para cuando quieras seguirlo a ritmo propio.

2. Requisitos previos

Lo que necesitas antes de empezar – VPS Ubuntu 24.04 LTS (o similar) – Dominio Con acceso a gestión DNS (Nominalia, Gandi, etc.) – Acceso SSH Puerto 22 abierto, usuario con sudo – Docker Instalado previamente – Proxy inverso Caddy o Nginx (yo uso Caddy standalone) – Puerto libre 8083 (o el que elijas para WriteFreely)

Mi entorno específico (para referencia) – VPS OVH: 4 vCore, 8GB RAM, 75GB NVMe – IP pública: 51.210.15.247 – Soporte: Ubuntu 24.04.4 LTS – Coste mensual: 5,83€ – Dominio registrado en: Nominalia

3. Preparación del DNS

⚠️ Haz esto PRIMERO — el DNS tarda 5-30 minutos en propagarse. Mientras se propaga, puedes ir instalando el resto.

3.1 Crear el registro DNS

Ve al panel de gestión de tu dominio → Zona DNS → Añadir nuevo registro:

3.2 Verificar propagación

Desde tu máquina local:

dig +short blog.tudominio.es
# Debería devolver tu ip pública

Si no devuelve nada, espera 5 minutos e intenta de nuevo. Puedes seguir propagando en paralelo mientras montas el contenedor.

4. Conexión al VPS

4.1 Conectar por SSH

ssh usuario@ip pública

4.2 ¡SIEMPRE con tmux!

tmux new -s writefreely

Por qué tmux: Si se corta la conexión (interrupción eléctrica, mala señal, etc.), el proceso sigue corriendo dentro del tmux. Sin tmux, si cae la sesión, puedes dejar el contenedor en estado inconsistente. Es una lección que aprendí con Castopod.

4.3 Comprobaciones previas

Verifica que los servicios base están arriba:

sudo docker ps

En mi caso, tenía activos:

Y el puerto 8083 debe estar libre:

sudo ss -tlnp | grep :8083
# NO debe devolver nada

5. Estructura de Directorios

mkdir -p ~/writefreely/{config,data,keys}
cd ~/writefreely

Esto crea tres carpetas separadas para facilitar backups y mantenimiento:

5.1 Verifica la creación

ls -la
# Debes ver: config  data  keys

6. docker-compose.yml

Crea el archivo:

nano docker-compose.yml

Contenido exacto:

services:
  writefreely:
    image: ghcr.io/writefreely/writefreely:latest
    container_name: writefreely
    restart: unless-stopped
    command: /go/cmd/writefreely/writefreely -c /config/config.ini
    ports:
      - "8083:8080"
    volumes:
      - ./config:/config
      - ./data:/data
      - ./keys:/go/keys

6.1 Detalles importantes

7. Asistente de Configuración

7.1 Lanzar el contenedor

sudo docker compose up -d

7.2 Ejecutar el asistente interactivo

IMPORTANTE: El binario de WriteFreely NO está en el PATH por defecto. La ruta completa es /go/cmd/writefreely/writefreely:

sudo docker compose run --rm --entrypoint /go/cmd/writefreely/writefreely writefreely -c /config/config.ini config start

7.3 Respuestas del asistente

El asistente te hará preguntas interactivamente. Estas fueron las mías:

7.4 Posible error en este paso

Si recibes permission denied al escribir el config.ini, ve al paso 8 antes de continuar. Los volúmenes necesitan permisos abiertos durante la instalación.

8. Permisos y Claves

8.1 Problema detectado

El contenedor corre como usuario bin (uid 2), pero nuestras carpetas son de usuario. Necesitamos dar acceso de escritura:

sudo chmod 777 ~/writefreely/config ~/writefreely/data ~/writefreely/keys

8.2 Generar claves criptográficas

sudo docker compose run --rm --entrypoint /go/cmd/writefreely/writefreely writefreely -c /config/config.ini keys generate

8.3 ⚠️ Problema común: claves anidadas

WriteFreely crea una subcarpeta keys/ dentro de keysparentdir. Si tu config dice keysparentdir = /go/keys, las claves acabarán en /keys/keys/ en lugar de /keys/.

Verifica:

ls -la ~/writefreely/keys/

Si ves una carpeta keys/ dentro, mueve los archivos afuera:

sudo mv ~/writefreely/keys/keys/* ~/writefreely/keys/
sudo rmdir ~/writefreely/keys/keys

Solución en config.ini: Cambia keysparentdir a /go (sin el /keys):

keys_parent_dir = /go

8.4 Inicializar base de datos

sudo docker compose run --rm --entrypoint /go/cmd/writefreely/writefreely writefreely -c /config/config.ini db init

8.5 Reiniciar el servicio

sudo docker compose down
sudo docker compose up -d

8.6 Verificar estado

sudo docker ps | grep writefreely

Deberías ver: writefreely Up (NO Restarting)

9. Entrypoint vs Command

9.1 El problema del bucle infinito

Si el contenedor sigue reiniciándose (Restarting (1)), mira los logs:

sudo docker logs --tail 30 writefreely

Si dice No configuration file yet aunque el config.ini existe, el problema es el conflicto entre ENTRYPOINT y CMD.

9.2 La solución correcta

La imagen oficial de WriteFreely ya tiene un ENTRYPOINT propio. Si defines command: en el compose, se añade después del entrypoint, generando una línea mal formada.

Dos soluciones posibles:

Opción A (la que usé): Sobrescribir entrypoint: con ruta completa:

services:
  writefreely:
    entrypoint: ["/go/cmd/writefreely/writefreely", "-c", "/config/config.ini"]

Opción B (más limpia): Dejar el entrypoint y asegurar que el comando sea compatible:

services:
  writefreely:
    command: writefreely -c /config/config.ini
    # Pero el binario debe estar en PATH (no siempre lo está)

Yo usé la Opción A porque funcionó a la primera.

9.3 Verificación

curl -I http://127.x.x.1:8083

Debería devolver HTTP/1.1 200 OK (o 303).

10. Integración con Caddy

10.1 Configurar el proxy inverso

Edita tu Caddyfile:

sudo nano /etc/caddy/Caddyfile

Añade el bloque:

# blog.tudominio.es → WriteFreely (puerto 8083)
blog.calvobarbablanca.es {
    reverse_proxy http://127.0.0.1:8083
    encode gzip zstd
}

10.2 Validar y recargar

sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo caddy fmt --overwrite /etc/caddy/Caddyfile
sudo systemctl reload caddy
sudo journalctl -u caddy -n 20 --no-pager

En los logs deberías ver Caddy obteniendo el certificado Let's Encrypt para tu blog en mi caso blog.calvobarbablanca.es.

11. Verificación Final

11.1 Pruebas desde la terminal

# DNS
dig +short blog.calvobarbablanca.es
# → Debe devolver: 51.210.15.247

# HTTPS local
curl -I http://127.0.0.1:8083
# → HTTP/1.1 200 OK o 303

# HTTPS completo
curl -I https://blog.calvobarbablanca.es
# → HTTP/2 200

11.2 Acceso web

Abre en tu navegador: https://blog.calvobarbablanca.es

11.3 Usuario admin Si no recuerdas la contraseña del administrador:

# Crear usuario admin (si no existe)
sudo docker compose exec writefreely /go/cmd/writefreely/writefreely -c /config/config.ini user create --admin calvo:NuevaPassTemporal2026

# O resetear contraseña de usuario existente
sudo docker compose exec writefreely /go/cmd/writefreely/writefreely -c /config/config.ini user reset-pass usuario

11.4 Probar la federación

Desde tu cuenta Mastodon: busca @usuario@blog.tudominio.es y síguelo. Tus posts llegarán al timeline federado de tus seguidores.

12. Errores y Soluciones

Esta sección resume los fallos reales de esta instalación. Son los que más importan, porque los libros no los cuentan.

Si quieres ver el proceso completo en vídeo:

Directo completo en PeerTube

Contacto y Federacion

Puedes encontrarme en el Fediverso en: Mastodon: https://tuiter.rocks/@wildperal WriteFreely: @calvo@blog.calvobarbablanca.es Este post está federado.

Última actualización: 11 Octubre 2026 Tecnología: WriteFreely + Docker + Caddy Licencia: Contenido bajo CC BY-SA 4.0