<p>When you use network_mode host, the <a href="https://docs.docker.com/network/host/" rel="nofollow noreferrer">published ports are ignored</a>, which means the ports that are open in the containers will be the same port in the host. Does not matter what you had declared in <code>ports</code></p>
<p>The default behavior is every service in the compose can talk to each other.</p>
<blockquote>
<p><a href="https://docs.docker.com/compose/networking/#links" rel="nofollow noreferrer">Links</a> are not required to enable services to communicate - by default, any service can reach any other service at that service’s name</p>
</blockquote>
<p>let's use this simple compose as an example. There is no network defined, docker will create one.</p>
<pre><code>version: '3.7'
services:
  nginx1:
    image: nginx
    ports:
      - '8080:80'
  nginx2:
    image: nginx
</code></pre>
<p>Nginx1 will be reachable through port 8080 on localhost and any other machines in the network.</p>
<pre><code>$ curl -I http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.19.10
</code></pre>
<p>While nginx2 will even have a port on the host.</p>
<pre><code>$ docker-compose ps
      Name                     Command               State                  Ports                
-------------------------------------------------------------------------------------------------
nginx1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8080-&gt;80/tcp,:::8080-&gt;80/tcp
nginx2_1   /docker-entrypoint.sh ngin ...   Up      80/tcp                              
</code></pre>
<p>And they still reach each other by their internal port using the service name</p>
<p>Accessing nginx1 from nginx2</p>
<pre><code>$ docker exec -it nginx2_1 curl -I http://nginx1:80
HTTP/1.1 200 OK
Server: nginx/1.19.10
</code></pre>
<p>Accessing nginx2 from nginx1</p>
<pre><code>$ docker exec -it nginx1_1 curl -I http://nginx2:80
HTTP/1.1 200 OK
Server: nginx/1.19.10
</code></pre>

CC BY-SA 4.0
2021-04-28T01:22:57.037Z
2021-04-28T01:22:57.037Z
Joao  Vitorino
<p>Instead of using <code>network_mode</code> to <code>host</code>, you can simply make use of <code>links</code> (new versions uses <code>networks</code>) which will make the communication to happen between two containers.</p>
<p>I have updated the <code>docker-compose.yaml</code> file and added <code>links</code> to connect <code>database</code> service (database container) to be accessed from your <code>backend</code> service.</p>
<p>In your backend database configuration, you need to use <code>database</code> as the db host. (Here <code>database</code> is the service name which is defined in the compose.yaml file)</p>
<pre><code>version: &quot;3&quot;

services:
  redis:
    image: redis:latest
    ports:
      - 6379:6379
    command: [&quot;redis-server&quot;, &quot;/redis.conf&quot;]
  database:
    image: &quot;postgres&quot;
    env_file:
      - ./database/database.env
    volumes:
      - database-data:/var/lib/postgresql/data
      - ./database/init-db.sql:/docker-entrypoint-initdb.d/init.sql
    restart: always
  backend:
    depends_on: [database]
    build: ./server
    volumes:
      - ./files:/var/lib/files
    ports:
      - 3333:3333
    restart: always
    links:
      - &quot;database&quot;

volumes:
  database-data:
</code></pre>

CC BY-SA 4.0
2021-04-27T23:23:25.083Z
2021-04-27T23:23:25.083Z
Samit
<p>I was recently shocked to find out that docker writes its own iptables rules and ignores ufw bindings completely. I had blocked all ports using the <code>ufw deny incoming command</code> and then selectively allowed only the ports that I wanted to expose.</p>
<p>I have a very simple setup that utilizes a postgresql container and a simple nodejs application. My primary goal is to keep the postgresql container port off the internet but let the node backend accept requests through port 3333. How do I do that?</p>
<p>My current <code>docker-compose.yml</code> file looks like this:</p>
<pre class="lang-yml prettyprint-override"><code>version: &quot;3&quot;

services:
  redis:
    image: redis:latest
    ports:
      - 6379:6379
    command: [&quot;redis-server&quot;, &quot;/redis.conf&quot;]
    network_mode: host
  database:
    image: &quot;postgres&quot;
    env_file:
      - ./database/database.env
    volumes:
      - database-data:/var/lib/postgresql/data
      - ./database/init-db.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - 5432:5432
    restart: always
    network_mode: host

  backend:
    depends_on: [database]
    build: ./server
    volumes:
      - ./files:/var/lib/files
    ports:
      - 3333:3333
    restart: always
    network_mode: host

