Tutorial
10 min read
51 views

Túneles de Proxy Sidecar en DevContainers: El Estándar Moderno para Desarrollo Local Seguro

IT
InstaTunnel Team
Published by our engineering team
Túneles de Proxy Sidecar en DevContainers: El Estándar Moderno para Desarrollo Local Seguro

Deja de instalar herramientas de túnel en tu máquina host. La práctica de ejecutar ngrok, cloudflared u otro demonio de túnel como un proceso no autorizado en tu portátil es un anti-patrón que pertenece al pasado. En 2026, la forma correcta es codificar toda tu topología de red — incluyendo el acceso público al túnel — dentro de tu devcontainer.json. Esta guía explica cómo hacerlo correctamente, qué herramientas escoger y por qué este cambio arquitectónico es importante.


Por qué la Forma Anticuada ya No Funciona

El flujo clásico del desarrollador es así: clona un repositorio, instala dependencias, instala ngrok globalmente, crea un túnel, pega la URL en algún lugar y repite cada vez que expira la sesión. Funciona — hasta que deja de hacerlo.

Los problemas se agravan a medida que los equipos crecen:

  • No reproducibilidad. La versión de la herramienta de túnel en tu máquina difiere de la de tu colega. El comportamiento varía. Los errores se culpan a la capa equivocada.
  • Deriva de seguridad. Un demonio instalado globalmente con acceso a la red se encuentra en tu sistema host, fuera de cualquier límite de contenedor. Sus credenciales están en tu directorio personal, a menudo sin cifrar.
  • Conflictos de puertos. Puertos codificados como 3000 o 8080 entran en conflicto entre proyectos. Empiezas a recordar qué proyecto usa qué puerto. Esto no es ingeniería; es arqueología.
  • Fricción en la incorporación. Cada nuevo desarrollador necesita una guía de configuración separada solo para la herramienta de túnel. Esa guía se queda obsoleta.

La especificación de DevContainer, mantenida conjuntamente por Microsoft y la comunidad, resuelve esto a nivel de entorno. Definiendo un dockerComposeFile en devcontainer.json junto con un servicio sidecar, haces del túnel un componente de primera clase, versionado, de tu cadena de suministro de software — efímero por defecto, reproducible por diseño.


La Arquitectura: Explicación de los Contenedores Sidecar

El patrón sidecar proviene de la arquitectura de microservicios. Un sidecar es un contenedor secundario que corre junto a tu contenedor principal, compartiendo su espacio de red, pero manejando una preocupación operativa distinta — en este caso, el túnel. Tu código de aplicación nunca toca el túnel. El túnel nunca toca tu código de aplicación. Ambos son desechables; ninguno es una excepción.

En términos de Docker Compose, la estructura es así:

.devcontainer/
├── devcontainer.json
├── docker-compose.yml
└── (opcional) Dockerfile

El servicio app principal ejecuta tu código. El sidecar del túnel — ya sea cloudflared, zrok u otro — corre como un servicio dependiente, inicia después de que la app esté saludable y termina limpiamente cuando se destruye la pila de Compose.


Opción 1: Túnel de Cloudflare (cloudflared)

El Túnel de Cloudflare, accesible vía el demonio cloudflared, es la opción más desplegada para equipos que ya usan Cloudflare para DNS. Establece conexiones salientes únicamente a la red de borde de Cloudflare, sin reglas de firewall entrantes ni IP públicas.

Obtener tu Token

Crea un túnel con nombre en el panel Zero Trust de Cloudflare. Durante la configuración, Cloudflare genera un TUNNEL_TOKEN. Cópialo inmediatamente — no se mostrará otra vez. Guárdalo como variable de entorno local o en tu gestor de secretos (secrets de GitHub Codespaces, variables de CI en GitLab, etc.), nunca en el repositorio.

docker-compose.yml

version: '3.8'

services:
  app:
    image: mcr.microsoft.com/devcontainers/node:20
    volumes:
      - ../:/workspace:cached
    command: sleep infinity
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 15s

  cloudflared:
    image: cloudflare/cloudflared:latest
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
    depends_on:
      app:
        condition: service_healthy
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

devcontainer.json

{
  "name": "Node.js + Cloudflare Tunnel",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",

  "remoteEnv": {
    "CLOUDFLARE_TUNNEL_TOKEN": "${localEnv:CLOUDFLARE_TUNNEL_TOKEN}"
  },

  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint"
      ]
    }
  }
}

El sintaxis ${localEnv:VARIABLE_NAME} indica que el motor del DevContainer lee el valor del entorno del host en el inicio y lo inyecta en el contexto de Compose. Nunca las credenciales tocan el repositorio. El túnel se autentica, conecta y está listo antes de tu primer npm run dev.

Nota de seguridad: Siempre configura network_mode para el contenedor cloudflared para comunicar solo a través de la red interna de Docker — no con network_mode: host. Esto asegura que el sidecar del túnel pueda alcanzar el contenedor app por nombre de servicio, pero no pueda explorar directamente la pila de red del host.


