Relayium

Aloja Relayium por tu cuenta: ejecuta tu servidor de transferencia de archivos y texto

Última actualización: 2026-08-06

Relayium tiene licencia AGPL-3.0 y es de código abierto, y el servidor es una única imagen autocontenida — sin base de datos externa, sin bucket de almacenamiento de terceros, nada para lo que registrarse. Si prefieres ejecutarlo todo por tu cuenta en vez de depender de relayium.com, esta guía levanta un servidor con Docker y apunta la CLI hacia él.

Autoalojar te da control total sobre dónde viven tus datos, tu propio dominio y certificado TLS, y ninguna dependencia de la infraestructura de nadie más. Todo lo que sigue se basa en los archivos que se distribuyen en el repositorio — docker-compose.yml, server/.env.example y docs/self-hosting.md — así que nada de lo que hay aquí es un indicador o ajuste que no exista de verdad.

Por qué autoalojar

Las transferencias en tiempo real de Relayium están cifradas de extremo a extremo. Un retransmisor TURN autoalojado puede transportar bytes cifrados y el servidor procesa metadatos de señalización, pero ninguno puede leer ni descifrar el texto en claro de los archivos; ni el servidor ni el retransmisor guardan una copia o historial del contenido en tiempo real en el servidor. El servidor sí guarda tu cuenta y — para las transferencias almacenadas/basadas en enlace — blobs de texto cifrado y una pequeña base de datos SQLite. Autoalojar significa que esos datos viven en infraestructura que tú controlas, bajo tu propio dominio, sin las decisiones operativas de nadie más de por medio.

Como el proyecto tiene licencia AGPL-3.0 y es de código abierto (github.com/relayium/relayium), puedes leer exactamente qué hace el servidor antes de confiarle nada, y bifurcarlo o modificarlo libremente.

Inicio rápido con Docker

Lo que necesitas antes del paso 1

  • Un host con Docker Engine y el plugin de Compose. docker compose version imprime una cadena de versión; si sale «docker: 'compose' is not a docker command», falta el plugin.
  • Un clon del repositorio. El archivo compose construye la imagen a partir de este árbol de fuentes, así que necesita el Dockerfile y web/ a su lado: no hay ninguna imagen precompilada que descargar.
  • Espacio en disco para el volumen con nombre relayium-data: la base de datos SQLite más el cifrado de las transferencias almacenadas que conserves.
  • Un dominio y un proxy inverso que termine TLS si va a usarlo alguien más aparte de ti. El contenedor solo habla HTTP en claro y por omisión publica únicamente en la interfaz de bucle local.
  • Nada más. Ni base de datos externa, ni bucket de almacenamiento de objetos, ni cuenta de terceros.

La raíz del repositorio incluye un Dockerfile y un docker-compose.yml que construyen una única imagen autocontenida — un binario Go estático que sirve la aplicación web precompilada, así que no hace falta un Node, una cadena de herramientas Go ni nginx aparte solo para ejecutarlo.

  1. Clona el repositorio y entra en él.

    git clone https://github.com/relayium/relayium.git
    cd relayium
  2. Constrúyelo y arráncalo. El secreto de relleno es obligatorio aunque el retransmisor esté apagado: Compose valida la variable requerida del servicio coturn desactivado por perfil al analizar el archivo, de modo que un docker compose up a secas se niega a arrancar.

    RELAYIUM_TURN_SECRET=placeholder docker compose up -d --build
  3. Comprueba que el contenedor se ha quedado arriba en vez de reiniciarse en bucle.

    docker compose ps
  4. Pregúntale a la instancia si de verdad puede servir. Usa /readyz, no /healthz: la diferencia entre ambos es todo el sentido de esta comprobación, y el recuadro de resultado esperado de abajo explica por qué.

    curl -s http://127.0.0.1:8080/readyz
  5. Copia la plantilla de configuración y pon tu URL pública. RELAYIUM_BASE_URL construye los enlaces del correo saliente y decide si las cookies de sesión llevan el atributo Secure, así que tiene que ser tu dirección https:// real.

    cp server/.env.example server/.env
    chmod 600 server/.env
  6. Pon nginx o Caddy delante, terminando TLS para tu dominio y pasando todo — /, /api, /ws, /admin — al puerto 8080. Después reinicia para que server/.env surta efecto.

    docker compose up -d

Qué aspecto tiene una instancia que funciona

El contenedor informa Up y ambos extremos responden. El que importa es ready: /healthz devuelve ok sin condiciones, antes de que se abra nada, así que también pasa en una instancia cuya base de datos o directorio de blobs es inservible. /readyz hace ping a la base de datos SQLite y al directorio de blobs, y responde 503 en cuanto uno de los dos falla.

