WittCode💻

Don't Expose All Your Docker Containers

By

Not all Docker containers need to be exposed to the host machine. Learn why that is and how to protect containers from the outside world using Docker Compose.

Table of Contents 📖

Nginx and NodeJS Example

So I recently made a course on how to build an Nginx load balancer for a NodeJS API cluster. In the architecture for this project, each component runs inside a Docker container inside a Docker network. However, not every component is exposed to the outside world. Specifically, the NodeJS API cluster can only be accessed by containers within the same Docker network. This protects the API cluster from being overloaded. In other words, if someone wanted to overload my NodeJS cluster with a bunch of requests, they would have to go through Nginx first and Nginx can easily be configured to handle a massive amount of requests and even drop requests if they seem like a DDOS attack.

Protecting Containers from the Outside World

Docker makes it very easy to protect containers from the outside world. For example, the Docker Compose expose key will expose the container inside the Docker network, not outside of it.

name: ${PROJECT_NAME}

services:

  # Node API server
  node:
    pull_policy: build
    image: node-i
    build:
      context: node
      dockerfile: Dockerfile.prod
    env_file: .prod.env
    restart: always
    expose: 
      - ${NODE_PORT}
    deploy:
      replicas: 3

  # Nginx reverse proxy
  nginx:
    pull_policy: build
    image: nginx-i
    build:
      context: .
      dockerfile: ./nginx/Dockerfile.prod
    container_name: ${NGINX_CONTAINER_NAME}
    env_file: .prod.env
    restart: always
    ports:
      - ${NGINX_PORT}:${NGINX_PORT}
    depends_on:
      - node

Notice how the Node service uses the expose key while the Nginx service uses the ports key. The expose key will expose ports that will not be published on the host machine. On the other hand, the ports key will be accessible internally and published on the host machine. The expose key is applicable in many situations. I am currently creating a course on monitoring a NodeJS application's metrics and logs using Docker. Most of the containers in that stack do not need to be exposed on the host machine.

ERROR: There are many situations where the expose key should be used instead of ports. Another example is databases. Database ports typically do not need to be exposed to the outside world.