Docker is cool. I’ve just started to use and play it for small projects. This part will cover the basics of building and running docker containers and images.
I started taking courses on Lynda.com which is given out free by my university and I went on a Binge Spree to do docker certifications for the same.
These are the basics you need to know about docker:
You create isolated, light-weight reproducible environments with Docker. You define OS, Packages and anything else you want inside the docker image and once you build it, it will be there ready for you. It works the same on all machines as it is completely isolated and does not differ/change depending on the OS you are running docker. This is a small Docker 101 tutorial. (Meant for me, can be used by you)
- Docker creates stand-alone packages called containers that comprise of everything that is needed for you to run the application.
- Each container gets its own CPU, memory and network resources and does not depend on a specific operating system or kernel.
- Docker IS NOT Virtual Machine. Docker works differently in how it shares/dedicates resources to containers.
- It uses something called as Layered Files System which allows the containers to share common parts hence they consume less resources on the host system than a VM.
In simple terms, Docker containers, contain everything you need to run an application, including the source code you wrote. Containers are also isolated and secure light-weight units on your system. This makes it easy to create multiple micro-services that are written in different programming languages and that are using different versions of the same lib and even the same OS.
Steps
- create an application
- create a Dockerfile
- build an image
- create a container
We will be creating an Express Node.js project which will consist of the following files:
app.js: this is the file that spins up the REST
package.json: this is the manifest file for the project, where we also write the dependancies and declare the start script.
Dockerfile: Basically a definition file to tell docker how to “Dockerize” the application.
mkdir project
cd project
npm init -y
# This will create the package.json file with a bunch of default values.
npm install express —-save
# If the above command throws and error, try "npm install express"
# The dependency we need and are about to use for out application
# Now write the below code at "app.js" file in the project directory and run it by
node app.js
This is the app.js file
// app.js
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
Go to http://localhost:3000 and you should see a “Hello World” displayed there.
Creating the DockerFile
This acts as a manifest but also as a build instruction file, how to get our app up and running.
This is the DockerFile that is needed for our application.
FROM node:latest
# FROM selects the OS image from the docker hub
WORKDIR /app
# we set a working directory inside the container
COPY . .
# Copy all files from the current directory we are in,
# to the directy defined by the WORKDIR command
RUN npm install
# Install npm
EXPOSE 3000
# Exposes the port 3000 and which we use to communicate with the container
ENTRYPOINT ["node", "app.js"]
# ENTRYPOINT is where we state how we start up our application
# the commands need to be specified as an array so the array [“node”, “app.js”]
# will be translated to the "node app.js" in the terminal
Assuming you are standing in the directory of the project, you will have to build the dockerfile by running:
“docker build -t divyendrapatil/node:latest .”
Do not forget the “.” at the end as it the location of the dockerfile (For Us, it is the same directory)
We need to map the internal port of the app to an external one, on the host machine.
We do the mapping by using the flag -p by:
We need to keep track of the port when we start the express server inside of our app.js , to make sure this matches what we write in the Dockerfile. It shouldn’t have to be that way, it’s just static and error-prone.
By doing this, we git rid of static values and rely on variables.
FROM node:latest
WORKDIR /app
COPY . .
ENV PORT=3000
RUN npm install
EXPOSE $PORT
ENTRYPOINT ["node", "app.js"]