Create a custom docker image
Let’s start with docker. For that we need to know how to run our projects inside a docker container and in this tutorial I go through
- Basic structure of custom docker image
- Common mistakes we do
- How to run any project on docker in development environment
- Run a react project on docker
Basic structure of custom docker image
Before creating a custom docker image we should understand the basic structure of the docker image and docker file
Docker image consists of base image, Dependencies and files added and the startup command.
Dockerfile is the one which holds instructions to create the image. Then it should basically have,
- Instructions to add base image — Base image consists of file structure.
- Instructions to install dependencies and copy files
- Startup command
Let’s identify the basic Dockerfile structure using a code.
FROM node // Define a base imageCOPY . . // Copy project files to the container
RUN npm install // Install node packages
PORT 3000 // Define the PORTCMD ["npm", "start"] // Define startup command
As you see there are three main section in basic docker file as described above. Let’s go through with keywords one by one.
- FROM <base_image> — To indicate the base image
- COPY <source> <destination> — Copy files from local machine to image. Then the source is from the local machine and destination is from the base image.
- RUN <command> — This is to execute and setup dependencies and packages inside the image.
- PORT <port_number> — This is to define the port which our application is running. This is only for developer use.
- CMD [command] — This is to define the startup command
Common mistakes we do
- Forget to define a working directory
In Dockerfile it is good to mention a working directory as follows. It helps us to separate our code from basic file structure because if there is a folder named same as which is in project there might be some problems.
If the mentioned location is not available it will automatically build the directory. Then all the COPY folders and files will go to that specific location
- Copy modules which can be generated. Which leads to copy unnecessary data. Ex: node_modules
- Choose wrong base image
Other thing we missed is, choosing correct images. In above example also I choose node as my base image which will took the node:latest which is heavier (300MB+) but I can select node:alpline as my base image which will do the same (30MB+).
If we choose a wrong image it will increase our image and container size.
How to run any project on docker in development environment
There are some basic rules you have to follow. Note that there are some cases you have to follow multiple steps which will be cover in another post.
- Select an appropriate base image
- Copy project into a project directory and generate and install dependencies if needed.
- Define the startup command which is the project start command
Run a react project on docker
Let’s make a react project and make the Dockerfile and run it on docker container.
Then make a Dockerfile inside the project directory
Let’s create the docker file.
FROM node:alpineWORKDIR /user/app
COPY package.json .
RUN npm install
COPY . .
PORT 3000CMD ["npm", "start"]
We are ready with our docker file let’s run it. But before you do it make sure to remove the node_modules. Then build it as follows. (Please don’t forget to put the “.” at last because it indicates all the files in project directory. 😉)
docker build -t yashod/myapp .
Quick tip : It is easy to tag your image when building it because it will help to remember the name not the id.
docker build -t <repository_name>/<project_name>:version .
Then it will give output as follows.
Step 1/6 : FROM node:alpine
alpine: Pulling from library/node
Status: Downloaded newer image for node:alpine
Step 2/6 : WORKDIR /user/app
---> Running in 3a4b81250301
Removing intermediate container 3a4b81250301
Step 3/6 : COPY package.json .
Step 4/6 : RUN npm install
---> Running in 61bd9e07980c
Removing intermediate container 61bd9e07980c
Step 5/6 : COPY . .
Step 6/6 : CMD ["npm", "start"]
---> Running in a5ae55d4882a
Removing intermediate container a5ae55d4882a
Successfully built e65809425baf
Successfully tagged yashodgayashan/myapp:latest
As you in the above all the steps we mentioned in the Dockerfile will be executed one by one and finally create a image called e65809425baf or yashodgayashan/myapp:latest as we tagged it.
Then let’s run that image as follows.
docker run yashodgayashan/myapp:latest
And it will give you output as follows
You can now view myapp in the browser.Local: http://localhost:3000
On Your Network: http://172.17.0.2:3000Note that the development build is not optimized.
To create a production build, use npm run build.
If you try to run the “http://localhost:3000” it wont begin because the port 3000 is in the container and it is not exposed to our local machine then it has to be mapped as follows,
docker run -p <local_port>:<container_port> image
Then our application is accessible throughout port 4000 on our local machine
docker run -p 4000:3000 yashodgayashan/myapp:latest
You can access the myapp through “http://localhost:4000”.
If you have found this helpful please hit that 👏 and share it on social media :)