Docker: Ins and Outs
Tags: docker, javascript, programming, devops
Published: 2022-05-06 13:20:09

This post is to complement this [article](https://dev.to/drsimplegraffiti/dockerize-nodejs-application-2p3i) 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](#skip) to the main part if you know how to set up Docker with Nodejs. 

##### Let's Take a Dive
![dive](https://media.giphy.com/media/14uzPzKMOuVIPu/giphy.gif)

#### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/md2qixq4poqcz3rr8ngm.PNG)
 
In your `index.js` file write the following lines of code:
```javascript
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5tskfzsuziy6o8sonn2.PNG)

--- 

Activate your Docker Desktop 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5eg7cu900wcz0w4zmnr.PNG)
Green here 👆🏼 means active 

---

We can build our image now.
> docker build -t node-devto .
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9ss6p8hfiunye7y5qwc.PNG)
 

##### check the image built
`docker image ls`
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/moepotkk0i6v9ryux8hb.PNG)

---
##### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jxn5hh6muz1i9ah4pzkg.PNG)
  
---

##### Let's test our running container
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uq4kv6khsk8eog4wp0q0.PNG)

---

### Interactive shell <a name="skip"></a>
 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5iqu967dinbj1p9qh7if.PNG)


---

##### Let's see folders and files in our container
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qjzzwdspbgaofokzuwyv.PNG)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3la3xrmwsiyc4qrwo0m8.PNG)

---

### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5c1qsq48ol1vg9rfvvr1.PNG)
Then we run our container from the built image.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z78zuotd9wdd26cqu0bz.PNG)

If we refresh our browser again, we see the changes
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/quavjqi43pt5scf7m000.PNG)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qemrjci1s9e1tbakfas5.PNG)

 🐋 Edit the package.json to run dev script
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g3qvjv8xltljzdu2z7gf.PNG)

 🐋 Reconfigure our `Dockerfile`
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pre3gq8dt1thp3tneom3.PNG)
 

 🐋 Let's Rebuild our image
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2c0ozkr4xqxpx9dfgnn.PNG)
  
 🐋 Next, we run the container from the built image using volume and bound/mount
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/913npf0bkni2r8mhxpzi.PNG)

Now let me change our Server response to `Hey, we made it`. Save the code base
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bl13ixlcjjn1bvy6lrl2.PNG)
  

Refresh our browser.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z727f54ng4owad5tmegs.PNG)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfisxqbkw5jvpuuwwxpq.PNG)


We can create files from our container and it will appear on our local file system
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aivfi8o0g2gddbagluh6.PNG)
 
 ---

##### 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](https://www.youtube.com/watch?v=3c-iBn73dDE&t=7282s)
[Docker](https://www.docker.com/)
[Learn Docker - DevOps with Node.js & Express](https://www.youtube.com/watch?v=9zUHg7xjIqQ&t=11515s)