Opción 2: Zrok — Túneles Efímeros de Confianza Cero

Mientras Cloudflare domina en entornos gestionados, zrok — basado en la capa de red OpenZiti de confianza cero — ha ganado tracción significativa para desarrolladores que quieren control total de infraestructura o URLs completamente efímeros y desechables. Zrok alcanzó su versión 1.0 a finales de 2025, trayendo una nueva consola de Agente, persistencia reservada de compartición y opciones ampliadas de auto-hospedaje vía Docker Compose con Caddy para TLS automático.

El diferenciador clave: cuando detienes una compartición de zrok, esa URL desaparece inmediatamente. No hay registro DNS persistente, ni túnel zombie, ni credenciales huérfanas. Para un contexto de DevContainer — que también es efímero — este comportamiento es exactamente el correcto.

Zrok también soporta comparticiones privadas, donde los recursos nunca se exponen a un endpoint público y toda comunicación está cifrada de extremo a extremo entre los clientes de zrok. Esto es útil para entornos internos de revisión donde no quieres una URL pública.

docker-compose.yml

version: '3.8'

services:
  app:
    image: mcr.microsoft.com/devcontainers/python:3.11
    volumes:
      - ../:/workspace:cached
    command: sleep infinity
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s

  zrok-sidecar:
    image: openziti/zrok:latest
    environment:
      - ZROK_ENABLE_TOKEN=${ZROK_TOKEN}
    depends_on:
      app:
        condition: service_healthy
    command: 
      sh -c "zrok enable $$ZROK_ENABLE_TOKEN 66
             zrok share public http://app:8000 --headless"

Cuando la pila inicia, el sidecar habilita el entorno zrok usando tu token, y luego inmediatamente provee una URL pública temporal que enruta a la aplicación Python en el puerto 8000. La URL se imprime en los logs del contenedor. Cuando se llama a docker compose down, el proceso zrok termina y se destruye la compartición.

Para obtener la URL generada, inspecciona los logs del sidecar:

docker logs <proyecto>-zrok-sidecar-1

O configura el sidecar para escribir la URL en un volumen compartido que tu postStartCommand pueda leer y mostrar en la terminal de VS Code.


Opción 3: pgrok — Túneles Multi-Inquilino Auto-Hospedados

Para equipos que quieren túneles de nivel empresarial sin el coste empresarial, pgrok ofrece una solución multi-inquilino basada en SSH que hospedas en tu propio dominio. Soporta autenticación OIDC, lo que significa que los desarrolladores se autentican con tu proveedor SSO (Okta, Auth0, Google Workspace, etc.) antes de que se emita una URL de túnel. Las URLs resultantes siguen el patrón https://feature-x.alice.dev.example.com — estables, legibles y específicas para cada desarrollador. Un operador de Kubernetes puede inyectar pgrok como sidecar automáticamente, dando a cada pod una URL revisable sin configuración adicional.

Para equipos con dominio y proveedor SSO, esto ofrece la mayor parte de la experiencia “ngrok empresarial” con costos de infraestructura de unos pocos dólares al mes.


Panorama de Herramientas de Túnel en 2026

La competencia contra ngrok se ha intensificado. En febrero de 2026, el proyecto de código abierto DDEV abrió un issue para considerar eliminar ngrok como proveedor predeterminado, citando límites más estrictos en la capa gratuita. El mercado ha respondido con alternativas viables en todos los rangos de precio:

Herramienta Modelo Mejor para Nivel gratuito
Cloudflare Tunnel SaaS gestionado Equipos en DNS de Cloudflare Sí (generoso)
zrok Código abierto / SaaS Efímero, confianza cero, auto-hospedable
pgrok Auto-hospedado Equipos con dominio propio + SSO Solo costo de infraestructura
Tailscale Funnel VPN en malla Acceso privado de equipo, basado en WireGuard Sí (personal)
Inlets Auto-hospedado / SaaS Nativo en Kubernetes, métricas Prometheus No (más de $25/mes)
ngrok SaaS gestionado Bien documentado, ampliamente soportado Restringido en 2026

Para pruebas de webhooks — el caso de uso más común en DevContainer — tanto Cloudflare Tunnel (URL persistente con nombre) como zrok (URL efímera por sesión) son opciones fuertes. Cloudflare es mejor cuando necesitas configurar un endpoint de webhook en un servicio externo (Stripe, GitHub) una sola vez y dejarlo. Zrok es mejor cuando quieres estado persistente cero y máxima aislamiento por sesión.


Mejores Prácticas

1. Siempre Usa Checks de Salud y Condiciones depends_on

El modo más común de fallo en configuraciones de sidecar de túnel es que el túnel se active antes de que la aplicación termine de arrancar, causando errores 502 Bad Gateway durante la ventana de inicio. La solución es tener checks de salud explícitos en el servicio app y condition: service_healthy en el bloque depends_on del sidecar. Esto no es opcional.

