Container Networking Basics: How Containers Talk to Each Other and the World

Containers are isolated by default, yet they still need to reach each other, the host, and the internet. Learn how container networking works — virtual networks, port publishing, DNS between containers, and the bridge that ties it all together — explained from zero.

Published October 21, 202611 min readBy ACY Partner Indonesia
Container networking — containers connected over a virtual bridge network
300 × 250Ad Space AvailablePlace your ad here

A container is built to be isolated — its own filesystem, its own processes, its own little world. That isolation is exactly what makes containers so useful. But the moment you run more than one container, or you want anyone outside to actually use what’s inside, a question shows up fast: how do these sealed-off boxes talk to each other, to the machine running them, and to the wider internet?

That’s the job of container networking. It sounds intimidating, and it has a reputation for being the part of containers where people get stuck. The good news is that underneath the jargon there are only a handful of ideas, and once they click, almost every networking surprise you’ll hit starts to make sense. Let’s build it up from the ground.

Why containers need networking at all

Picture a typical setup: a web app in one container, a database in another, maybe a cache in a third. The web app needs to send queries to the database. Visitors on the internet need to reach the web app. The database, ideally, should not be reachable from the internet at all — only the web app should be able to see it.

None of that works if every container is a perfectly sealed box. So container platforms give each container a network connection, the same way plugging a network cable into a real computer would. The difference is that all of this is virtual — there are no physical cables, no physical switches. The platform creates software versions of those things and wires your containers into them.

If you’ve read about how a container isolates a process, networking is the deliberate, controlled hole you poke in that isolation so the container can be useful. The whole art of container networking is opening just enough of a hole — and no more.

Each container gets its own network identity

When a container starts, the platform typically gives it its own virtual network interface and its own private IP address. This is the first idea to internalize: a container usually has a different IP from the host machine it runs on.

So if your host has an IP like 192.168.1.50, a container running on it might get something like 172.17.0.2 on an internal, private network that only exists inside that host. From the container’s point of view, it looks like a normal little computer with a normal network connection.

  HOST MACHINE  (IP 192.168.1.50)
  ┌──────────────────────────────────────────┐
  │                                          │
  │   container A          container B       │
  │   172.17.0.2           172.17.0.3        │
  │      │                     │             │
  │      └──────── bridge ──────┘            │
  │             (172.17.0.1)                 │
  │                  │                       │
  └──────────────────┼───────────────────────┘

                  the internet

Those private addresses live on a virtual network the platform sets up. Containers on the same virtual network can reach each other directly using those addresses. Containers on different networks can’t — and that separation is a feature, not a bug. It’s how you keep your database invisible to everything except the services that should see it.

Private IPs are temporary and internal

A container’s private IP is assigned by the platform and can change every time the container restarts. It also only means anything inside that host’s virtual network — you can’t type 172.17.0.2 into a browser on your phone and reach anything. That’s why, as you’ll see, we almost never hardcode container IPs. We use names instead.

The bridge: the virtual switch in the middle

Look again at the diagram above and notice the thing in the middle labelled bridge. This is the single most important piece to understand, and it’s where the word “bridge network” comes from.

A bridge is a virtual switch. In the physical world, a network switch is the box you plug several computers into so they can talk to one another. The bridge does exactly that, but in software. When the platform starts, it creates a default bridge, gives it an address (often something like 172.17.0.1), and every container you run gets connected to it unless you say otherwise.

Because all those containers share one bridge, they all sit on the same little private network and can reach each other. The bridge also acts as their gateway — when a container wants to talk to something outside the host (say, to download an update from the internet), its traffic goes to the bridge, and the bridge passes it along to the host’s real network connection.

So the bridge plays two roles at once:

  • A switch that connects containers to each other.
  • A gateway that connects containers outward to the rest of the world.

This is the default behavior on most container platforms, and for a lot of simple cases you never have to think about it. It just works. The trouble usually starts at the edges — getting traffic in from the outside, and getting containers to find each other reliably. Those are the next two pieces.

Getting traffic in: publishing ports

Here’s a confusing-at-first reality: by default, a container is reachable from other containers on its network, but not from the outside world — not even from the host machine in the normal way you’d expect. Your web app might be happily listening on port 80 inside its container, and yet typing the host’s address into a browser gives you nothing.

