Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Infrastructure & Operations11 min read

Custom Network Design for Containerized Blockchain Workloads

A practical guide to building, isolating, and verifying custom container networks for blockchain nodes, RPC clients, and supporting services.

TL;DR

A custom network is a user-defined container network that gives you control over which services can reach each other, how names resolve, and whether traffic can leave the host. For blockchain infrastructure, this matters because nodes, RPC clients, indexers, and monitoring agents have very different exposure requirements. This article explains the mental model behind custom networks, shows runnable Docker and Podman procedures, and describes how to verify isolation and DNS behavior without guessing at results. It also covers common failure modes and the tradeoffs between bridge, internal, overlay, and host-adjacent designs.

Scope and the direct answer

A custom network is a network you define yourself rather than relying on a runtime default. In Docker and Podman, the most common form is a user-defined bridge network: containers attached to it get automatic name-based DNS resolution, a dedicated subnet, and isolation from containers that are not attached. You create it with a command such as docker network create or podman network create, then attach workloads with --network.

For blockchain workloads, the useful pattern is to separate planes of communication. A node's peer-to-peer traffic, an RPC client's access to that node, and an operator's SSH or metrics access should not all share one flat network. A custom network lets you place the node and its trusted clients together while keeping unrelated containers out.

This guide assumes you already have a container runtime installed and that you are comfortable with basic docker run or podman run commands. It does not assume any specific chain, provider, or host operating system.

  • Custom bridge networks provide DNS-based service discovery by container name.
  • Internal networks block outbound access to the host LAN and the internet.
  • Overlay networks extend a custom network across multiple hosts.
  • Host networking bypasses isolation and should be a deliberate exception.

Prerequisites and assumptions

You need a Linux host or a Docker Desktop environment with permission to create networks. Rootless Podman works for most of the examples, but subnet and port-binding behavior can differ from rootful mode. Confirm your runtime version before relying on driver-specific flags.

You also need a plan for what each container should reach. Write it down before creating anything: which services talk to each other, which need outbound internet access, and which ports must be published to the host. That plan becomes your verification checklist later.

docker version
docker network ls
podman version
podman network ls

Mental model: names, subnets, and isolation boundaries

A custom bridge network is a virtual switch with its own subnet. Each attached container gets an interface on that switch. The runtime runs an embedded DNS resolver so that a container named node-a can be reached by other containers on the same network using that name. This is the main practical difference from the default bridge, where name resolution is limited.

Isolation is a property of attachment, not of the container itself. A container is isolated from another container only if they share no network. If you attach a container to two custom networks, it becomes a router between them, which may be exactly what you want for a proxy or gateway, and exactly what you do not want for a database.

An internal network adds a second boundary: containers on it can talk to each other but cannot reach outside the host. That is useful for a backend service that should only be reached through a reverse proxy on a separate network.

  • One network per trust boundary is usually clearer than one large shared network.
  • Name resolution is scoped to the network, so duplicate names on different networks do not collide.
  • Publishing a port with -p creates a host-facing path that bypasses network isolation for that port.

Creating a custom bridge network with Docker

The following procedure creates a custom bridge network with an explicit subnet, then runs two containers on it. Replace the image names with your own node and client images. The commands are illustrative and do not depend on a specific chain.

Choose a subnet that does not overlap with your host LAN, VPN, or other container networks. Overlapping subnets are a common cause of routing surprises.

docker network create \
  --driver bridge \
  --subnet 172.28.0.0/24 \
  --gateway 172.28.0.1 \
  node-net

docker run -d --name node-a --network node-net \
  --restart unless-stopped \
  your-node-image:latest

docker run -d --name rpc-client --network node-net \
  your-client-image:latest sleep infinity

docker network inspect node-net

Creating an internal custom network with Podman

Podman uses the same concepts with slightly different defaults. The --internal flag creates a network with no external connectivity. This is appropriate for a backend service that should only be reached by containers on the same network.

After creating the network, run a container on it and confirm that it can resolve a peer by name but cannot reach a public address. The exact error message depends on the runtime and kernel, so treat the observed failure as the verification signal rather than expecting one specific string.

podman network create \
  --subnet 10.89.0.0/24 \
  --internal \
  backend-net

podman run -d --name backend-api --network backend-net \
  your-api-image:latest

