Headscale Docker Compose es la solución definitiva para desplegar tu propia red VPN mesh sin depender de servidores externos. Si gestionas un homelab o infraestructura self-hosted, necesitas conectar tus dispositivos de forma segura desde cualquier lugar. Headscale implementa el servidor de control de Tailscale de forma open-source, permitiéndote crear una red privada cifrada con WireGuard donde tú controlas cada aspecto.
En esta guía aprenderás a instalar y configurar Headscale Docker Compose paso a paso. Cubriremos desde los requisitos previos hasta funciones avanzadas como MagicDNS, nodos de salida y compartición de archivos con Taildrop. Todo con configuraciones funcionales y listas para producción.
¿Qué es Headscale y por qué usarlo?
Headscale es una implementación open-source del servidor de control de Tailscale. Mientras que Tailscale ofrece un servicio comercial donde sus servidores de coordinación gestionan tu red, Headscale te permite alojar ese servidor de coordinación en tu propia infraestructura.
El proyecto cuenta con más de 34.700 estrellas en GitHub, está escrito en Go y tiene licencia BSD-3-Clause. Uno de sus mantenedores activos trabaja en Tailscale Inc. y contribuye al proyecto durante su horario laboral, lo que garantiza compatibilidad con el ecosistema oficial.
La tecnología subyacente es WireGuard, el protocolo VPN moderno reconocido por su rendimiento y seguridad. Headscale actúa como coordinador: no enruta el tráfico entre tus dispositivos, sino que les indica cómo conectarse directamente entre ellos (peer-to-peer). Esto significa que el servidor necesita recursos mínimos mientras tus datos viajan cifrados sin intermediarios.
Las principales ventajas de usar este servicio frente a la versión comercial son:
- Control total: Tus datos de coordinación y claves nunca salen de tu servidor
- Sin límites artificiales: Sin restricciones de nodos, usuarios o subredes
- Privacidad completa: Ningún tercero conoce la topología de tu red
- Integración con OIDC: Conecta con tu proveedor de identidad existente
- Coste cero: Software libre sin suscripciones ni planes de pago
Características de Headscale Docker Compose
Desplegar Headscale con Docker Compose simplifica enormemente la gestión del servicio. Estas son las funcionalidades que ofrece la versión actual (v0.27.1):
- Gestión de nodos: Registro interactivo y con claves pre-autenticadas, soporte para nodos efímeros
- Dual Stack: Soporte completo para IPv4 e IPv6
- Subnet routers y exit nodes: Expón subredes locales o usa nodos como pasarela de salida
- Servidor DERP integrado: Relay para conexiones que no pueden establecer NAT traversal directo
- MagicDNS: Resolución DNS automática para todos los nodos de tu red
- Split DNS: Nameservers globales y restringidos por dominio
- Taildrop: Compartición de archivos directa entre dispositivos
- Tailscale SSH: Acceso SSH sin gestión de claves tradicional
- ACLs: Listas de control de acceso vía API para segmentar tu red
- OIDC: Single Sign-On con OpenID Connect (Google, Authentik, Keycloak, etc.)
Requisitos previos para la instalación
Antes de desplegar Headscale Docker Compose necesitas cumplir estos requisitos:
- Servidor con IP pública o accesible desde Internet (VPS, servidor dedicado o puerto abierto en tu router)
- Docker y Docker Compose instalados (guía oficial de Docker)
- Dominio propio con un registro DNS tipo A apuntando a la IP de tu servidor (ejemplo:
hs.tudominio.com) - Reverse proxy con SSL (Caddy, Traefik o Nginx Proxy Manager) para HTTPS
- Puertos disponibles: 8080 (API) y 9090 (métricas, opcional)
Instalar Headscale Docker Compose paso a paso
Sigue estos pasos para tener tu servidor de VPN mesh funcionando en minutos.
Paso 1: Crear la estructura de directorios
Primero, crea los directorios necesarios para la configuración y datos persistentes:
mkdir -p /opt/headscale/{config,lib,run}
cd /opt/headscale
Paso 2: Descargar la configuración base
Descarga el archivo de configuración de ejemplo desde el repositorio oficial de Headscale y guárdalo en el directorio de configuración:
wget -O config/config.yaml \
https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
Paso 3: Configurar Headscale
Edita el archivo config/config.yaml y ajusta los parámetros esenciales:
# URL pública donde los clientes se conectarán
server_url: https://hs.tudominio.com
# Dirección de escucha interna
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
# Base de datos SQLite (recomendada para la mayoría de instalaciones)
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
# Prefijos de red para los nodos
prefixes:
v4: 100.64.0.0/10
v6: fd7a:115c:a1e0::/48
# Configuración DNS
dns:
magic_dns: true
base_domain: tudominio.ts
nameservers:
global:
- 1.1.1.1
- 9.9.9.9
# DERP integrado (relay para NAT traversal)
derp:
server:
enabled: true
region_id: 999
stun_listen_addr: 0.0.0.0:3478
Paso 4: Crear el archivo docker-compose.yml
Crea el archivo docker-compose.yml con la siguiente configuración:
services:
headscale:
image: docker.io/headscale/headscale:0.27.1
container_name: headscale
restart: unless-stopped
ports:
- "8080:8080"
- "9090:9090"
- "3478:3478/udp"
volumes:
- ./config:/etc/headscale
- ./lib:/var/lib/headscale
- ./run:/var/run/headscale
command: serve
healthcheck:
test: ["CMD", "headscale", "health"]
interval: 30s
timeout: 10s
retries: 3
Paso 5: Arrancar el servicio
Con el archivo docker-compose.yml y la configuración listos, levanta Headscale Docker Compose:
docker compose up -d
Verifica que el contenedor está funcionando correctamente:
docker compose logs -f headscale
Deberías ver mensajes indicando que el servidor está escuchando en el puerto 8080. Si aparecen errores, revisa que el archivo config.yaml tiene el formato YAML correcto y que los directorios tienen los permisos adecuados.
Configurar Headscale Docker Compose con reverse proxy
Para exponer tu servidor de forma segura con HTTPS, necesitas un reverse proxy. Aquí tienes la configuración con Caddy, una de las opciones más sencillas:
# Caddyfile
hs.tudominio.com {
reverse_proxy localhost:8080
}
Si utilizas Traefik, añade las labels correspondientes al servicio en tu docker-compose.yml. Lo importante es que el reverse proxy termine el SSL y redirija el tráfico al puerto 8080 del contenedor. Consulta la documentación oficial sobre reverse proxy para configuraciones específicas con Nginx o Traefik.
Ten en cuenta que Headscale Docker Compose necesita que el reverse proxy soporte WebSockets, ya que los clientes mantienen conexiones persistentes con el servidor de coordinación. Tanto Caddy como Traefik lo soportan sin configuración adicional.
Conectar dispositivos a Headscale Docker Compose
Una vez tu servidor está en marcha, es hora de conectar dispositivos. El proceso funciona con los clientes oficiales de Tailscale.
Crear un usuario
Primero, crea un usuario en tu servidor:
docker exec headscale headscale users create mi-usuario
Método 1: Registro interactivo
En el dispositivo cliente, ejecuta:
tailscale up --login-server https://hs.tudominio.com
Se abrirá una ventana del navegador mostrando tu clave de máquina. Copia esa clave y regístrala en el servidor:
docker exec headscale headscale nodes register \
--user mi-usuario \
--key mkey:tu_clave_aqui
Método 2: Clave pre-autenticada
Ideal para automatización y despliegues masivos. Genera una clave en el servidor:
docker exec headscale headscale preauthkeys create \
--user mi-usuario \
--reusable \
--expiration 24h
Usa la clave en el cliente sin intervención manual:
tailscale up --login-server https://hs.tudominio.com \
--authkey tu_clave_preautenticada
Verificar la conexión
Lista todos los nodos conectados a tu red:
docker exec headscale headscale nodes list
Verás una tabla con el nombre, dirección IP, estado y último contacto de cada nodo registrado. Desde el cliente, ejecuta tailscale status para confirmar que ves los demás dispositivos de la red.
Funciones avanzadas de Headscale Docker Compose
Exit nodes (nodos de salida)
Un exit node permite que todo el tráfico de un dispositivo salga a Internet a través de otro nodo de tu red. Esto es útil para acceder a tu red doméstica como si estuvieras en casa:
# En el nodo que actuará como salida:
tailscale up --login-server https://hs.tudominio.com --advertise-exit-node
# Aprobar la ruta en el servidor:
docker exec headscale headscale routes enable -r ID_RUTA
Subnet routers (rutas de subred)
Permite acceder a dispositivos de una LAN local que no tienen el cliente Tailscale instalado:
# Anunciar la subred local 192.168.1.0/24:
tailscale up --login-server https://hs.tudominio.com \
--advertise-routes=192.168.1.0/24
# Aprobar en el servidor:
docker exec headscale headscale routes list
docker exec headscale headscale routes enable -r ID_RUTA
MagicDNS y Split DNS
Con MagicDNS habilitado en la configuración, cada nodo es accesible por su nombre. Por ejemplo, si tu nodo se llama servidor-casa y el dominio base es tudominio.ts, puedes acceder a él como servidor-casa.tudominio.ts desde cualquier dispositivo de la red.
El Split DNS permite resolver dominios específicos con nameservers diferentes, ideal para redes corporativas o acceso a servicios internos. Esta funcionalidad convierte a Headscale Docker Compose en una solución de red completa, no solo una VPN básica.
Integración OIDC (Single Sign-On)
Añade autenticación centralizada conectando tu proveedor OIDC. En el archivo config.yaml:
oidc:
issuer: https://auth.tudominio.com
client_id: headscale
client_secret: tu_secreto_oidc
allowed_users:
- [email protected]
Esto permite que los usuarios se autentiquen mediante Google, Authentik, Keycloak u otro proveedor compatible con OpenID Connect. Es una de las funcionalidades más demandadas para entornos donde varios usuarios comparten la misma instalación de Headscale Docker Compose.
Headscale Docker Compose vs Tailscale: comparativa
¿Cuándo tiene sentido usar la solución self-hosted frente al servicio comercial? Esta tabla te ayudará a decidir:
| Característica | Headscale (Self-hosted) | Tailscale (Comercial) |
|---|---|---|
| Coste | Gratuito (necesitas servidor) | Gratuito hasta 100 dispositivos |
| Control de datos | Total, en tu infraestructura | Servidores de Tailscale Inc. |
| Límite de nodos | Sin límite | 100 en plan gratuito |
| Interfaz web | Via proyectos comunitarios | Dashboard oficial completo |
| Soporte | Comunidad (Discord, GitHub) | Soporte oficial |
| Funnel/Serve | No disponible aún | Disponible |
| Facilidad de setup | Moderada | Muy sencilla |
| OIDC / SSO | Sí | Sí (planes de pago) |
Troubleshooting y solución de problemas
Estos son los problemas más comunes al configurar Headscale Docker Compose y sus soluciones:
El cliente no puede conectarse
- Verifica que
server_urlenconfig.yamlcoincide exactamente con la URL accesible desde Internet - Comprueba que el reverse proxy está redirigiendo correctamente al puerto 8080
- Asegúrate de que el certificado SSL es válido (no autofirmado)
- Revisa los logs:
docker compose logs -f headscale
Los nodos no se ven entre sí
- Verifica que el servidor DERP está habilitado y el puerto UDP 3478 está abierto
- Comprueba las ACLs: por defecto Headscale permite todo el tráfico entre nodos del mismo usuario
- Ejecuta
tailscale ping nombre-nodopara diagnosticar la conectividad
Usar la imagen de debug
La imagen de producción de Headscale es distroless (sin shell ni utilidades del sistema) para máxima seguridad. Si necesitas inspeccionar el contenedor para diagnosticar problemas, usa la variante -debug que incluye una shell Busybox:
image: docker.io/headscale/headscale:0.27.1-debug
Con esta imagen puedes acceder al contenedor con docker exec -it headscale sh y examinar archivos de configuración, la base de datos SQLite o los logs internos del servicio.
FAQ sobre Headscale Docker Compose
¿Headscale es compatible con los clientes oficiales de Tailscale?
Sí. Headscale funciona con los clientes oficiales de Tailscale en todas las plataformas: Linux, macOS, Windows, Android e iOS. Solo necesitas especificar tu servidor con el parámetro --login-server al conectar.
¿Puedo migrar de Tailscale a Headscale?
Sí, pero requiere reconectar cada dispositivo a tu nuevo servidor. No existe una herramienta de migración automática. Genera claves pre-autenticadas para facilitar el proceso y reconecta los clientes apuntando a tu URL de Headscale.
¿Qué base de datos utiliza Headscale?
Por defecto utiliza SQLite, que es suficiente para la gran mayoría de instalaciones. También soporta PostgreSQL para despliegues de mayor escala. La base de datos almacena usuarios, nodos, claves y configuración de rutas.
¿Necesito una IP pública para usar Headscale?
Sí, el servidor debe ser accesible desde Internet para que los clientes puedan conectarse. Puedes usar un VPS económico (desde 3-5€/mes) o abrir un puerto en tu router doméstico. El tráfico entre nodos es peer-to-peer y no pasa por tu servidor.
¿Cuántos dispositivos soporta Headscale?
No tiene un límite definido. Headscale Docker Compose está diseñado para redes personales y de pequeñas organizaciones. Con SQLite y un VPS modesto, gestionar cientos de nodos no supone ningún problema de rendimiento.
Conclusión
Desplegar Headscale Docker Compose te da control total sobre tu red VPN mesh sin depender de servicios de terceros. Con más de 34.000 estrellas en GitHub y una comunidad muy activa, el proyecto demuestra que la soberanía digital en redes privadas es viable y accesible para cualquier entusiasta del self-hosting.
La combinación de WireGuard como protocolo base, los clientes oficiales de Tailscale y la flexibilidad de Headscale como servidor de coordinación crea un ecosistema robusto y seguro. Funciones como MagicDNS, subnet routers, exit nodes y la integración OIDC cubren prácticamente cualquier escenario de uso en un homelab o infraestructura profesional.
Recuerda que con Headscale Docker Compose el tráfico entre nodos es directo y cifrado punto a punto. Tu servidor solo coordina las conexiones iniciales, por lo que incluso un VPS básico es suficiente para gestionar decenas o cientos de dispositivos. Una vez configurado, la red se mantiene prácticamente sola.
Si buscas más herramientas para tu infraestructura self-hosted, explora nuestra categoría de Docker Compose con más de 50 guías de despliegue.
