Time to read: 5 min read
Docker is a PaaS(Platform-as-a-Service) product that uses OS level virtualization to deliver a software as a package called container. Each containers are separated from each other and they bundled their own dependencies, but it's possible to communicate between two or more containers.
Before I start tell you the reason, I would like to share my own story. Once I worked for someone on a VueJS application. After finishing my development I was going to deliver him. And he asked me a favor to deploy the app for him. Then he gave me the credentials of his vps(MS Azure). I thought it'll be easy to do it as I did that before. So, without thinking I just logged into server with ssh and start deploying the application in traditional process. After sometimes I realized Node version is 4.*. Which is very low for my application. So, I updated the node version and then I was on real trouble. Because client already had a nodejs backend application hosted on that machine with 4.* node version. So quickly I had to downgrade the node version. Then I googled million times about different node version. I found NVM(Node Version Manager). I deploy the VueJS application with nvm. But I wasn't convince. After some days I read about Docker. And it sounds pretty awesome to me.
Come to the point, Why Docker?
To move a software from dev server to test server and then into production server with the dependency of the software we will use docker. It's really safe.
Suppose you have a process manual for setup your application. And you and your team always follow the manual for setup new/existing applications. Dockerfile is that process manual for each application. You'll be needed to write some instruction into the Dockerfile according to docker commands. That's it your application will be ready 😄. Now let's write a docker file for basic node application.
FROM node:lts-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:stable-alpine as production-stage COPY --from=build-stage /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
All the capital words are docker built-in commands.
Every docker image is created from one or more base images. In that case I am taking node image. In most of the case images are come from Docker Hub (opens new window). lts-alpine means I am taking the node docker image which release tag is LTS(Long Term Support). And as build-stage is a alias name.
I was thinking that I am
Declaring the work directory inside docker container. Remember a docker container is OS level virtualization, So, here /app is same as a unix directory like /home.
Coping package.json and package-lock.json into the working directory.
RUN is a docker command for running shell command inside the docker container. Here we are going to install the dependencies for our application.
Now copy everything into working directory of docker container. If your curious mind asked the question Why we copied package.json if I am coping now?. Then my answer will be to the the
npm install you need a package.json file.
Build your application. In your case it might be the different command.
Same as before I am pulling the nginx stable release and named it as production-stage.
Copy all the distribution files of our application from /app/dist to nginx public directory. In your application /app/dist might be different. But the process flow should be same.
Expose a port. Be careful before you expose any port. You must have access on it. For example, suppose you exposed 5001 port. But this port is not accessible or used by others. Then it's not going to work.
Run nginx from command line from the docker container.
Now we will build the Dockerfile by typing following command.
docker build -t iashraful/docker-into .
-t is for tag. and dot[.] means all.
docker run -it -d -p 5001:80 --rm --name docker-intro iashraful/docker-into
Here, -it is short for --interactive + --tty when you docker run with this command.. it would take you straight inside of the container,, where -d is short for --detach which means you just run the container and then detach from it so basically you run container in the background. -p for mapping the machine port with container port. It's machine port:container port. --rm means automatically remove the image if it exists, also removes the anonymous volumes associated with the container when the container is removed. --name is for naming the container.
If everything is alright till now then open up your browser and hit
http://localhost:5001. You'll see your application.
I think it's enough for today. I hope next will be Publishing docker image to Docker Hub