podman run --rm --network backend-net your-tools-image:latest \
  sh -c 'getent hosts backend-api; curl -sS --max-time 5 https://example.com || echo outbound-blocked'

Verifying DNS resolution and isolation

Verification should be a repeatable procedure, not a one-time glance. Run the same checks after every change to the network topology. The table below is a template: fill in the observed result for your environment rather than assuming a value.

CheckCommand patternExpected signalObserved result
Name resolutiongetent hosts node-a from a peer containerReturns an address on the custom subnetRecord your output
Cross-network isolationPing a container on a different networkFails or times outRecord your output
Outbound access on internal netcurl a public URLBlockedRecord your output
Published port reachabilitycurl the host port from outsideSucceeds only for ports you publishedRecord your output
DNS after restartRe-run name resolution after restarting a containerStill resolvesRecord your output

If a check does not match the expected signal, stop and fix the topology before adding more services. Layering more containers on a broken network makes the failure harder to isolate.

docker exec rpc-client getent hosts node-a
docker exec rpc-client sh -c 'curl -sS --max-time 5 http://node-a:8545/health || true'
docker run --rm --network bridge your-tools-image:latest \
  sh -c 'getent hosts node-a || echo not-visible-from-default-bridge'

Connecting a client to a node over the custom network

Once the network is in place, clients should address the node by container name rather than by a hard-coded IP. This keeps configuration stable when containers restart and receive new addresses. The example below uses a placeholder RPC URL that resolves through the custom network.

If your client needs to reach a public RPC endpoint as well, attach it to a second, non-internal network. That makes the client a deliberate bridge between the isolated node network and the outside world, which is easier to audit than giving every container outbound access.

export RPC_URL=http://node-a:8545

curl -sS -X POST "$RPC_URL" \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'

Troubleshooting common custom network failures

Most custom network problems fall into a small number of categories. Name resolution failures usually mean the containers are not on the same network, or the client is using an IP that changed after a restart. Outbound failures on an internal network are expected behavior, not a bug. Port conflicts usually mean a published port is already bound on the host.

If a container can reach a peer by IP but not by name, check that both are attached to the same user-defined network and that the runtime's DNS resolver is running. If a container cannot reach anything at all, inspect the network and confirm the subnet does not overlap with an existing route.

  • Container name resolution fails: confirm both containers share the same custom network.
  • Subnet overlap: choose a range outside your host LAN and VPN ranges.
  • Port already allocated: change the host-side port or stop the conflicting process.
  • Internal network blocks expected traffic: move the service to a non-internal network or add a proxy.
  • Host access to custom networks behaves differently across platforms: verify on the target host, not only on a laptop.

Limitations and tradeoffs

Custom networks add operational overhead. Every new network is another object to name, document, and clean up. Overlay networks add latency and require a working cluster control plane. Internal networks are secure by default but inconvenient when a service legitimately needs to fetch updates or reach a public RPC endpoint.

Host networking is sometimes used to avoid NAT and port publishing, but it removes the isolation boundary entirely. For blockchain nodes that expose RPC or peer ports, that tradeoff deserves explicit review. In most cases a custom bridge network with narrowly published ports is easier to reason about.

If your goal is simply to choose a reliable public RPC endpoint rather than to design container networking, that decision belongs in a provider comparison rather than here. Use the RPC Assistant for concrete endpoint and provider recommendations, and keep this guide for the network topology around your own infrastructure.

Next steps for production readiness

Turn the verification table into a script that runs after every deployment. Store the network definitions in version control alongside your compose files or deployment manifests. Document which network each service belongs to and why.

For teams running dedicated infrastructure, review how node hosting and RPC service tiers fit your topology. The blockchain node hosting guide covers operational concerns beyond networking, and the multi-chain RPC endpoints guide explains how clients should be configured across chains. If you are comparing managed options, see RPC pricing and dedicated nodes.

Finally, decide where the boundary between your custom network and external services sits. A common pattern is an internal network for the node and its trusted clients, plus a narrow egress path through a proxy. That keeps the blast radius small while still allowing the node to sync.

  • Version-control network definitions and verification scripts.
  • Re-run isolation checks after every topology change.
  • Keep public exposure limited to the ports you intentionally publish.
  • Use RPC Assistant when the remaining question is which endpoint or provider to use.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started