Oxcart Download
Menu

Container networking on a Mac: ports, VPN, DNS, Little Snitch and TLS

On a Mac, containers run on a Linux side behind the Mac's network, so ports, VPNs, DNS and firewalls depend on how the container app relays traffic. Oxcart opens every outbound connection from the Mac itself, so your VPN, DNS and Little Snitch rules apply to containers, and it encrypts the link between the Mac and the engine with TLS 1.3.

Updated

How container networking works on a Mac

macOS cannot run Linux containers directly, so every container app on the Mac runs them on a Linux side and relays traffic between it and the Mac. Three paths matter:

  • Inbound: a published port on the Mac forwards to a container.
  • Outbound: a container opens a connection to the internet, your company network, or a service on the Mac.
  • Names: a container looks up a hostname.

When these paths bypass the Mac's own networking, VPN routes don't apply, internal hostnames don't resolve, and a firewall can't see which app is talking. Oxcart is built so that they don't.

Outbound: your VPN, DNS and firewall still apply

Oxcart redirects outbound TCP from containers and build steps, IPv4 and IPv6, to the Mac, which opens the connection with its own sockets. The Mac's routing table decides where it goes, including routes your VPN client installs. Oxcart changes no Mac routes, VPN settings or firewall preferences.

Address lookups (A and AAAA) use the macOS system resolver, including /etc/hosts and the resolver selection your VPN configures, so company hostnames resolve in containers the way they do in your browser. Container names stay scoped to their Docker networks, and DNS works over UDP and TCP.

Little Snitch, LuLu and endpoint agents

A network filter often holds the first connection from a new program for about two seconds while it asks you. Oxcart does not wait on that: connections take a fallback path until the main link is proven, a slow or failed connection moves to the fallback on its own, and three failures in a row take the link down for 30 seconds before it is probed again. Approve Oxcart once in your filter and its rules apply from then on.

Inbound: published ports

Publish ports with the normal Docker syntax:

# 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

A binding without an address listens on all of the Mac's IPv4 addresses, which makes it reachable from other machines on your network unless the macOS firewall blocks them. TCP and UDP can use the same host port number. Published listeners are released when the container stops.

Published ports also answer on the engine's own localhost, so a registry you run in a container works as a push target:

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

The Ports view: why a port isn't answering

Oxcart's Ports view lists every listener on your Mac and every container port, grouped by repository, worktree and branch, so two checkouts of the same project don't blur together. Each binding is ready, pending or error, with the reason:

  • the address is already in use on the Mac;
  • the server inside the container listens only on 127.0.0.1;
  • nothing is listening on that port yet.

Ports that other machines can reach carry a marker. Your coding agent sees the same information through Oxcart's MCP ports tool; see Docker for AI coding agents.

Reaching the Mac from a container

host.docker.internal resolves in containers and in build steps, and reaches services bound to the Mac's 127.0.0.1 over TCP. Point a container at a database or a dev server running natively on the Mac:

docker run --rm curlimages/curl http://host.docker.internal:3000/health

Treat this as a deliberate opening: any container you run can reach services on your Mac's loopback this way, so don't leave unauthenticated admin services on 127.0.0.1 while running containers you don't trust.

The encrypted link between the Mac and the engine

Traffic between the Mac and the Linux side crosses a virtual network that macOS shares with other virtualization software on the same Mac. Oxcart carries published and outbound TCP on that link inside TLS 1.3 (TLS_AES_128_GCM_SHA256), pinned to a certificate made fresh at every engine start, with a 256-bit bearer token per start. An invalid token closes the connection, and the Linux side closes connections that don't come from the Mac's address before TLS begins.

The threat this addresses: other software on that shared network spoofing addresses to read or inject traffic, or to open new connections to your containers. A guest firewall also keeps that software away from unpublished container ports and the internal resolver. Encryption has a cost on that link, and it is a cost we chose. The Docker API itself never goes over the network: it is a private Unix socket, and with no ports published Oxcart holds no TCP or UDP socket on the Mac.

Current limits

  • Host network mode (--network host) and IPv6 container networking are not implemented; containers have IPv4 addresses.
  • host.docker.internal carries TCP; UDP to the host gateway is not implemented.
  • Published TCP and UDP don't preserve the client's address: the container sees the Linux side as the peer.
  • Non-address DNS records (such as SRV and TXT) use the network's DHCP resolvers rather than macOS split DNS.

