skip to Main Content

I am new to docker and writing a simple node application. I am confused by the various locations that ports are specified:

  • The node application listens on a certain port
  • The dockerfile defines a port to "expose" the application on
  • The docker run command specifies a local machine port, and a container port

My questions are: Which location is specifying what? Do they all need to be the same?

Related files:

index.js

const express = require('express');

const app = express();


app.get('/', (req,res)=>{
    res.send("g'day mate");
})

app.listen(3000, ()=>{
    console.log("listening")
})

Dockerfile

FROM node:16

# Create app directory
WORKDIR /

#Copy app sourcecode
COPY . . 

# install dependencies
RUN npm install

#Expose on port 3000
EXPOSE 3000

# This is the command to run the app
CMD [ "node", "index.js"]

The docker run command

docker run -dp 3000:3000 test-app

Thank you for your assistance

2

Answers


  1. From your question, I’m not sure if the concept of port is ok for you.

    My teacher use to simplify IP address and port as : IP address is the building and port is the flat in that building you are looking for.

    In index.js your express application is listening to the flat 3000 of the building it is running in.

    Because you are running your app in Docker, then the building is Docker. So the EXPOSE 3000 in Dockerfile is telling to Docker that this port should be exposed (basically not auto closed).

    Then in your command docker run -p 3000:3000 you are telling your host machine (your computer) to link his port 3000 to the port 3000 of Docker.

    You can also think it as extension cable : you are wiring the first cable (your computer) to the second one (docker) and then the second one to the third one (express app).

    Login or Signup to reply.
  2. The node application listens on a certain port

    This port number is very important. Connections between containers use only this port number and ignore any other settings. You cannot change this port number with pure Docker settings; it’s possible the application supports changing this through a command-line parameter or an environment variable but that will be application-specific.

    The docker run command specifies a local machine port, and a container port

    The container port must match the application port. The local machine port can be anything you want provided it’s not used by anything else on the host. These do not need to match.

    The dockerfile defines a port to "expose" the application on

    This should be the same as the application port, but it does almost nothing and there are no consequences to getting it wrong or omitting it entirely.

    Since "expose" doesn’t do anything, this makes the mechanic very simple. docker run -p 12345:3000 forwards from port 12345 on the host to port 3000 in the container. That needs to match where the application is actually listening (it also needs to be listening on the special 0.0.0.0 "all interfaces" address and not 127.0.0.1 "only accept connections initiated from within the same container"). Dockerfile EXPOSE is pretty much only documentation.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search