Cómo funcionan las redes de contenedores en Mac
macOS no puede ejecutar contenedores Linux directamente, así que cada app de contenedores en Mac los ejecuta en un entorno Linux y transmite el tráfico entre este y el Mac. Hay tres recorridos importantes:
- Entrante: un puerto publicado en el Mac reenvía el tráfico a un contenedor.
- Saliente: un contenedor abre una conexión a Internet, a la red de tu empresa o a un servicio del Mac.
- Nombres: un contenedor resuelve un nombre de host.
Cuando estos recorridos eluden la red del propio Mac, las rutas de VPN no se aplican, los nombres de host internos no se resuelven y un firewall no puede ver qué app se comunica. Oxcart está diseñado para evitarlo.
Saliente: tu VPN, DNS y firewall siguen aplicándose
Oxcart redirige el TCP saliente de contenedores y pasos de compilación, tanto IPv4 como IPv6, al Mac, que abre la conexión con sus propios sockets. La tabla de rutas del Mac decide por dónde pasa, incluidas las rutas que instala tu cliente VPN. Oxcart no cambia las rutas del Mac, la configuración de VPN ni las preferencias del firewall.
Las consultas de direcciones (A y AAAA) usan el resolvedor del sistema macOS, incluidos /etc/hosts y la selección de resolvedores configurada por tu VPN, de modo que los nombres de host de la empresa se resuelven en los contenedores como en tu navegador. Los nombres de los contenedores permanecen limitados a sus redes Docker, y el DNS funciona por UDP y TCP.
Little Snitch, LuLu y agentes de seguridad del equipo
Un filtro de red suele retener la primera conexión de un programa nuevo unos dos segundos mientras te pide permiso. Oxcart no espera: las conexiones toman una ruta alternativa hasta que se verifica el enlace principal; una conexión lenta o fallida cambia automáticamente a esa ruta. Tres fallos seguidos desactivan el enlace durante 30 segundos antes de comprobarlo de nuevo. Autoriza Oxcart una vez en tu filtro y sus reglas se aplicarán a partir de entonces.
Entrante: puertos publicados
Publica puertos con la sintaxis habitual de Docker:
# Mac loopback only (recommended for development)
docker run -d -p 127.0.0.1:8080:80 nginx
# Ephemeral host port, UDP
docker run -d -p 127.0.0.1::9000/udp my-udp-service
# IPv4 and IPv6 listeners on the Mac
docker run -d -p "[::]:8080:80" nginx Una vinculación sin dirección escucha en todas las direcciones IPv4 del Mac, por lo que otros equipos de tu red pueden alcanzarla salvo que el firewall de macOS los bloquee. TCP y UDP pueden usar el mismo número de puerto del host. Los puertos de escucha publicados se liberan cuando el contenedor se detiene.
Los puertos publicados también responden en el localhost del propio motor, así que un registro que ejecutes en un contenedor funciona como destino de envío:
docker run -d -p 127.0.0.1:5000:5000 --name registry registry:2
docker tag my-app localhost:5000/my-app
docker push localhost:5000/my-app La vista Ports: por qué un puerto no responde
La vista Ports de Oxcart muestra todos los puertos de escucha del Mac y todos los puertos de contenedores, agrupados por repositorio, worktree y rama, para distinguir dos copias de trabajo del mismo proyecto. Cada vinculación aparece como ready, pending o error, con el motivo:
- la dirección ya se está usando en el Mac;
- el servidor del contenedor solo escucha en
127.0.0.1; - todavía no hay nada escuchando en ese puerto.
Los puertos accesibles desde otros equipos llevan una marca. Tu agente de programación ve la misma información mediante la herramienta MCP ports de Oxcart; consulta Docker para agentes de programación con IA.
Acceder al Mac desde un contenedor
host.docker.internal se resuelve en los contenedores y en los pasos de compilación, y llega por TCP a los servicios vinculados a 127.0.0.1 del Mac. Dirige un contenedor a una base de datos o a un servidor de desarrollo que se ejecute de forma nativa en el Mac:
docker run --rm curlimages/curl http://host.docker.internal:3000/health Trátalo como una apertura deliberada: cualquier contenedor que ejecutes puede alcanzar así los servicios de la interfaz de bucle local de tu Mac. No dejes servicios de administración sin autenticación en 127.0.0.1 mientras ejecutas contenedores en los que no confías.
El enlace cifrado entre el Mac y el motor
El tráfico entre el Mac y el entorno Linux atraviesa una red virtual que macOS comparte con otros programas de virtualización del mismo Mac. Oxcart transporta el TCP publicado y saliente de ese enlace dentro de TLS 1.3 (TLS_AES_128_GCM_SHA256), fijado a un certificado nuevo en cada arranque del motor, con un token Bearer de 256 bits por arranque. Un token no válido cierra la conexión, y el entorno Linux cierra las conexiones que no proceden de la dirección del Mac antes de iniciar TLS.
La amenaza que evita: otros programas de esa red compartida que suplanten direcciones para leer o inyectar tráfico, o abrir nuevas conexiones a tus contenedores. Un firewall del sistema invitado también mantiene a esos programas alejados de los puertos de contenedores no publicados y del resolvedor interno. El cifrado tiene un coste en ese enlace, y lo hemos elegido conscientemente. La API Docker nunca pasa por la red: es un socket Unix privado y, sin puertos publicados, Oxcart no mantiene ningún socket TCP o UDP en el Mac.
Límites actuales
- El modo de red del host (
--network host) y las redes IPv6 de contenedores no están implementados; los contenedores tienen direcciones IPv4. host.docker.internaltransporta TCP; UDP hacia la puerta de enlace del host no está implementado.- El TCP y UDP publicados no conservan la dirección del cliente: el contenedor ve el entorno Linux como interlocutor.
- Los registros DNS que no son direcciones (como SRV y TXT) usan los resolvedores DHCP de la red en lugar del DNS dividido de macOS.
Resolución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
Conexión rechazada en localhost:PORT | El servidor escucha en 127.0.0.1 dentro del contenedor | Escuchar en 0.0.0.0; la vista Ports identifica este caso |
| «port is already allocated» | Otro proceso o contenedor ocupa el puerto del host | Elegir otro puerto del host; la vista Ports muestra quién lo ocupa |
| Un nombre de host interno no se resuelve en un contenedor | El nombre solo existe en el DNS de tu VPN | Conectar la VPN en el Mac; las consultas de direcciones siguen el resolvedor del Mac |
| El contenedor no alcanza un servidor de desarrollo del Mac | Se usa localhost dentro del contenedor | Usar host.docker.internal |
| La primera descarga se queda parada unos segundos | Un filtro de red está preguntando por una conexión nueva | Autorizar Oxcart una vez; las conexiones usan mientras tanto la ruta alternativa |
| Tus compañeros pueden acceder a tu puerto de desarrollo | Publicado sin dirección | Publicar en 127.0.0.1 |
Preguntas
¿Los contenedores Docker en Mac usan mi VPN?
En Oxcart, sí. El propio Mac abre las conexiones salientes de los contenedores, así que se aplican sus rutas, VPN, DNS dividido para consultas de direcciones y firewall por aplicación. Oxcart no cambia las rutas del Mac, la configuración de VPN ni las preferencias del firewall.
¿Cómo accedo desde un contenedor a un servicio de mi Mac?
Usa host.docker.internal. En Oxcart llega por TCP a los servicios vinculados a 127.0.0.1 del Mac, desde contenedores y pasos de compilación. --add-host mac:host-gateway te da otro nombre para la misma dirección.
¿Por qué veo el contenedor en ejecución pero no puedo acceder a su puerto?
Normalmente, el servidor dentro del contenedor escucha en 127.0.0.1, que los puertos publicados no pueden alcanzar; haz que escuche en 0.0.0.0. Las otras causas son un puerto del host ya ocupado o que todavía no haya nada escuchando. La vista Ports de Oxcart muestra cuál es el caso.
¿Oxcart funciona con Little Snitch y LuLu?
Sí. Cuando un filtro de red retiene la primera conexión de Oxcart mientras te pide permiso, las conexiones toman una ruta alternativa hasta que se verifica el enlace, así que nada falla ni espera tu respuesta. Una conexión lenta o fallida cambia automáticamente a la ruta alternativa.
¿El tráfico de los contenedores está cifrado en mi Mac?
El TCP publicado y saliente entre el Mac y el motor de Oxcart viaja dentro de TLS 1.3, fijado a un certificado creado en cada arranque del motor, con un token de 256 bits por arranque. Esto protege ese enlace frente a otros programas de virtualización de la red compartida de tu Mac. El tráfico a Internet se protege con lo que use la propia app, como HTTPS.
¿Mis puertos publicados son visibles para otros equipos de mi red?
Un puerto publicado sin dirección escucha en todas las direcciones IPv4 del Mac, por lo que otros equipos pueden alcanzarlo salvo que el firewall de macOS los bloquee. Publícalo en 127.0.0.1 para limitarlo a tu Mac. Oxcart marca los puertos accesibles desde otros equipos.
¿Oxcart admite la red del host o IPv6 para contenedores?
No. El modo de red del host y las redes IPv6 de contenedores no están implementados. Los contenedores tienen direcciones IPv4; aun así, se pueden publicar puertos en IPv6 con "[::]:8080:80".
Fuentes y método
El comportamiento de red descrito aquí se probó en Oxcart el 10 de octubre de 2026, incluidos TCP saliente, DNS, puertos publicados, acceso al host y TLS en el enlace entre el Mac y los contenedores.