Troubleshooting

Container networking problems on a Mac and their fixes
SymptomLikely causeFix
Connection refused on localhost:PORTServer listens on 127.0.0.1 inside the containerListen on 0.0.0.0; the Ports view names this case
"port is already allocated"Another process or container holds the host portPick another host port; the Ports view shows the owner
Internal hostname doesn't resolve in a containerName only exists on your VPN's DNSConnect the VPN on the Mac; address lookups follow the Mac's resolver
Container can't reach a dev server on the MacUsing localhost inside the containerUse host.docker.internal
First pull stalls for a couple of secondsA network filter is asking about a new connectionApprove Oxcart once; connections use the fallback meanwhile
Teammates can reach your dev portPublished without an addressPublish to 127.0.0.1

Questions

Do Docker containers on a Mac use my VPN?

In Oxcart, yes. Outbound connections from containers are opened by the Mac itself, so the Mac's routes, VPN, split DNS for address lookups and per-app firewall apply to them. Oxcart changes no Mac routes, VPN settings or firewall preferences.

How do I reach a service on my Mac from a container?

Use host.docker.internal. In Oxcart it reaches services bound to the Mac's 127.0.0.1 over TCP, from containers and from build steps. --add-host mac:host-gateway gives you another name for the same address.

Why can I see the container running but not reach its port?

Usually the server inside the container listens on 127.0.0.1, which published ports cannot reach; make it listen on 0.0.0.0. The other causes are a host port already in use or nothing listening yet. Oxcart's Ports view shows which one it is.

Does Oxcart work with Little Snitch and LuLu?

Yes. When a network filter holds Oxcart's first connection while it asks you, connections take a fallback path until the link is proven, so nothing breaks or waits on your answer. A slow or failed connection moves to the fallback on its own.

Is container traffic encrypted on my Mac?

Published and outbound TCP between the Mac and Oxcart's engine travels inside TLS 1.3, pinned to a certificate made at every engine start, with a 256-bit token per start. It protects that link from other virtualization software on your Mac's shared network. Traffic to the internet is protected by whatever the app itself uses, such as HTTPS.

Are my published ports visible to other machines on my network?

A port published without an address listens on all of the Mac's IPv4 addresses, so other machines can reach it unless the macOS firewall blocks them. Publish to 127.0.0.1 to keep it on your Mac. Oxcart marks ports that other machines can reach.

Does Oxcart support host networking or IPv6 for containers?

No. Host network mode and IPv6 container networking are not implemented. Containers have IPv4 addresses; ports can still be published on IPv6 with "[::]:8080:80".

Sources and method

Networking behavior described here was tested on Oxcart on October 10, 2026, including outbound TCP, DNS, published ports, host access and TLS on the Mac-to-container link.

Try Oxcart on your own projects

Free for 60 days. Then $20 per user, per major version: not a subscription.

Apple silicon · macOS 26 or later

Read next

Release notes

Oxcart 0.1.4

Latest release

Licensing and refinements.

  • Secure email-link license activation.
  • License and Mac management from Settings.
  • Offline license verification.
  • Performance improvements, UI polish, and bug fixes.

Requires macOS 26.0 or later

Oxcart 0.1.3

Idle memory reclamation.

  • Reclaims VM memory when no containers are running.
  • Preserves containers, images, volumes, and networks.

Requires macOS 26.0 or later

Oxcart 0.1.2

Command-line tool integration.

  • Switch between Oxcart's bundled Docker tools and an existing installation.
  • UI polish.

Requires macOS 26.0 or later

Oxcart 0.1.1

Bundled Docker tools and agent controls.

  • Docker CLI 29.9, Compose 5.6, and Buildx 0.38 included.
  • Docker context integration and secure Keychain credentials.
  • MCP agent connections with per-agent permissions and blocking.

Requires macOS 26.0 or later

Oxcart 0.1.0

Docker-compatible containers for Apple silicon.

  • Docker CLI, Compose, and Buildx compatibility.
  • Offline setup with bundled runtime components.
  • Ports organized by project and Git branch.
  • MCP integration with read-only access by default.
  • Verified automatic updates.

Requires macOS 26.0 or later