Creating a Node.js App with Docker A Step-by-Step Guide
· 26 min read
Creating a Node.js App with Docker: A Step-by-Step Guide
Let's Dive into Docker!
Ever heard of Docker? It's like a toolbox for developers! It helps us wrap up our apps neatly in what we call "containers." Think of a container as a tiny, self-contained space where your app can live and do its thing.
Now, why do we like containers? Well, they're like super-light virtual machines, making our apps run smoothly without taking up too much space.
They also keep our apps separate from each other, like little islands, so they don't mess with one another.
Even though containers have been around for a while, they're becoming more popular because they give us cool perks like keeping our apps safe and making sure they all work the same way no matter where we run them. Let's explore how we can use Docker to make our apps even more awesome!
When you're using Docker to build and expand your app, the first step is usually making something called an "image." Think of it as a snapshot of everything your app requires to run smoothly.
This image is like a bundled package that contains your app's code, necessary tools, settings and what it needs to operate. Creating an image ensures that wherever your app runs, it always has a consistent setup and only carries what it absolutely needs.
So, making an image is like preparing a special kit for your app, ensuring it's ready to work seamlessly anywhere you want it to! In this guide, you'll make a special package for a simple website using Express and Bootstrap. After that, you'll put your package into a container and save it on Docker Hub for later. Lastly, you'll take out your saved package from Docker Hub and use it to create another container. This shows how you can easily make copies and expand your website whenever you want!
Now, why do we like containers? Well, they're like super-light virtual machines, making our apps run smoothly without taking up too much space.
They also keep our apps separate from each other, like little islands, so they don't mess with one another.
Even though containers have been around for a while, they're becoming more popular because they give us cool perks like keeping our apps safe and making sure they all work the same way no matter where we run them. Let's explore how we can use Docker to make our apps even more awesome!
When you're using Docker to build and expand your app, the first step is usually making something called an "image." Think of it as a snapshot of everything your app requires to run smoothly.
This image is like a bundled package that contains your app's code, necessary tools, settings and what it needs to operate. Creating an image ensures that wherever your app runs, it always has a consistent setup and only carries what it absolutely needs.
So, making an image is like preparing a special kit for your app, ensuring it's ready to work seamlessly anywhere you want it to! In this guide, you'll make a special package for a simple website using Express and Bootstrap. After that, you'll put your package into a container and save it on Docker Hub for later. Lastly, you'll take out your saved package from Docker Hub and use it to create another container. This shows how you can easily make copies and expand your website whenever you want!
Requirements
Before we get started, it's good to make sure your computer is using a somewhat recent version of Ubuntu. If you're on version 16.04 or an even older one, it's a good idea to upgrade to a newer version because the older ones don't get support anymore. Don't worry, though! We have some easy guides that'll help you upgrade your Ubuntu to the latest and greatest version.
To try out this guide, make sure you have:
To try out this guide, make sure you have:
- A server running Ubuntu. You should also have a regular user account with the ability to use administrative commands (like sudo), and your firewall should be active. If you're not sure how to set these up, we have a guide to help you get started.
- Docker installed on your server. You can follow the first two steps of our guide titled "How To Install and Use Docker on Ubuntu" for Ubuntu versions 22.04, 20.04 or 18.04.
- Node.js and npm installed on your server. You can install them by following the instructions provided in our guide for Ubuntu versions 22.04, 20.04 or 18.04.
- A Docker Hub account. If you don't have one yet, don't worry! We have an introduction to help you get started with Docker Hub.
Creating Your Node.js App with Docker: Easy Steps
- Get Your App Ready:
First things first, gather everything your app needs to run smoothly. It's like making sure you have all the tools before starting a craft project! - Build Your Node.js App:
Craft the files for your Node.js app. This is where you put the magic code that makes your app work like a charm. - Guide Docker with Your App's Blueprint:
Write a "Dockerfile" to help Docker understand how to bundle up your app. It's like providing a recipe for Docker to cook up your app just right! - Store Your App in the DockerHub Closet:
Think of DockerHub as a big storage space. Put a copy of your app there so you can easily share it or use it again later. It's like having a safe spot for your digital stuff!
Prepare Your App:
First things first, get everything your app needs to run smoothly. It's similar to making sure you have all the tools before starting a craft project! To begin, create a special folder for your project in your computer's home area. We'll call ours "node_project," but feel free to pick a name you like:
First things first, get everything your app needs to run smoothly. It's similar to making sure you have all the tools before starting a craft project! To begin, create a special folder for your project in your computer's home area. We'll call ours "node_project," but feel free to pick a name you like:
mkdir node_project
Go to this folder:
cd node_project
This folder will be like the main hub of your project.
Next up, make a file called "package.json." This file holds important details about your project, like what other things it needs to work. You can open this file with a program called "nano" or any other text editor you like.
Next up, make a file called "package.json." This file holds important details about your project, like what other things it needs to work. You can open this file with a program called "nano" or any other text editor you like.
nano package.json
Now, let's add some important details about your project. We'll include its name, your name as the creator, the type of license it uses, the starting point of your app and any other things your app needs to work. Make sure to replace the example author information with your own name and contact details!
{
"name": "nodejs-image-demo",
"version": "1.0.0",
"description": "nodejs image demo",
"author": "Sammy the Shark <sammy@example.com>",
"license": "MIT",
"main": "app.js",
"keywords": [
"nodejs",
"bootstrap",
"express"
],
"dependencies": {
"express": "^4.16.4"
}
}
This document holds important details about your project like its name, the person who made it (you!) and the rules for sharing it. When choosing a name for your project, make it short and describe what it does. Also, be sure it's unique and not already used by someone else. We've put the MIT license in there, which means others can freely use and share your app's code. It's like saying, "Hey, feel free to use this, just be cool about it!
Also, in this file, you'll see:
- "main": This points to the main file of your app, which will be called "app.js." You'll create this file next.
- "dependencies": These are the other programs or tools your app needs to work properly. For now, it's just Express version 4.16.4 or newer.
Even though there's no repository listed here, you can add one later if you want to keep track of different versions of your app. It's like having a history of changes!
Once you're done making changes, save and close the file. To get everything your project needs to run, just run this command:
npm install
Now, when you run this command, it will bring in all the things your project needs as listed in that "package.json" file we created earlier. So, let's move on to creating the files that make up your application!
Build Your Node.js App:
Let's create a website that gives users cool info about sharks. Our app will have a main starting point called "app.js" and a folder called "views" where we'll keep the stuff that makes our site look cool.
We'll make a landing page, "index.html," that shows some basic shark facts and a link to a page with more detailed info, "sharks.html." In the "views" folder, we'll create both of these pages.
First things first, open up "app.js" in the main project folder. This is where we'll write the special instructions for our app.
nano app.js
The start of this file does some important stuff. It's like setting up the workspace for building our app. Here, we create the main tools (Express application and Router) we need for our website. We also set up some basic details, like where our project files are and the entrance number (port) for people to visit our site. It's like preparing the space for the cool things we're about to do!
const express = require('express');
const app = express();
const router = express.Router();
const path = __dirname + '/views/';
const port = 8080;
The "require" function is like calling for a specific tool we need, in this case, it's Express, which helps us build our website. With Express, we create two important things: the app and the router. The router is like a guide that tells our website where to send people when they click on different links or buttons. We'll add these instructions as we go along.
We also set up two special names:
We also set up two special names:
- "path" tells our app where to find our website files. In this case, it's inside a folder called "views" in our project.
- "port" tells our app which door to open so people can visit our site. We've set it to listen for visitors on door number 8080.
Next, we'll start giving our app directions on how to handle different requests using the router.
...
router.use(function (req,res,next) {
console.log('/' + req.method);
next();
});
router.get('/', function(req,res){
res.sendFile(path + 'index.html');
});
router.get('/sharks', function(req,res){
res.sendFile(path + 'sharks.html');
});
The router.use function does something helpful - it loads a special tool called a "middleware" function. This tool helps us manage and process all the requests that come to our website, directing them to the right place. It's like having a guide to make sure everyone goes to the correct spots.
After setting up this middleware, we decide what our website should do when someone asks for specific things:
- When someone visits the main URL of our website, we want to show them the "index.html" page.
- If someone goes to a specific route called "/sharks" on our site, we'll show them the "sharks.html" page.
Finally, we tell our app to put all this together and start working. We also make sure it knows to be ready for visitors on port 8080, which is like saying, "Hey world, we're here and ready to share our cool website!
...
app.use(express.static(path));
app.use('/', router);
app.listen(port, function () {
console.log('Example app listening on port 8080!')
})
The completed app.js file will appear as follows:
const express = require('express');
const app = express();
const router = express.Router();
const path = __dirname + '/views/';
const port = 8080;
router.use(function (req,res,next) {
console.log('/' + req.method);
next();
});
router.get('/', function(req,res){
res.sendFile(path + 'index.html');
});
router.get('/sharks', function(req,res){
res.sendFile(path + 'sharks.html');
});
app.use(express.static(path));
app.use('/', router);
app.listen(port, function () {
console.log('Example app listening on port 8080!')
})
Once you're done, remember to save and close the file.
Now, let's add some stuff that stays the same on our website, like pictures or styles. To begin, create a new folder called "views":
Now, let's add some stuff that stays the same on our website, like pictures or styles. To begin, create a new folder called "views":
mkdir views
Open the first page of your website, index.html:
nano views/index.html
Add the following code to the file. This will bring in Bootstrap and create a cool-looking section with a link to more detailed shark information (sharks.html):
<!DOCTYPE html>
<html lang="en">
<head>
<title>About Sharks</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link href="css/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>
<body>
<nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
<div class="container">
<button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
</button> <a class="navbar-brand" href="#">Everything Sharks</a>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav mr-auto">
<li class="active nav-item"><a href="/" class="nav-link">Home</a>
</li>
<li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="jumbotron">
<div class="container">
<h1>Want to Learn About Sharks?</h1>
<p>Are you ready to learn about sharks?</p>
<br>
<p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
</p>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-6">
<h3>Not all sharks are alike</h3>
<p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.
</p>
</div>
<div class="col-lg-6">
<h3>Sharks are ancient</h3>
<p>There is evidence to suggest that sharks lived up to 400 million years ago.
</p>
</div>
</div>
</div>
</body>
</html>
At the top of the page, there's a menu that lets users switch between the Home and Sharks pages. Inside this menu, we're using a special feature from Bootstrap to highlight the current page. It's like making the page you're on stand out. We've also set up the links to our pages. The addresses here match the routes we decided on in the app.js file. It's a bit like setting up signposts that point to the different sections of our website.
...
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav mr-auto">
<li class="active nav-item"><a href="/" class="nav-link">Home</a>
</li>
<li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
</li>
</ul>
</div>
...
Also, we've added a button in the jumbotron section that takes you to our page with more information about sharks.
...
<div class="jumbotron">
<div class="container">
<h1>Want to Learn About Sharks?</h1>
<p>Are you ready to learn about sharks?</p>
<br>
<p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
</p>
</div>
</div>
…
We also included a link to a special style sheet in the header:
...
<link href="css/styles.css" rel="stylesheet">
…
After you're done, remember to save and close the file.
Now that we have our main website page ready, let's make another page called "sharks.html." This page will have more details about sharks for those who are interested.
To get started, open up the file:
Now that we have our main website page ready, let's make another page called "sharks.html." This page will have more details about sharks for those who are interested.
To get started, open up the file:
nano views/sharks.html
Now, let's add some code to this page. It will bring in Bootstrap and our custom style sheet, and then provide users with detailed information about different types of sharks.
<!DOCTYPE html>
<html lang="en">
<head>
<title>About Sharks</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link href="css/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>
<nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
<div class="container">
<button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
</button> <a class="navbar-brand" href="/">Everything Sharks</a>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav mr-auto">
<li class="nav-item"><a href="/" class="nav-link">Home</a>
</li>
<li class="active nav-item"><a href="/sharks" class="nav-link">Sharks</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="jumbotron text-center">
<h1>Shark Info</h1>
</div>
<div class="container">
<div class="row">
<div class="col-lg-6">
<p>
<div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.
</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
</p>
</div>
<div class="col-lg-6">
<p>
<div class="caption">Other sharks are known to be friendly and welcoming!</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
</p>
</div>
</div>
</div>
</html>
Also, in this file, we're using a special class called "active" to show which page we're currently on.
Once you're done, save and close the file.
To wrap things up, let's make our custom style sheet that we linked to in both index.html and sharks.html. To start, create a new folder named "css" inside the "views" directory:
mkdir views/css
Open the CSS file:
nano views/css/styles.css
Now, let's put in the following code. This will give our pages the color and font style we want:
.navbar {
margin-bottom: 0;
}
body {
background: #020A1B;
color: #ffffff;
font-family: 'Merriweather', sans-serif;
}
h1,
h2 {
font-weight: bold;
}
p {
font-size: 16px;
color: #ffffff;
}
.jumbotron {
background: #0048CD;
color: white;
text-align: center;
}
.jumbotron p {
color: white;
font-size: 26px;
}
.btn-primary {
color: #fff;
text-color: #000000;
border-color: white;
margin-bottom: 5px;
}
img,
video,
audio {
margin-top: 20px;
max-width: 80%;
}
div.caption: {
float: left;
clear: both;
}
In this file, we not only set the font and color but also made sure the images won't be too big. We did this by saying they can't be wider than 80% of the page. This way, they won't take up more space than we want them to.
Remember to save and close the file when you're done.
Now that our application files are ready and the necessary tools are installed, it's time to start the application.
If you followed the setup guide at the beginning, you've set up a protective wall (firewall) around your server, allowing only certain types of communication. To let people access our site on door number 8080, run:
sudo ufw allow 8080
To begin using your app, make sure you're inside the main folder of your project:
cd ~/node_project
Run the program by typing 'node app.js'
node app.js
Open your web browser and go to http://your_server_ip:8080. This will take you to the main page of the website.
Press the 'Get Shark Info' button. This will take you to a page with more information about sharks
You have successfully started the application. When you're done, close the server by pressing CTRL+C. Now, let's create a Dockerfile to make it easy to use and expand this application.
Writing the Dockerfile:
Your Dockerfile is like a recipe for Docker to understand how to bundle up your app. It specifies what should be included in your application container when it runs. This ensures that your application runs smoothly and consistently, regardless of where it's deployed.
By following these guidelines on building optimized containers, we aim to make our image as efficient as possible. This involves minimizing the number of image layers and keeping the image focused on a single purpose — recreating our application files and static content. To get started, head to your project’s root directory and create the Dockerfile. This file will be crucial in helping Docker understand how to package your application effectively.
nano Dockerfile
Docker images are like a stack of building blocks, each layer adding something new. Our first step is to choose the base block for our application. We'll start with the node:10-alpine image, which is recommended because it's the Long-Term Support (LTS) version of Node.js. This image is based on Alpine Linux, which helps keep our image size small.
To make sure this choice fits your project, you can read more about it on the Docker Hub Node image page under the Image Variants section.
To set this as the foundation for our application, just add the following line to our Dockerfile:
FROM node:10-alpine
This image already has Node.js and npm installed. Every Dockerfile must start with a FROM instruction.
By default, the Docker Node image has a non-root 'node' user. It's safer to avoid running containers as root, and to only grant them the permissions they need. So, we'll use the 'node' user's home directory as our application's working directory. Inside the container, we'll also switch to using this 'node' user.
For more tips on how to work with the Docker Node image, you can check out this guide on best practices
To make sure our application code in the container has the right permissions, let's create two folders: 'node_modules' and 'app'. These folders will be created inside '/home/node'. By setting up these folders in advance, we ensure they have the correct permissions. This step is important because when we use 'npm install' to install local node modules in the container, we want to make sure everything works smoothly. We also need to make sure the folders are owned by our 'node' user.
...
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
To learn more about why it's helpful to combine multiple 'RUN' instructions, check out this discussion on managing container layers.
Next, we'll set the working directory of our application to '/home/node/app'. This is where our application code will live inside the container.
…
WORKDIR /home/node/app
If we don't specify a working directory, Docker will create one automatically. So, it's better to set it ourselves to be clear.
Next, let's copy the 'package.json' and 'package-lock.json' files. These files are important because they list all the dependencies our application needs to run correctly.
...
COPY package*.json ./
By placing the 'COPY' instruction before we run 'npm install' or copy the application code, Docker can optimize its process using caching. Each step in the build process is saved as a layer and Docker checks if it already has a cached layer for a specific instruction. If the 'package.json' file hasn't changed, Docker can reuse the existing layer, saving time by skipping the reinstallation of node modules.
To make sure all application files, including those in the 'node_modules' directory, are owned by the non-root 'node' user, we switch to using the 'node' user before running 'npm install'. This helps maintain security and ensures proper permissions for our application files.
...
USER node
Once we've copied the project dependencies and switched to using the 'node' user, we can now install the dependencies by running 'npm install'. This command will download and install all the necessary packages our application needs to run correctly.
...
RUN npm install
Next, let's copy your application code into the application directory on the container. We'll make sure to set the appropriate permissions so that everything works smoothly.
...
COPY --chown=node:node . .
This step makes sure that all the application files belong to the non-root 'node' user.
Lastly, we'll open up port 8080 on the container and start running the application.
...
EXPOSE 8080
CMD [ "node", "app.js" ]
The 'EXPOSE' command doesn't actually publish the port; instead, it's like a note to yourself and others about which ports your application will use when it's running.
The 'CMD' command is what actually starts up your application inside the container. Here, it's running the command 'node app.js', which starts our Node.js application. Remember, you should only have one 'CMD' instruction in your Dockerfile.
There's a lot more you can do with Dockerfiles! For a full list of instructions, you can check out Docker's Dockerfile reference documentation.
Here's how the complete Dockerfile looks:
FROM node:10-alpine
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
USER node
RUN npm install
COPY --chown=node:node . .
EXPOSE 8080
CMD [ "node", "app.js" ]
After you're done making changes, remember to save and close the file.
Before we build the application image, let's create a .dockerignore file. It works similarly to a .gitignore file – it tells Docker which files and directories in your project directory should not be copied into your container.
Now, let's open the .dockerignore file.
nano .dockerignore
In the .dockerignore file, list the names of the folders and files you don't want Docker to include in the image. These typically include your local node modules, npm logs, Dockerfile, and the .dockerignore file itself.
node_modules
npm-debug.log
Dockerfile
.dockerignore
If you're using Git, it's a good idea to add your .git directory and .gitignore file to the .dockerignore file as well.
Once you've added all the necessary files to the .dockerignore file, save and close it.
Now, you're ready to build the application image using the 'docker build' command. Adding the '-t' flag allows you to give the image a name that's easy to remember. Since we'll be pushing the image to Docker Hub, let's include your Docker Hub username in the tag. We'll name the image 'nodejs-image-demo', but you can choose any name you like. Just make sure to replace 'your_dockerhub_username' with your actual Docker Hub username.
sudo docker build -t your_dockerhub_username/nodejs-image-demo .
The '.' in the command specifies that Docker should use the current directory as the location to build the image from.
Building the image will take a little time, usually a minute or two. Once it's done, you can check the images to see if it was created successfully.
sudo docker images
After running the command, you'll see some messages on your screen. These messages will show you what's happening as Docker builds your image. Once it's finished, you'll get some output that confirms the process is complete.
Output
REPOSITORY TAG IMAGE ID CREATED SIZE
your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 73MB
node 10-alpine f09e7c96b6de 3 weeks ago 70.7MB
Now, we can create a container using the 'docker run' command. We'll add three flags to this command:
-p: This flag allows us to publish a port on the container and map it to a port on our host. By default, we'll use port 80 on the host, but you can change this if needed, especially if another process is already using that port. You can learn more about how this works by reading the discussion in the Docker documentation on port binding.
-d: This flag tells Docker to run the container in the background, so it won't tie up your command line.
--name: This flag lets us give the container a name that's easy to remember.
Here's the command to run:
sudo docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
After your container is running, you can check a list of all your running containers using the command 'docker ps'.
sudo docker ps
You'll see some information displayed on your screen. This output will show you details about the containers that are currently running.
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e50ad27074a7 your_dockerhub_username/nodejs-image-demo "node app.js" 8 seconds ago Up 7 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo
Now that your container is up and running, you can access your application by opening your web browser and typing in your server's IP address without specifying a port.
http://your_server_ip
You'll see your application's main page load once more in your web browser.
Now that you've finished creating an image for your application, you can upload it to Docker Hub. This way, you'll have it stored online and can access it whenever you need.
Storing Your App on DockerHub:
Think of DockerHub as a big online storage space. You can save a copy of your app there so you can easily share it or use it again later. It's like having a safe spot for your digital stuff!
To start, log in to your Docker Hub account, which you should have created earlier.
To start, log in to your Docker Hub account, which you should have created earlier.
sudo docker login -u your_dockerhub_username
When asked, type in your Docker Hub account password. This will save your login details in a file called ~/.docker/config.json in your computer's home folder.
Now, you can upload your application image to Docker Hub. Use the tag you created earlier: your_dockerhub_username/nodejs-image-demo.
sudo docker push your_dockerhub_username/nodejs-image-demo
Now, let's see which containers are currently running on your computer.
sudo docker ps
You'll see some information displayed on your screen. This output will show you details about the containers that are currently running.
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e50ad27074a7 your_dockerhub_username/nodejs-image-demo "node app.js" 3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp nodejs-image-dem
To stop your running app, find the special ID in the list that Docker showed you. Replace the highlighted part below with your unique ID:
sudo docker stop e50ad27074a7
See a list of all your images by adding the -a flag:
docker images -a
After running the command, you'll see a list showing the name of your image. It might look like "your_dockerhub_username/nodejs-image-demo," and you'll also see the node image along with any other images you've created.
Output
REPOSITORY TAG IMAGE ID CREATED SIZE
your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 7 minutes ago 73MB
<none> <none> 2e3267d9ac02 4 minutes ago 72.9MB
<none> <none> 8352b41730b9 4 minutes ago 73MB
<none> <none> 5d58b92823cb 4 minutes ago 73MB
<none> <none> 3f1e35d7062a 4 minutes ago 73MB
<none> <none> 02176311e4d0 4 minutes ago 73MB
<none> <none> 8e84b33edcda 4 minutes ago 70.7MB
<none> <none> 6a5ed70f86f2 4 minutes ago 70.7MB
<none> <none> 776b2637d3c1 4 minutes ago 70.7MB
node 10-alpine f09e7c96b6de 3 weeks ago 70.7MB
To clean up, use the following command to remove the stopped container and all images, including the ones that are not being used:
docker system prune -a
When you see a question in the output, type 'y' to confirm that you want to get rid of the stopped container and images. Just so you know, this will also delete your build cache.
Now, you've successfully removed the container running your app and the image itself. If you want to learn more about removing Docker stuff, check out this guide on How To Remove Docker Images, Containers, and Volumes.
Now that everything is cleaned up, you can get your application image back from Docker Hub:
docker pull your_dockerhub_username/nodejs-image-demo
List your images again to make sure everything has been cleaned up:
docker images
Look at the output, and you should see your application image listed:
Output
REPOSITORY TAG IMAGE ID CREATED SIZE
your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 73MB
Now, you can recreate your container by using the command from Step 3:
docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
Check which containers are currently running by using the following command:
docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "node app.js" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-dem
Go to http://your_server_ip once more to see your application in action.
Conclusion
In this guide, you built a simple website using Express and Bootstrap. You also made a special package for your app, called a Docker image. You used this image to create a container and shared it on Docker Hub. Later, you learned how to delete and rebuild your image and container using Docker Hub.
Great job! Now, you can explore more and create awesome things with Docker.
If you have any questions or want to learn more, feel free to ask or check out additional resources. Happy coding!