None Network #

Among all the network drivers Docker offers, none is the simplest conceptually and the least often discussed seriously. When a container runs with --network none, it has no network interface at all — not bridge, not host, not overlay. Only one interface exists: lo (loopback). The container is truly offline.

At first glance, this sounds useless. Why run a container that can’t talk to anyone? But that’s exactly where its power lies: there are many workloads that simply must not talk to the outside. Batch jobs processing local files, security sandboxes running untrusted code, even containers deliberately isolated for auditing — all are ideal use cases for the none network.

This article covers none networking in depth: how it works at the OS level, when to use it, when not to use it, and how to combine it with other patterns for extra isolation. By the end, you’ll understand why this seemingly “useless” mode is actually one of Docker’s sharpest security tools.

What Is the None Network? #

None networking is a mode where Docker doesn’t create any network interface for the container. No veth, no bridge, no external IP address. The container only has the lo (loopback) interface that exists on every Unix-like OS.

flowchart TB
    subgraph HOST["Docker Host"]
        H_NET[Host Network]
    end
    subgraph CT["Container (none network)"]
        LO[lo: 127.0.0.1]
    end
    HOST -. X no link .-> CT

Main characteristics:

  • No eth0, no IP address from DHCP or IPAM.
  • No internet or host network access.
  • No communication with other containers, except via filesystems or stdin/stdout.
  • Only internal communication via 127.0.0.1 (loopback) inside the container itself.
  • No port mapping — impossible because there’s no interface.
  • Maximum network isolation — network attack surface = 0.
Loopback still exists: localhost inside the container points to the container itself, not the host or other containers. This is useful for applications listening on 127.0.0.1 that should only be accessed internally (e.g. an admin UI reverse-proxied via a UNIX socket).

How It Works at the OS Level #

To understand none networking, you need to understand two things: how Docker normally creates interfaces, and what it doesn’t do in none mode.

When a Normal Container Runs (Bridge) #

flowchart LR
    H_BR[bridge: docker0<br/>172.17.0.1] -->|veth| C_ETH[eth0: 172.17.0.2]
    H_BR -->|iptables NAT| H_ETH[host eth0]

Docker creates:

  • A veth pair — the virtual cable between container and host.
  • A bridge interface — the virtual switch connecting many containers.
  • An IP address from the bridge subnet.
  • A default route through the bridge gateway.
  • iptables rules for outbound NAT and inbound DNAT.

When a Container Is on the None Network #