Why? Because the container’s port 80 lives on that private virtual network. The outside world has no route to it. To fix this, you publish (sometimes called “expose” or “map”) a port — you tell the platform to connect a port on the host to a port inside the container.

   Browser on the internet


   host:8080  ──published──►  container:80
   (reachable)               (the app listens here)

In practice this looks like a mapping written as HOST_PORT:CONTAINER_PORT. A common command-line flag is -p:

# Map port 8080 on the host to port 80 inside the container
run -p 8080:80 my-web-app

Now a request arriving at the host on port 8080 gets forwarded into the container’s port 80. The container didn’t change at all — it’s still listening on 80 internally. You just built a doorway from the host’s port into it.

A few things worth knowing about port publishing:

  • The two numbers don’t have to match. 8080:80 means “host 8080 goes to container 80.” You might run three containers that all listen on port 80 internally, and publish them on host ports 8080, 8081, and 8082 so they don’t collide.
  • A host port can only be used once. If two containers both try to publish to host port 8080, the second one fails. The internal ports can repeat freely; the host ports cannot.
  • Only publish what needs to be public. Your database listens on a port too, but you almost never publish it. Leaving it unpublished means it’s reachable by your app container (same network) but invisible from outside — exactly what you want.

Publish narrowly, not generously

Every published port is a door into your system. A database, a cache, an internal admin panel — these usually have no business being reachable from the internet. Keep them on the internal network and let only the public-facing service (your web app) talk to them. If you find yourself publishing a database port “just to test something,” remember to close it again. This is the same least-privilege thinking that keeps real servers safe.

If you’ve read about ports and protocols, this will feel familiar — a published port is just a regular port on the host, forwarded inward. Nothing exotic; it’s the same port concept you already know, applied across the container boundary.

How containers find each other: names, not IPs

We said container IPs change on restart and shouldn’t be hardcoded. So how does the web app container actually reach the database container if it can’t rely on 172.17.0.3?

The answer is DNS between containers. Modern container platforms run a small built-in DNS service on each user-defined network. When you put containers on a network and give them names, they can reach each other by name, and the platform resolves that name to whatever IP the container currently has.

  web app container                database container
  "shop-web"                       "shop-db"
        │                                ▲
        │   connect to "shop-db:5432"    │
        └────────────────────────────────┘
            (DNS resolves the name
             to the current IP)

So instead of configuring your app with a brittle IP address, you configure it with a stable name like shop-db. The database container can restart, get a brand-new IP, and your app keeps working — because it asks for the name, and the platform hands back the right address every time.

The default bridge doesn't do name resolution

There’s a classic beginner trap here. The platform’s default bridge network usually does not give you name-based discovery — containers there can only reach each other by IP. Name resolution works on user-defined networks (networks you create yourself). So the standard advice is: create your own network, attach your related containers to it, and let them find each other by name. If two containers “can’t see each other” despite running side by side, the first thing to check is whether they’re on a user-defined network together or stranded on the default bridge.

This is why container tooling encourages you to group related containers onto a shared, named network. That single decision gives you both connectivity (they can reach each other) and discovery (they can find each other by name) at the same time.

Network isolation as a security tool

Here’s where networking stops being plumbing and becomes design. Because you control which containers share a network, you control who can talk to whom — and that’s one of the cleanest security boundaries you have.

A common, sensible pattern looks like this:

  • A frontend network that the public-facing web server sits on. Its port is published, so the internet can reach it.
  • A backend network that holds the database and other internal services. Nothing here is published.
  • The web app is attached to both networks, so it can take requests from the public side and forward queries to the private side.
   internet

      ▼  (published port)
  ┌─────────────┐        ┌──────────────────────┐
  │  frontend   │        │       backend        │
  │   network   │        │       network        │
  │             │        │                      │
  │  web app ───┼────────┼──► database          │
  │             │        │    cache             │
  └─────────────┘        └──────────────────────┘
                          (no published ports —
                           unreachable from internet)

The database literally has no path from the internet. Even if an attacker found its port, there’s no route to it — it lives on a private network with no published doors. The only way in is through the web app, which means your attack surface is small and deliberate. This is the same principle you’d use when placing a reverse proxy in front of internal services: expose one carefully controlled entry point, and keep everything else private behind it.

A quick mental checklist