volumes:
  database-data:
</code></pre>

CC BY-SA 4.0
2021-04-26T21:23:50.950Z
typically you put all your boxes inside a private network where they have zero incoming access from the outside world ( internet ) unless specified by your reverse proxy server ( haproxy or nginx ) yet have full access to and from each other ... aws VPC gives you this so does other private network toolings
Scott Stensland
<docker><docker-compose><security><ports>
Docker: Let containers communicate to each other but don't expose to internet
Chris
# Docker: Let containers communicate to each other but don't expose to internet

(Asked by: username_0 on 2021-03-18)

I was recently shocked to find out that docker writes its own iptables rules and ignores ufw bindings completely. I had blocked all ports using the ufw deny incoming command and then selectively allowed only the ports that I wanted to expose.
I have a very simple setup that utilizes a postgresql container and a simple nodejs application. My primary goal is to keep the postgresql container port off the internet but let the node backend accept requests through port 3333. How do I do that?
My current docker-compose.yml file looks like this:
version: "3"

services:
  redis:
    image: redis:latest
    ports:
      - 6379:6379
    command: ["redis-server", "/redis.conf"]
    network_mode: host
  database:
    image: "postgres"
    env_file:
      - ./database/database.env
    volumes:
      - database-data:/var/lib/postgresql/data
      - ./database/init-db.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - 5432:5432
    restart: always
    network_mode: host

  backend:
    depends_on: [database]
    build: ./server
    volumes:
      - ./files:/var/lib/files
    ports:
      - 3333:3333
    restart: always
    network_mode: host

volumes:
  database-data:

**Tags:** docker, docker-compose, security, ports

> **Comments:**
> **username_1**: typically you put all your boxes inside a private network where they have zero incoming access from the outside world ( internet ) unless specified by your reverse proxy server ( haproxy or nginx ) yet have full access to and from each other ... aws VPC gives you this so does other private network toolings  

---

## 2 answers

### Answer by username_2 on 2021-04-28. Score: 1

When you use network_mode host, the published ports are ignored, which means the ports that are open in the containers will be the same port in the host. Does not matter what you had declared in ports
The default behavior is every service in the compose can talk to each other.

Links are not required to enable services to communicate - by default, any service can reach any other service at that service’s name

let's use this simple compose as an example. There is no network defined, docker will create one.
version: '3.7'
services:
  nginx1:
    image: nginx
    ports:
      - '8080:80'
  nginx2:
    image: nginx

Nginx1 will be reachable through port 8080 on localhost and any other machines in the network.
$ curl -I http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.19.10

While nginx2 will even have a port on the host.
$ docker-compose ps
      Name                     Command               State                  Ports                
-------------------------------------------------------------------------------------------------
nginx1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8080->80/tcp,:::8080->80/tcp
nginx2_1   /docker-entrypoint.sh ngin ...   Up      80/tcp                              

And they still reach each other by their internal port using the service name
Accessing nginx1 from nginx2
$ docker exec -it nginx2_1 curl -I http://nginx1:80
HTTP/1.1 200 OK
Server: nginx/1.19.10

Accessing nginx2 from nginx1
$ docker exec -it nginx1_1 curl -I http://nginx2:80
HTTP/1.1 200 OK
Server: nginx/1.19.10


---

### Answer by username_3 on 2021-04-27. Score: 0

Instead of using network_mode to host, you can simply make use of links (new versions uses networks) which will make the communication to happen between two containers.
I have updated the docker-compose.yaml file and added links to connect database service (database container) to be accessed from your backend service.
In your backend database configuration, you need to use database as the db host. (Here database is the service name which is defined in the compose.yaml file)
version: "3"

services:
  redis:
    image: redis:latest
    ports:
      - 6379:6379
    command: ["redis-server", "/redis.conf"]
  database:
    image: "postgres"
    env_file:
      - ./database/database.env
    volumes:
      - database-data:/var/lib/postgresql/data
      - ./database/init-db.sql:/docker-entrypoint-initdb.d/init.sql
    restart: always
  backend:
    depends_on: [database]
    build: ./server
    volumes:
      - ./files:/var/lib/files
    ports:
      - 3333:3333
    restart: always
    links:
      - "database"

volumes:
  database-data:


---

