youhatch
youhatch

Reputation: 341

On what PORT is my docker container with a React app running? Reacts' default PORT or EXPOSE from Dockerfile?

I'm a newbie to Docker so please correct me if anything I'm stating is wrong.

I created a React app and wrote a following Dockerfile in the root repository:

# pull official base image
FROM node:latest

# A directory within the virtualized Docker environment
# Becomes more relevant when using Docker Compose later
WORKDIR /usr/src/app
 
# Copies package.json and package-lock.json to Docker environment
COPY package*.json ./
 
# Installs all node packages
RUN npm install
 
# Copies everything over to Docker environment
COPY . .
 
# Uses port which is used by the actual application
EXPOSE 8080
 
# Finally runs the application
CMD [ "npm", "start" ]

My goal is to run the docker image in a way, that I can open the React app in my browser (with localhost). Since in the Dockerfile I'm Exposing the app to the PORT: 8080. I thought I can run:

docker run -p 8080:8080 -t <name of the docker image>

But apparently the application is accessible through 3000 in the container, cause when I run:

docker run -p 8080:3000 -t <name of the docker image>

I can access it with localhost:8080.

What's the point of the EXPOSE port in the Dockerfile, when the service running in its container is accessible through a different port? When containerizing a NodeJS app, do I always have to make sure that process.env.PORT in my app is the same as the EXPOSE in the Dockerfile?

Upvotes: 2

Views: 10168

Answers (3)

Karthikeyan Ganesan
Karthikeyan Ganesan

Reputation: 2035

Actually react app runs the default port 3000. so you must to mention ports and expose in docker-compose.yml. Now I'm changing the 3000 port to 8081

  frontend: 
      container_name: frontend 
      build: 
        context: ./frontend/app
        dockerfile: ../Dockerfile  
      volumes:
        - ./frontend/app:/home/devops/frontend/app 
        - /home/devops/frontend/app/node_modules
      ports:
        - "8081:3000"
      expose:
        - 8081
      command: ["npm", "start"]
      restart: always 
      stdin_open: true 

And run the docker

$ sudo docker-compose up -d

Then check the running containers for find the running port

$ sudo docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                              NAMES
83b970baf16d        devops_frontend     "docker-entrypoint..."   31 seconds ago      Up 30 seconds       8081/tcp, 0.0.0.0:8081->3000/tcp   frontend

It's resolved. check your public port

$ curl 'http://0.0.0.0:8081'

Upvotes: 1

Daniel
Daniel

Reputation: 2531

EXPOSE is for telling docker what ports from inside the application can be exposed. It doesn't mean anything if you do not use those port inside (container -> host).

The EXPOSE is very handy when using docker run -P -t <name of the docker image> (-P capital P) to let Docker automatically publish all the exposed ports to random ports on the host (try it out. then run docker ps or docker inspect <containerId> and checking the output).

So if your web Server (React app) is running on port 3000 (inside the container) you should EXPOSE 3000 (instead of 8080) to properly integrate with the Docker API.

Upvotes: 5

Julian Orinyol
Julian Orinyol

Reputation: 606

It's kind of weird. Its just documentation in a sense.

https://docs.docker.com/engine/reference/builder/#:~:text=The%20EXPOSE%20instruction%20informs%20Docker,not%20actually%20publish%20the%20port.

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.

do I always have to make sure that process.env.PORT in my app is the same as the EXPOSE in the Dockerfile? Yes. You should.

And then you also need to make sure that port actually gets published, when you use the docker run command or in your docker-compose.yml file, or however you plan on running docker.

Upvotes: 1

Related Questions