Setting up Container
Create Clean directory
Add Your react project
Add Your
dockerfile
file# set the base image to create the image for react app FROM node:20-alpine # create a user with permissions to run the app # -S -> create a system user # -G -> add the user to a group # This is done to avoid running the app as root # If the app is run as root, any vulnerability in the app can be exploited to gain access to the host system # It's a good practice to run the app as a non-root user RUN addgroup app && adduser -S -G app app # set the user to run the app USER app # set the working directory to /app WORKDIR /app # copy package.json and package-lock.json to the working directory # This is done before copying the rest of the files to take advantage of Docker’s cache # If the package.json and package-lock.json files haven’t changed, Docker will use the cached dependencies COPY package*.json ./ # sometimes the ownership of the files in the working directory is changed to root # and thus the app can't access the files and throws an error -> EACCES: permission denied # to avoid this, change the ownership of the files to the root user USER root # change the ownership of the /app directory to the app user # chown -R <user>:<group> <directory> # chown command changes the user and/or group ownership of for given file. RUN chown -R app:app . # change the user back to the app user USER app # install dependencies RUN npm install # copy the rest of the files to the working directory COPY . . # expose port 5173 to tell Docker that the container listens on the specified network ports at runtime EXPOSE 5173 # command to run the app CMD npm run dev
Add your `.dockerignore` file. If needed
Building Image
BUILD OPTION 1
COMMAND: docker build -t react_docker .
This won't work if you are trying to run a image which requires access to port of host machine.
BUILD OPTION 2
PORT MAPPING:
EXPOSE inst. does only one jod: it's to inform Docker that the container should listen to that specific exposed port in runtime
This means
we know on which port the docker container will listen to
Docker knows it
and so does the container
but someone is missing that information, it's the host is the main computer we're using to run it
As we know containers run in isolated environments and by default they don't expose their ports to the host machine or anyone else
this means that even if a process inside the container is listening on a specific Port the port is not accessible from outside the container and to make our host machine aware of that we have to utilize a concept known as Port mapping
COMMAND: docker run -p 5173:5173 react_docker
NOTE: If working with VITE In package.json. UNDER SCRIPTS > "dev" add --host
"scripts": { "dev": "vite --host", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" },
NOTE: If working with create-react-app bundler In package.json. UNDER SCRIPTS > "start" add --host
"scripts": { "start": "react-scripts start --dev", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" },
OPTION 3
Update previous command, in order to prevent rebuilding image whenever changes are implemented.
Done by using volume to keep track of changes in directory called "app".
This means mount the current working directory folder "app" into the app directory inside the container.
Effectively meaning local code is linked to container. any changes we make locally will be immediately reflected inside the running container.
COMMAND: docker run -p 5173:5173 -v "$(pwd):/app -v /app/node_modules react-docker
-v "$(pwd):/app
: Accept all changes in app working directory-v /app/node_modules
: Prevent reinstall every time of node_modules
Run Image
RUN IMAGE AS CONTAINER USING CMD. docker run react_docker
WON'T WORK