Docker 101: Create Custom Image (REACT APP)

Docker 101: Create Custom Image (REACT APP)

PART IX

Setting up Container

  1. Create Clean directory

  2. Add Your react project

  3. 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
    
  4. 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

REFERENCE