When something doesn’t connect, run through these in order — they catch the large majority of container networking problems:

  1. Are the two containers on the same user-defined network? If not, they can’t see each other (and on the default bridge, can’t resolve names).
  2. Is the app inside actually listening on the port you think? A container listening on 127.0.0.1 instead of 0.0.0.0 won’t accept connections from outside itself, even with a published port.
  3. Did you publish the port to the host? If you can reach a service from another container but not from your browser, you probably forgot the HOST:CONTAINER mapping.
  4. Is the host port already taken? Two containers can’t publish to the same host port, and another program on the host might already hold it.
  5. Are you using a name where the IP might have changed? Hardcoded IPs break on restart; names don’t.

That short list resolves most of the “but they’re right next to each other, why can’t they talk?” moments.

Wrapping up

Container networking is less mysterious than its reputation. Boil it down and you get:

  • Containers are isolated by default, so the platform gives each one a virtual network interface and a private IP to let it communicate at all.
  • A bridge is a virtual switch and gateway in the middle: it connects containers to each other and forwards their traffic out to the world.
  • The outside world can’t reach a container until you publish a port, mapping a HOST_PORT to a CONTAINER_PORT. Publish only what truly needs to be public.
  • Containers find each other by name via built-in DNS — but only on user-defined networks, not the default bridge. Names survive restarts; IPs don’t.
  • Choosing which containers share a network is a real security boundary: keep databases and internal services off any published network so the internet can’t reach them.

Once you can picture the bridge, the published ports, and the named networks, the rest of container networking is mostly variations on these few moves. Next, it’s worth stepping back to compare containers against running directly on a machine — what you trade away, and what you gain, when you choose containers over bare metal.

Tags:servercontainersnetworkingportsbeginner
728 × 90Ad Space AvailablePlace your ad here

Related Articles

See All Articles

You Might Also Like

SSL and encryption at rest — data protected in transit and on disk
Server / Server Security

SSL and Encryption at Rest: Protecting Data Both in Transit and on Disk

Encryption protects your data in two places: while it travels the network (in transit) and while it sits on disk (at rest). Learn the difference, why you need both, how TLS, full-disk encryption, and key management actually fit together, and the practical mistakes to avoid — explained from the.

Nov 9, 202613 min read
Securing ports and services — closing the doors on a server you don't use
Server / Server Security

Securing Ports and Services: Closing the Doors You Don't Use

Every open port on a server is a door someone could try to walk through. Learn what ports and services really are, why an exposed service is your biggest risk, and the simple discipline of closing everything you don't need — explained from the ground up.

Nov 8, 202611 min read
Principle of least privilege — granting only the minimum access each user and process needs
Server / Server Security

The Principle of Least Privilege: Give Everything Only the Access It Truly Needs

Least privilege is the quiet rule behind almost every solid security setup: every user, process, and key gets the minimum access required to do its job, and nothing more. Learn what it means, why it limits the blast radius of any breach, and how to apply it across users, services, files, and keys.

Nov 7, 202613 min read
Fail2ban and intrusion basics — watching logs and automatically banning repeated abusers
Server / Server Security

Fail2ban and Intrusion Basics: Automatically Banning the Bots Hammering Your Server

Attackers don't stop after one failed guess — they keep hammering, thousands of times a day. Learn how intrusion attempts actually look, what fail2ban does, how it watches your logs and bans abusers automatically, and how to set it up sensibly without locking yourself out — explained from zero.

Nov 6, 202613 min read
Keeping software updated — closing known security holes before attackers use them
Server / Server Security

Keeping Software Updated: The Boring Habit That Stops Most Server Breaches

Most servers don't get hacked through clever new attacks — they get hacked through old, known holes that a simple update would have closed. Learn why updates matter, what to update, how to do it safely without breaking things, and how to make it a habit instead of a panic.

Nov 5, 202610 min read
Firewall configuration — a default-deny rule set that opens only the ports you need
Server / Server Security

Firewall Configuration: Setting Up Default-Deny Rules Without Locking Yourself Out

Knowing what a firewall is and actually configuring one well are two different skills. Learn how to write a default-deny rule set, order rules correctly, allow your own access first, handle IPv6 and cloud security groups, and test before you commit — a practical, vendor-neutral guide from zero.

Nov 4, 202615 min read