Goal of this article is to onboard you on to the docker in just couple of minutes, such that it won’t explain any concepts behind instead it will give you hands on. Think of this article as “Hello World” of your docker journey to run your first docker container
First install the docker: Install Docker
In this article simple node JS web server is create to be served with Docker.
Following is the HTTP server created using nodeJS without any libraries or framework
# file name app.js
const http = require("http");
const host = '0.0.0.0';
const port = 8080;
const requestListener = function (req, res) {
res.setHeader("Content-Type", "application/json");
res.writeHead(200);
res.end(`{"message": "This is a JSON response ${Math.random()}"}`);
};
const server = http.createServer(requestListener);
server.listen(port, host, () => {
console.log(`Server is running on http://${host}:${port}`);
});
Assuming above code is saved into file app.js, you can verify if it is working with command
node app.js
Create Dockerfile
Then, our job is to create Dockerfile which is the configuration file used by Docker Engine build an image for us to run container
FROM node:16.3.0
WORKDIR /app
COPY app.js /app/
CMD ["node", "app.js"]
Explaining the above Dockerfile
FROM defines the base image
WORKDIR defines the working directory for any other following instructions like RUN
, CMD
, ENTRYPOINT
, COPY
and ADD
COPY copies the specified files or directory to desired location in the image
CMD specifies the default command to run when container starts where this can be overridden by run command
Next big step is to build an image
Build Docker Image
To build the image run the command “docker build .” but make sure your current working directory is same as where Dockerfile is. Dockerfile is ideally located in the root directory of the project
docker build -t testnodeweb .
Above command generates the docker image
docker build -t testnodeweb . [+] Building 3.0s (8/8) FINISHED => [internal] load build definition from Dockerfile => => transferring dockerfile: 36B => [internal] load .dockerignore => => transferring context: 2B => [internal] load metadata for docker.io/library/node:16.3.0 => [internal] load build context => => transferring context: 463B => [1/3] FROM docker.io/library/node:16.3.0@sha256:ca6daf1543242a5509ea => CACHED [2/3] WORKDIR /app => [3/3] COPY app.js /app/ => exporting to image => => exporting layers => => writing image sha256:ec788377bad70b6a170c15a46422794f9712769e49548 => => naming to docker.io/library/testnodeweb
Verify if the docker image is created using the command
docker image ls
You should see the something like below
REPOSITORY TAG IMAGE ID CREATED SIZE testnodeweb latest ec788377bad7 About a minute ago 855MB
Where,
Each image is associated with unique id “IMAGE ID” and the name (testnodeweb) we see under the column REPOSITORY is the same name we have specified when building image using build command with option -t
Running the Container
To run the container use the docker command “docker run”. But wait, can you simply access service running in container with designated port ? No
To access those services, we need to expose the port or publish the port to associate it with any host port for port forwarding using option -p
docker run -p 8088:8080 testnodeweb
Longer syntax
docker run --name test-nodeweb\
--publish published=8088,target=8080
testnodeweb
Short Syntax
docker run --name test-nodeweb \
-p 8088:8080 \
testnodeweb
Where –name option gives a human friendly name to the container to refer it later
Stop or Kill container
To stop or kill the containers you use “docker stop” or “docker kill” commands with container IDs or human friendly names specified when running containers
docker stop 1db8773d3fd4
# or
docker kill 1db8773d3fd4
As said, we can also use human friendly name associated with container
docker kill test-nodeweb
Great! Well done. Happy Containers 🐬