depends_on:
  app:
    condition: service_healthy

Sin esto, Docker Compose solo garantiza el orden de inicio de los contenedores, no la disponibilidad de la aplicación.

2. Evita Mapeos de Puertos Host Codificados

Si enrutas tráfico a través de un túnel sidecar, no necesitas exponer puertos del contenedor al host con ports: - "3000:3000". Elimina esas asignaciones. Esto elimina conflictos de puertos — otro proyecto puede usar el puerto 3000 en la misma máquina sin conflicto. Si también necesitas acceso local en navegador durante desarrollo, usa la función de reenvío de puertos de VS Code en lugar de un mapeo estático de Docker.

3. Seguridad en la Inyección de Secretos

El patrón ${localEnv:VARIABLE_NAME} en devcontainer.json es la forma correcta para todos los entornos. Para GitHub Codespaces, guarda tu CLOUDFLARE_TUNNEL_TOKEN o ZROK_TOKEN en la interfaz de secretos del usuario; se inyectan automáticamente como variables de entorno al iniciar, y ${localEnv:...} las lee. Nunca pongas tokens en archivos .env que se rastreen con git. Añade .env a .gitignore y trátalo como un archivo solo local.

4. Visibilidad de Logs para Contenedores Sidecar

Como el sidecar corre en segundo plano, sus logs no aparecen en tu terminal principal de VS Code. Los desarrolladores deben consultarlos activamente. Hay tres opciones prácticas:

  • Usa la extensión de Docker en VS Code para seguir los logs de cada contenedor desde la barra lateral.
  • Ejecuta docker logs <proyecto>-<servicio-sidecar>-1 --follow en una terminal del host.
  • Configura un postStartCommand en devcontainer.json que lea una URL escrita por el sidecar en un volumen compartido y la muestre en la terminal.

La tercera opción ofrece la mejor experiencia — la URL pública aparece automáticamente en la terminal de VS Code al iniciar el contenedor, sin inspección manual de logs.

5. Fija Versiones de Imagen en Equipos de Producción

Para experimentación individual, cloudflare/cloudflared:latest o openziti/zrok:latest está bien. Para DevContainers de equipo en un repositorio, fija a un digest o etiqueta de versión específica. Esto evita que una actualización silenciosa de la imagen upstream rompa el entorno de todos simultáneamente, especialmente porque cloudflared y zrok lanzan versiones con frecuencia.

image: cloudflare/cloudflared:2025.2.0

Todo Junto: Un Flujo de Trabajo Completo

Aquí la experiencia completa del desarrollador cuando esto está configurado correctamente:

  1. El desarrollador clona el repositorio.
  2. VS Code detecta .devcontainer/devcontainer.json y pide reabrir en contenedor.
  3. Docker Compose levanta el contenedor app y el sidecar del túnel.
  4. El contenedor app realiza su check de salud; una vez saludable, inicia el sidecar.
  5. El sidecar se autentica, crea el túnel y escribe la URL pública en un volumen compartido.
  6. El postStartCommand lee la URL y la muestra en la terminal integrada.
  7. El desarrollador ve algo como https://mi-proyecto.ejemplo.com en su terminal en segundos tras cargar el entorno.
  8. Pega esa URL en la configuración de webhook de Stripe y empieza a programar.
  9. Cuando ejecuta Ctrl+C y se detiene el contenedor, el túnel se destruye. No se necesita limpieza.

Sin herramientas instaladas en host. Sin gestión manual de tokens. Sin conflictos de puertos. Sin URLs obsoletas apuntando a un portátil que ya cerró.


Conclusión

El patrón de proxy sidecar en DevContainer no es una curiosidad arquitectónica de nicho — es la forma correcta de manejar túneles localhost en 2026. Ya sea que elijas Cloudflare Tunnel por su fiabilidad gestionada, zrok por su modelo efímero de confianza cero, o pgrok por su control completo de infraestructura, el principio es el mismo: la infraestructura de túnel debe estar dentro de la definición del contenedor, controlada por versión junto al código, no instalada ad-hoc en la máquina del desarrollador.

El resultado es una incorporación más rápida, mejor postura de seguridad, comportamiento de red reproducible y el fin de los errores de “funciona en mi máquina” relacionados con túneles. Docker fue diseñado para encapsular exactamente este tipo de preocupaciones operativas. Úsalo.

Continue from this article into the most relevant product guides and workflows.

Related Topics

#DevContainer sidecar proxy, docker localhost tunnel, devcontainer.json networking, isolated proxy container, ephemeral localhost tunnels, Cloudflared devcontainer sidecar, Zrok docker sidecar, zero-install dev networking, infrastructure as code tunnels, local development security, preventing host machine pollution, secure Docker networking, automated tunnel deployment, reverse proxy container, isolated development environments, cloud-native local development, tunneling inside containers, embedded proxy agent, developer environment standardization, devops localhost routing, immutable dev environments, secure webhook testing Docker, declarative development infrastructure

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles