Docker: Ins and Outs

Docker: Ins and Outs

This post is to complement this article on how to get started with docker. We will be deep diving a bit and exploring what docker has in store for us. For the sake of consistency, I'll start from the ground up. You can skip to the main part if you know how to set up Docker with Nodejs.

Let's Take a Dive

dive

Agenda

๐ŸŽฏ Setup ๐ŸŽฏ Interactive Shell ๐ŸŽฏ Data Persistence (volumes and nodemon hot reload) ๐ŸŽฏ Data Sharing between Container and Local machine


Setup

Lets setup our NodeJs server and dockerize it. Image description

In your index.js file write the following lines of code:

const express = require('express');
const app = express();

const port = process.env.PORT || 4545;

app.use(express.json());

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

Next, add the Dockerfile and add the following line: Image description


Activate your Docker Desktop Image description Green here ๐Ÿ‘†๐Ÿผ means active


We can build our image now.

docker build -t node-devto . Image description

check the image built

docker image ls Image description


Let's run our container from the built image

Run: docker run -v $(pwd):/app -p4000:4545 -d --name node-api-devto node-devto

Image description


Let's test our running container

Image description


Interactive shell

Let's open our running container in interactive shell mode docker exec -it [container id or name] bash docker exec -it 4b73a54c50e6 bash

Image description


Let's see folders and files in our container

Image description

Exit the interactive shell using: exit


Creating Files in container

We can create files in our container and as we will normally interact with our terminal

Image description


Data persistence

If we change anything in our express server, for instance the response we are sending to our client. let's change the response from Hello World! to Hello Docker!. To update our code, we delete the running container, change our code and rebuild the image. Image description Then we run our container from the built image. Image description

If we refresh our browser again, we see the changes Image description

The process above can be cumbersome. To avoid rebuild our images for every little change that we make, we make use of volumes, that allows us to have persistence data,[bind/mount] this allows us to sync data in our local filesystem[folder] to our container file system[folder]

First, let's install nodemon as a Development Dependencies to help restart our server automatically on change.

๐Ÿ‹ Install nodemon Image description

๐Ÿ‹ Edit the package.json to run dev script Image description

๐Ÿ‹ Reconfigure our Dockerfile Image description

๐Ÿ‹ Let's Rebuild our image Image description

๐Ÿ‹ Next, we run the container from the built image using volume and bound/mount Image description

Now let me change our Server response to Hey, we made it. Save the code base Image description

Refresh our browser. Image description

Yippee, it works! We no longer need to rebuild every time we want to see changes.


Data Sharing between Container and Local machine

Lets open our interactive shell again

Image description

We can create files from our container and it will appear on our local file system Image description


Conclusion

I hope this post was helpful. Stick around for more useful docker commands, how to use docker-compose, running services and work-around in my next post


References

Docker Tutorial for Beginners Docker Learn Docker - DevOps with Node.js & Express

ย