flowchart LR
    C_LO[lo: 127.0.0.1]
    C_NO[eth0: DOESN'T EXIST]
    ROUTE[Default route: DOESN'T EXIST]

Docker creates very little:

  • Loopback lo — always present, only 127.0.0.1.
  • No veth — no cable to the host.
  • No eth0 — no external interface.
  • No default route — no way out.
  • No iptables rules for this container — nothing to NAT.

The result: the container is a totally isolated process at the network level. It still has its own namespaces (PID, mount, UTS, IPC), but its network namespace contains only lo.


How to Run a Container with None Networking #

# CLI way
docker run -d --network none --name isolated alpine sleep 3600

# Check the interfaces inside the container
docker exec isolated ip addr show

Output:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever

Only lo. No eth0, no other IPs.

Check routing:

docker exec isolated ip route

Output:

# (empty - no routes, including no default)

Check connectivity:

docker exec isolated ping -c 1 8.8.8.8
# ping: connect: Network is unreachable

docker exec isolated wget -qO- http://google.com
# wget: unable to resolve host address 'google.com'
# (even DNS fails because there's no resolver)
There’s still no DNS resolver: Even Docker’s internal DNS (127.0.0.11) is inactive on none networks. The container is completely cut off from all DNS systems. Every dependency must already exist inside the image.

Docker Compose with None Networking #

version: "3.9"
services:
  batch-processor:
    image: my-batch:v1
    network_mode: none
    volumes:
      - ./input:/data/input:ro
      - ./output:/data/output:rw

This container:

  • Reads files from /data/input (volume).
  • Processes files locally.
  • Writes results to /data/output (volume).
  • Never talks to the internet or other containers.

Fits offline ETL, image processing, transcoding, or any workload working purely on local data.


Use Case: Batch Jobs and Offline Processing #

Batch jobs are the clearest use case. If a process only needs file input/output and no network, the none network provides:

  • Security — no accidental data egress path.
  • Performance — no networking overhead; the container focuses on CPU/disk.
  • Predictability — deterministic batch jobs, no “internet went down” variable.

Concrete examples:

# Image processing pipeline
docker run --rm --network none \
  -v $PWD/photos:/photos:ro \
  -v $PWD/thumbs:/thumbs:rw \
  image-processor \
  --input /photos --output /thumbs --size 256x256
# Video transcoding
docker run --rm --network none \
  -v $PWD/videos:/videos:rw \
  jrottenberg/ffmpeg \
  -i /videos/input.mov -c:v libx264 /videos/output.mp4
# CSV to Parquet
docker run --rm --network none \
  -v $PWD/data:/data:rw \
  csv-to-parquet:latest \
  --input /data/raw.csv --output /data/processed.parquet
A general principle: if your batch job works entirely on the filesystem, enable --network none. This removes one class of problems (network flakiness) and one attack vector (network exfiltration).

Use Case: Security Sandboxes for Untrusted Code #

One of the most valuable use cases: running untrusted code with minimal risk. Code injections, third-party scripts, ML models from unclear sources — all can be put into a none-network container.

# Run a script from an untrusted user
docker run --rm --network none \
  --read-only \
  --tmpfs /tmp:size=10m \
  --cpus=1 --memory=256m \
  --user 1000:1000 \
  python:3.12-slim \
  python /mnt/user-script.py

The combination of none network + read-only + tmpfs + resource limits + non-root is Docker’s strongest sandbox pattern. It isn’t perfect (kernel exploit risk remains), but for application-level threats it’s very effective.

Defense in Depth #

flowchart TB
    A[Untrusted Code] --> B[Container]
    B --> C[none network]
    B --> D[read-only fs]
    B --> E[--user 1000]
    B --> F[--memory 256m]
    B --> G[--cpus 1]
    B --> H[--cap-drop ALL]

    style C fill:#dfd
    style D fill:#dfd
    style E fill:#dfd
    style F fill:#dfd
    style G fill:#dfd
    style H fill:#dfd

Each layer adds isolation. The none network is the layer that closes network-based vectors: data exfiltration, command & control callbacks, internal service scanning. Without a network, many modern attacks fail immediately.


Use Case: CI/CD Build Steps That Don’t Need the Network #

CI/CD often runs build steps that shouldn’t need the internet. The image is already pulled, dependencies already cached. A build step that downloads again is a code smell — and a security risk.

# GitHub Actions - build step without network
jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: my-build-image:latest
      options: --network none
    steps:
      - uses: actions/checkout@v4
      - run: make build
      - run: make test

With --network none, the build step is guaranteed deterministic and safe: nothing downloads extra binaries, nothing fetches uncached dependencies. If the build succeeds, its dependability is assured.

A bug commonly exposed by none networking: applications that silently fetch configuration from the internet at startup. When --network none is enabled, the app crashes because it can’t reach the endpoint. That’s a sign of fragile architecture — configuration should be embedded in the image, not fetched at runtime.

Use Case: Applications with Offline Sidecars #

An interesting pattern: offline sidecar containers running in none mode for housekeeping.

version: "3.9"
services:
  app:
    image: my-app
    networks: [app-net]
  
  audit-log:
    image: log-rotator
    network_mode: none
    volumes:
      - app-logs:/var/log/app:ro
      - archive:/archive:rw
    # Rotate log files without a network

audit-log reads logs from a volume, compresses them, and writes an archive. It doesn’t need to talk to anyone. With the none network, it’s guaranteed not to suddenly upload logs outside.


Comparison with Bridge Networking #

Aspectnonebridge
IP AddressNoneAutomatic
Internet AccessNoYes (via NAT)
Inter-Container CommunicationNoYes (same bridge)
Internal DNSNoYes (user-defined)
Port MappingNot possibleYes (-p)
veth pairNoneYes
iptables rulesMinimal (or none)Complete
Use caseSandboxes, batch, securityMulti-container apps
Network overheadZeroStandard
Don’t equate none with “no network at all”. Loopback 127.0.0.1 still exists, and applications inside the container can still listen on a loopback port (e.g. an admin UI). What’s lost is the ability to exit to other networks. 127.0.0.1 is the container itself, not the host or other containers.

When None Networking Should NOT Be Used #

1. Web / API Server Applications #

Web servers need to receive requests and responses. No network = no requests arrive.

# ✗ Anti-pattern: web server without a network
docker run --network none -p 80:80 nginx
# The container runs but nobody can connect
# -p is ignored because there's no interface

2. Databases with Clients in Other Containers #

A database on the none network = clients can’t connect. Databases must be on the same bridge network as their clients.

3. Services Needing Updates / Image Pulls #

Containers that download something at runtime (apt-get update, pip install, npm install) need a network. Build dependencies must already be in the image.

4. Network-Based Health Checks #

Network health checks (HTTP endpoints, TCP connects) won’t work on the none network. Use process- or file-based health checks.

services:
  worker:
    image: my-worker
    network_mode: none
    healthcheck:
      test: ["CMD", "test", "-f", "/tmp/worker.alive"]
      interval: 30s

Combining with Manual Networking (Advanced) #

For rare cases, you can add a network manually to a none container after it’s running. This gives you full control over when the container may talk to the network.

# 1. Create a container with none networking
docker run -d --network none --name audit alpine sleep 3600

# 2. When communication is needed, connect to a network (if host policy allows)
docker network connect bridge audit

# 3. Do the communication
docker exec audit ping -c 1 172.17.0.3

# 4. Disconnect again
docker network disconnect bridge audit

This is rarely used, but useful for:

  • Emergency debugging — open the network briefly, inspect, close it again.
  • Conditional connectivity — containers normally offline, but enable the network for periodic sync.
  • Privileged operations — admins can attach a network during troubleshooting.
Be careful: giving a none container network access in production must go through very strict controls. This is one of the patterns attackers often use to escape a sandbox. Audit every docker network connect to a container that was originally none.

None Network Best Practices #

✓ USE the none network if:
  ✓ Batch jobs / offline processing
  ✓ Sandboxes for untrusted code
  ✓ Already-deterministic CI/CD build steps
  ✓ Sidecar housekeeping (log rotation, metric aggregation)
  ✓ Fault-tolerance testing (check the app still runs without a network)
  ✓ Audit / compliance requirements (no network access)

✗ DON'T use the none network if:
  ✗ Web/API/worker apps that must receive requests
  ✗ Databases with clients
  ✗ Services needing to download dependencies
  ✗ Network-based health checks
  ✗ Containers needing sync to external systems

Common Anti-Patterns #

1. Using None for Apps That Need a Network #

# ✗ Anti-pattern: web server on the none network
docker run -d --network none -p 80:80 nginx
# The container crashes; host port 80 receives nothing
# ✓ Solution: bridge + port mapping
docker run -d --network app-net -p 80:80 nginx

2. Forgetting That DNS Is Also Gone #

# ✗ Anti-pattern: an app fetching config from the internet
docker run --network none my-app
# The app crashes because it can't resolve "config.example.com"

# ✓ Solution: embed the config in the image, or use bridge

3. Assuming -p Works on the None Network #

# ✗ Anti-pattern: using -p without a network
docker run -d --network none -p 8080:80 my-app
# -p is ignored. The container can't be reached.
# ✓ Solution: use bridge with -p, or host networking

None Networking for Compliance and Regulatory Requirements #

Some industries have regulations that explicitly forbid containers having network access. Finance, healthcare, and government have requirements that certain workloads must never talk to external systems at all.

# Example: HIPAA-compliant processing pod
apiVersion: v1
kind: Pod
metadata:
  name: phi-processor
spec:
  containers:
  - name: processor
    image: phi-processor:v1
    securityContext:
      runAsNonRoot: true
      runAsUser: 1000
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
    resources:
      limits:
        memory: "512Mi"
        cpu: "500m"
    volumeMounts:
    - name: data
      mountPath: /data
      readOnly: true
    - name: output
      mountPath: /output
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: phi-input
  - name: output
    persistentVolumeClaim:
      claimName: phi-output

On Kubernetes, you can enforce none-style networking with a NetworkPolicy denying all egress, or with an empty podSelector in the policy. The result: containers can only communicate via the filesystem, per regulation.

Compliance pattern: For workloads processing sensitive data (PHI, PII, financial data), combine the none network with a read-only filesystem, runAsNonRoot, and audit logging. This provides a clear audit trail: data enters via a volume, gets processed, exits via a volume — it never leaves the pod.

Summary #

  • None networking = a container with no network interface at all (except loopback). No eth0, no IP, no default route, no iptables rules.
  • The strongest network isolation among all network modes. Network attack surface = 0.
  • Good for: offline batch jobs, untrusted-code sandboxes, deterministic CI/CD build steps, sidecar housekeeping, audit/compliance.
  • Bad for: web servers, databases with clients, services downloading dependencies, network-based health checks.
  • The DNS resolver is also gone127.0.0.11 (Docker’s internal DNS) is inactive. All dependencies must be embedded in the image.
  • The security combination: none network + --read-only + --user non-root + --cap-drop ALL + resource limits = Docker’s strongest sandbox.
  • Unexpected usefulness: fault-tolerance testing — run the app with none and see what breaks. This exposes hidden network dependencies that are often the source of bugs.
  • Networks can be added manually via docker network connect, but this is an advanced pattern that must be strictly audited.
  • Anti-patterns: web servers on none, forgetting DNS is also gone, using -p on none (ignored).
  • A general principle: if a workload doesn’t need a network, disable the network. The default should be “least privilege” — open only what’s needed.

← Previous: Host Network   Next: Port Mapping & Exposure →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact