Skip to content

Raspberry Pi

La Raspberry Pi actúa como puente de red entre el VPS (donde corre la API) y los dispositivos locales del gimnasio (ControlID IdFace, UniFi Controller). Ejecuta Dokploy (con Traefik), Tailscale para el túnel seguro, y una regla de Traefik para reenviar los callbacks de los dispositivos ControlID hacia la API.

┌─────────────────────┐ ┌─────────────────────────────────┐
│ VPS │ │ GYM (VLAN 30) │
│ api.vitality-gym │◄──── Tailscale Tunnel ──────►│ ┌─────────────────────┐ │
│ .com │ │ │ Raspberry Pi │ │
│ (API Hono) │ │ │ 192.168.30.X │ │
│ │ Subnet routing permite │ │ Dokploy + Traefik │ │
│ │ al VPS alcanzar la VLAN │ │ Tailscale: 100.x │ │
│ │ │ └──────────┬──────────┘ │
│ │ │ │ LAN │
│ │ │ ┌──────────┴──────────┐ │
│ │ │ │ IdFace Turnstile │ │
│ │ │ │ 192.168.30.Y │ │
│ │ │ ├─────────────────────┤ │
│ │ │ │ IdFace Premium │ │
│ │ │ │ 192.168.30.Z │ │
│ │ │ └─────────────────────┘ │
└─────────────────────┘ └─────────────────────────────────┘
FlujoDirecciónVíaPropósito
API → ControlIDVPS → DispositivosTailscale Subnet RoutingCrear usuarios, enrolar caras, consultar logs
ControlID → APIDispositivos → RPI → VPSTraefik (regla dinámica)Monitor webhook (eventos de acceso en tiempo real)
API → UniFiVPS → ControllerTailscale directoPortal cautivo WiFi

Terminal window
# Instalar Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
# Iniciar sesión
sudo tailscale up

Seguir las instrucciones del enlace que aparece para autenticar.


Esto permite que el VPS alcance los dispositivos en la VLAN 192.168.30.0/24 a través del túnel Tailscale.

Terminal window
# Habilitar IP forwarding (requerido para subnet routing)
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
# Reiniciar Tailscale con la ruta de la VLAN
sudo tailscale up --advertise-routes=192.168.30.0/24
  1. Ir a https://login.tailscale.com/admin/machines
  2. Buscar la Raspberry Pi en la lista
  3. Click en los tres puntos (⋮)Edit route settings
  4. Activar la ruta 192.168.30.0/24
Terminal window
# Desde el VPS, hacer ping a un dispositivo en la VLAN
ping 192.168.30.Y # IP del IdFace

Paso 3: Configurar Traefik para el Proxy de ControlID

Section titled “Paso 3: Configurar Traefik para el Proxy de ControlID”

Dokploy ya ejecuta Traefik. Solo necesitamos agregar una regla de enrutamiento dinámica para que Traefik reenvíe las peticiones del monitor ControlID hacia la API pública.

3.1 Localizar la configuración de Traefik

Section titled “3.1 Localizar la configuración de Traefik”

Dokploy guarda la configuración de Traefik en /etc/dokploy/traefik/. Verificar que exista el directorio de configuración dinámica:

Terminal window
# Ver la estructura de configuración de Traefik
ls /etc/dokploy/traefik/
# Verificar que el archivo principal referencia un directorio de dynamic config
cat /etc/dokploy/traefik/traefik.yml

Si el archivo traefik.yml no tiene un file provider para configuración dinámica, necesitas agregarlo:

Terminal window
# Crear directorio para configuración dinámica (si no existe)
sudo mkdir -p /etc/dokploy/traefik/dynamic

Y agregar al traefik.yml (si no está ya):

providers:
file:
directory: /etc/dokploy/traefik/dynamic
watch: true

Crear el archivo de configuración dinámica:

Terminal window
sudo nano /etc/dokploy/traefik/dynamic/controlid-proxy.yml

Con el siguiente contenido:

http:
routers:
controlid-proxy:
rule: "PathPrefix(`/api/v1/access-control/`)"
entryPoints:
- web
service: controlid-api
services:
controlid-api:
loadBalancer:
servers:
- url: "https://api.vitality-gym.com"
passHostHeader: false

Explicación:

  • Router controlid-proxy: Captura todas las peticiones HTTP que llegan con el path /api/v1/access-control/
  • Entry point web: Puerto 80 (HTTP), que es el que usan los dispositivos ControlID
  • Service controlid-api: Reenvía al VPS vía HTTPS
  • passHostHeader: false: Envía api.vitality-gym.com como Host en lugar de la IP de la RPI

Traefik detecta automáticamente el archivo nuevo (si watch: true está habilitado). No es necesario reiniciar.

Terminal window
# Probar desde la RPI
curl -X POST http://localhost/api/v1/access-control/monitor/dao \
-H "Content-Type: application/json" \
-d '{"test": true}'
# Probar desde la VLAN (como lo haría un IdFace)
curl -X POST http://192.168.30.X/api/v1/access-control/monitor/dao \
-H "Content-Type: application/json" \
-d '{"test": true}'

Si recibes una respuesta de la API (aunque sea un error 4xx), el proxy funciona.


Agregar las siguientes variables al .env del VPS:

# ============ CONTROLID ACCESS CONTROL ============
# IP de los dispositivos IdFace (accesibles vía Tailscale Subnet Routing)
CONTROLID_TURNSTILE_IP=192.168.30.Y
CONTROLID_PREMIUM_IP=192.168.30.Z
# Credenciales de acceso a los dispositivos (por defecto admin/admin)
CONTROLID_TURNSTILE_LOGIN=admin
CONTROLID_TURNSTILE_PASSWORD=admin
CONTROLID_PREMIUM_LOGIN=admin
CONTROLID_PREMIUM_PASSWORD=admin
# URL del callback — IP de la Raspberry Pi en la VLAN
# Los dispositivos hacen POST HTTP aquí, Traefik reenvía a la API
CONTROLID_API_CALLBACK_URL=http://192.168.30.X

Paso 5: Configurar los Dispositivos ControlID

Section titled “Paso 5: Configurar los Dispositivos ControlID”

Una vez que los dispositivos estén conectados a la VLAN y tengas sus IPs:

  1. Acceder a la interfaz web del IdFace: http://192.168.30.Y
  2. Configurar IP estática en la VLAN (si no usan DHCP reservado)
  3. Cambiar contraseñas por defecto de admin
  4. Desde la interfaz de admin de Vitality Gym, usar la función “Configurar Dispositivo” que ejecuta:
    • POST /set_configuration.fcgi con el monitor apuntando a la RPI
    • Esto equivale a http://192.168.30.X/api/v1/access-control/monitor/dao

Terminal window
# Verificar que subnet routing está activo
tailscale status
# Verificar IP forwarding
sysctl net.ipv4.ip_forward
# Debe ser: net.ipv4.ip_forward = 1
# Verificar rutas
ip route show

Los dispositivos no envían eventos al monitor

Section titled “Los dispositivos no envían eventos al monitor”
Terminal window
# Verificar que Traefik tiene la ruta cargada
# Revisar el dashboard de Traefik en Dokploy o:
curl http://localhost:8080/api/http/routers | jq '.[] | select(.name | contains("controlid"))'
# Ver logs de Traefik
docker logs $(docker ps -q --filter "name=traefik") --tail 50

Verificar conectividad entre dispositivos y RPI

Section titled “Verificar conectividad entre dispositivos y RPI”
Terminal window
# Desde la RPI, verificar que los dispositivos responden
curl -s http://192.168.30.Y/login.fcgi \
-X POST -H "Content-Type: application/json" \
-d '{"login":"admin","password":"admin"}'

ServicioPuertoDirecciónProtocolo
Traefik (Dokploy)80/443Entrada general + proxy ControlIDHTTP/HTTPS
ControlID IdFace API80RPI/VPS → DispositivosHTTP
Tailscale41641/UDPRPI ↔ VPSWireGuard
UniFi Controller8080VPS → Controller (vía Tailscale)HTTP