$ docker compose ps
NAME                IMAGE                     STATUS          PORTS
relayium-server-1   relayium/relayium:local   Up 12 seconds   127.0.0.1:8080->8080/tcp

$ curl -s http://127.0.0.1:8080/healthz
ok
$ curl -s http://127.0.0.1:8080/readyz
ready

Añade un retransmisor TURN para las transferencias entre redes

Las transferencias en la misma red (red local) y el push/pull basado en SSH funcionan sin nada extra. Las transferencias en tiempo real entre redes (dos dispositivos tras NAT distintos) a veces necesitan un retransmisor TURN para establecer una ruta — el retransmisor solo ve texto cifrado, nunca el contenido de tus archivos.

docker-compose.yml tiene un perfil relay opcional que arranca coturn (el servidor TURN) y una pequeña instancia de Redis para la medición de bytes retransmitidos, junto al servidor principal:

El secreto tiene que llegar a dos sitios distintos, y equivocarse falla en silencio. coturn lo recibe por la sustitución de variables de Compose, que solo se resuelve desde el shell o desde un .env en la raíz del proyecto. El servidor lo lee de su propio entorno — es decir, de server/.env — y un secreto vacío desactiva TURN por completo. Si solo pones uno de los dos, acabas con un coturn en marcha para el que el servidor nunca emite credenciales: todos los contenedores se declaran sanos, no se registra nada, y las transferencias a través de NAT estrictos siguen fallando exactamente igual que antes.

  1. Genera un único secreto aleatorio largo. Abajo se usa siempre el mismo valor.

    openssl rand -hex 32
  2. Pon ese secreto, junto con las direcciones de retransmisión a las que apunta tu dominio, en server/.env: es lo que hace que el servidor active TURN.

    RELAYIUM_TURN_SECRET=<the value from step 1>
    RELAYIUM_TURN_URLS=turn:example.com:3478,turns:example.com:5349
  3. Exporta ese mismo archivo al shell para que la sustitución de Compose pueda entregarle a coturn un secreto idéntico. Hacerle source mantiene una única fuente y deja el secreto fuera de la línea de órdenes, donde ps lo expondría.

    set -a; . ./server/.env; set +a
  4. Arranca la pila con el perfil relay.

    docker compose --profile relay up -d --build
  5. Abre los puertos de retransmisión en el cortafuegos del host. coturn se ejecuta con la red del host, así que son reglas del host y no de Docker: UDP 3478 y 49152-65535, TCP 3478 y 5349.

  6. Comprueba que el servidor — y no solo coturn — ha arrancado con el secreto. Esta es la comprobación que caza el caso silencioso.

    docker compose exec server env | grep RELAYIUM_TURN

Qué aspecto tiene un retransmisor que funciona

Ambas claves vuelven no vacías desde dentro del contenedor del servidor. Que coturn esté en marcha no demuestra nada por sí solo: el navegador solo recibe credenciales de retransmisión emitidas por el servidor.

$ docker compose exec server env | grep RELAYIUM_TURN
RELAYIUM_TURN_SECRET=3f7a…
RELAYIUM_TURN_URLS=turn:example.com:3478,turns:example.com:5349

Instala la CLI en tu máquina

Este último paso ejecuta la CLI de relayium en tu propio ordenador (no en el servidor), así que instálala ahí si aún no la tienes. En macOS o Linux:

curl -fsSL https://relayium.com/install.sh | sh

Apunta la CLI hacia tu servidor

La CLI de Relayium usa por defecto el servidor de punto de encuentro de relayium.com para send/receive y text entre redes. Pasa --server para usar el tuyo en su lugar:

  1. En una máquina que ya tenga la CLI de la sección anterior, inicia sesión contra tu servidor en vez de contra relayium.com. Imprime una URL y un código; apruébalo en un navegador con sesión iniciada en tu instancia.

    relayium login --server https://your-domain
  2. Comprueba a qué servidor están vinculadas las credenciales guardadas. whoami no acepta opciones: informa de lo que el inicio de sesión escribió de verdad, y eso es justo lo que hace que merezca la pena ejecutarlo.

    relayium whoami
  3. Pasa el mismo --server al enviar. Sin él, la CLI acuña el código de emparejamiento en relayium.com y el otro extremo no lo encontrará jamás en tu instancia.

    relayium send ./report.pdf --server https://your-domain
  4. Recibe en la otra máquina con el código impreso y el mismo --server. Las sesiones de texto funcionan igual.

    relayium receive 483920 --server https://your-domain
    relayium text --server https://your-domain
    relayium text 483920 --server https://your-domain

Cómo sabes que está hablando con tu instancia

whoami imprime la cuenta y, entre paréntesis, el servidor al que está vinculada. Que ahí aparezca tu propio dominio y no relayium.com es la confirmación.

$ relayium login --server https://your-domain
Open https://your-domain/device and enter code: WDJB-MJHT
logged in as you@example.com

$ relayium whoami
you@example.com (https://your-domain)

Cuando no funciona

Cinco fallos cubren casi todo autoalojamiento fallido. Cada uno tiene una línea que leer o una orden que ejecutar que lo zanja, y tres de los cinco parecen un éxito hasta que ejecutas la comprobación.

Síntoma, comprobación, solución

docker compose up se niega a arrancar siquiera, antes de construir nada.
docker compose up -d --build
# required variable RELAYIUM_TURN_SECRET is missing a value

Compose sustituye las variables de todo el archivo antes de filtrar por perfiles, así que valida la variable requerida del servicio coturn desactivado incluso con el retransmisor apagado. Antepón cualquier valor de relleno — RELAYIUM_TURN_SECRET=placeholder docker compose up -d --build — y sustitúyelo por un secreto real solo cuando actives de verdad el perfil relay.

El contenedor está Up, pero un navegador de otra máquina no llega a él.
docker compose ps
# PORTS  127.0.0.1:8080->8080/tcp

Esa vinculación al bucle local es el comportamiento por omisión, para que un host público no exponga HTTP en claro a internet. En producción déjala así y termina TLS en un proxy inverso del mismo host. Para una máquina solo de LAN sin proxy, publícalo más ampliamente con RELAYIUM_BIND=0.0.0.0 docker compose up -d: esa variable la lee compose, no el servidor.

/healthz dice ok, pero el registro falla y los enlaces almacenados no aparecen nunca.
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/readyz
# 503

/healthz devuelve ok sin condiciones y solo demuestra que el proceso está escuchando. /readyz hace ping a la base de datos SQLite y al directorio de blobs, así que un 503 significa que uno de los dos es inservible: comprueba que el volumen relayium-data está montado y que RELAYIUM_DB y RELAYIUM_BLOB_DIR apuntan dentro de él.

relayium login imprime una URL de verificación en localhost que no puedes abrir.
relayium login --server https://your-domain
# Open http://localhost:8080/device and enter code: WDJB-MJHT

El servidor construye esa URL a partir de RELAYIUM_BASE_URL, cuyo valor por omisión es http://localhost:8080. Ponlo en server/.env con tu dirección https:// real y reinicia. También decide si las cookies de sesión llevan el atributo Secure, así que dejarlo mal no es solo cuestión de estética.

coturn está en marcha, pero las transferencias entre redes a través de NAT estricto siguen fallando, y sin nada en los registros.
docker compose exec server env | grep RELAYIUM_TURN
# sin salida

El secreto llegó a coturn por la sustitución de Compose pero nunca llegó al servidor, cuyo secreto vacío desactiva TURN por completo. Pon RELAYIUM_TURN_SECRET y RELAYIUM_TURN_URLS en server/.env, hazle source con set -a; . ./server/.env; set +a para que la sustitución vea el mismo valor, y reinicia el perfil relay. Ambas claves tienen que volver no vacías en esa comprobación.

Preguntas frecuentes

¿Necesito configurar TURN?

Solo si quieres que las transferencias en tiempo real entre redes funcionen a través de NAT estrictos. Las transferencias en la misma red, el push/pull basado en SSH y el daemon directo funcionan todos sin él — TURN sirve puramente para el recorrido de NAT en la ruta del código de emparejamiento entre redes.

¿La CLI sigue siendo gratis si me autoalojo?

Sí. La CLI sigue siendo gratis con relayium.com o con tu servidor. send o text sin código necesitan una cuenta en el servidor de destino para generar uno, y up la necesita para guardar un archivo. receive, down y text con el código impreso no requieren iniciar sesión.

¿Puedo usar mi propio dominio y certificado TLS?

Sí. La imagen de Docker escucha en HTTP simple en :8080; pon nginx o Caddy delante con tu propio dominio y certificado (por ejemplo, vía certbot/Let's Encrypt). docs/self-hosting.md cubre qué hay que redirigir; la configuración nginx de producción propia de Relayium no está publicada, así que tendrás que escribir la tuya.

¿Qué datos almacena mi servidor autoalojado?

Una base de datos SQLite (cuentas, sesiones) en RELAYIUM_DB y, para las transferencias almacenadas/basadas en enlace, blobs cifrados en RELAYIUM_BLOB_DIR que el propio servidor no puede descifrar. El servidor no guarda archivos en tiempo real ni cuerpos de mensajes y solo retransmite el handshake de señalización; los dispositivos receptores sí pueden conservar archivos o texto.

Instala la CLI gratuita de Relayium y apúntala hacia tu propio servidor con --server.

Obtener la CLI

Sigue leyendo