Docker Guide: Understanding Port Mapping, Dockerfile, and Docker Compose

Continuing our Docker series, today we’ll cover important topics like port mapping, Dockerfile, and Docker Compose. We’ll also show how to create a Dockerfile to containerize a Node.js server and how to publish custom Docker images on Docker Hub.

Port Mapping

Port mapping in Docker lets you access a containerized app from the host machine. By default, containers are isolated and can't be accessed from outside. Port mapping connects a port on the host to a port inside the container, allowing external access to the service in the container.

How to Use Port Mapping

When running a Docker container, you can use the -p flag to specify port mapping. The syntax is:

docker run -p [host_port]:[container_port] [image]

For example, to map port 80 of the host to port 3000 of a container running a Node.js application, use:

docker run -p 8000:3000 my-nodejs-app

This command makes the application accessible on http://localhost:8000.

Publishing Custom Docker Images on Docker Hub

Publishing your custom Docker images on Docker Hub allows you to share your images publicly or privately. Here’s how to do it:

Steps to Publish Docker Images

  1. Create a Docker Hub Account: Sign up at Docker Hub.

  2. Login to Docker Hub: Use the Docker CLI to log in.

docker login
  1. Build Your Docker Image: Build your Docker image with a tag that includes your Docker Hub username.
docker build -t yourusername/my-nodejs-app .
  1. Push the Image to Docker Hub: Push the image to Docker Hub.
docker push yourusername/my-nodejs-app

Your image is now available on Docker Hub and can be pulled using:

docker pull yourusername/my-nodejs-app

Dockerfile

A Dockerfile is a text document that contains a series of instructions on how to build a Docker image. It automates the creation of Docker images, ensuring that the environment is consistent and reproducible.

What is a Dockerfile Used For?

  • Automation: Automates the process of creating Docker images.

  • Consistency: Ensures the same environment across different stages (development, testing, production).

  • Reproducibility: Makes it easy to recreate the same image anytime, anywhere.

How to Create a Dockerfile

Creating a Dockerfile involves defining the base image and the steps required to build your application. Here’s a step-by-step guide to creating a Dockerfile for a Node.js server.

Example Dockerfile for Node.js Server

Create a file named Dockerfile in your Node.js project directory and add the following content:

FROM ubuntu
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y nodejs
COPY package.json package.json
COPY package-lock.json package-lock.json
COPY . .

ENTRYPOINT ["node", "main.js"]

Explanation:

  • FROM ubuntu: Specifies the base image.

  • RUN apt-get update: Updates the package list.

  • RUN apt-get install -y curl: Installs curl.

  • RUN apt-get install -y nodejs: Installs Node.js.

  • COPY package.json package.json: Copies package.json to the container.

  • COPY package-lock.json package-lock.json: Copies package-lock.json to the container.

  • COPY . . : Copies the entire project directory to the container.

  • ENTRYPOINT ["node", "main.js"]: Specifies the command to run the application.

Docker Compose

Docker Compose is a tool that helps you define and run multi-container Docker applications. It uses a YAML file to setup the application's services, networks, and storage.

How to Use Docker Compose

  1. Create a docker-compose.yml file in your project directory.

  2. Define the services that make up your application.

Example docker-compose.yml for Node.js and PostgreSQL

version: "3.6"
services:
  app:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      postgres:
        condition: service_healthy
  postgres:
    image: postgres:13
    ports:
      - "5450:5432"
    restart: always
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: "cal-saml"
      POSTGRES_PASSWORD: ""
      POSTGRES_HOST_AUTH_METHOD: trust
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
  postgres_is_ready:
    image: postgres
    depends_on:
      postgres:
        condition: service_healthy
volumes:
  db_data:

Explanation:

  • version: Specifies the Docker Compose file format version.

  • services: Defines the services (app and postgres in this case).

  • app: Configures the Node.js application service.

    • build: Specifies the build context.

    • ports: Maps port 3000 on the host to port 3000 in the container.

    • depends_on: Indicates that the app service depends on the postgres service.

  • postgres: Configures the PostgreSQL service.

    • image: Specifies the PostgreSQL image.

    • ports: Maps port 5450 on the host to port 5432 in the container.

    • restart: Always restarts the container on failure.

    • volumes: Defines a volume for persisting data.

    • environment: Sets environment variables for the database.

    • healthcheck: Configures a health check for the PostgreSQL service.

  • volumes: Defines named volumes for data persistence.

To start the application, run:

docker-compose up

Conclusion

Understanding port mapping, Dockerfile, and Docker Compose helps you manage Docker applications better. Dockerfile automates the creation of consistent Docker images, and Docker Compose makes it easier to manage multi-container applications. Publishing custom Docker images on Docker Hub lets you share your work with others.

Feel free to share your thoughts or ask questions in the comments below!