tutorial-cloud/blog/2019-05-29-blog-4.md
2024-10-25 10:05:08 +05:30

700 lines
38 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
slug: fourth-blog-post
title: Fourth Blog Post
authors: [slorber, yangshun]
tags: [hola, docusaurus]
---
<!-- truncate -->
import CodeBlock from '@site/src/components/CodeBloack';
<br/>
<span className="main-head">Creating a Node.js App with Docker: A Step-by-Step Guide</span>
<div className="head">Let's Dive into Docker!</div>
<div className="text">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. <br/> <br/>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. <br/><br/>They also keep our apps separate from each other, like little islands, so they don't mess with one another.<br/><br/>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!<br/><br/>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. <br/><br/>
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. <br/> <br/>
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!</div>
<div className="head">Requirements</div>
<div className="text">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. <br/> <br/>To try out this guide, make sure you have: <br/> <br/> <ol><li>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.</li> <br/> <li>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.</li> <br/> <li>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.
</li> <br/> <li>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.</li></ol></div>
<div className="head">Creating Your Node.js App with Docker: Easy Steps</div>
<div className="text"><ol><li><strong>Get Your App Ready</strong>:<br/>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!</li><br/><li><strong>Build Your Node.js App</strong>:<br/>Craft the files for your Node.js app. This is where you put the magic code that makes your app work like a charm.</li><br/><li><strong>Guide Docker with Your App's Blueprint:</strong><br/>
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!</li> <br/><li><strong>Store Your App in the DockerHub Closet</strong>:<br/>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!</li></ol></div><br/>
<div className="text"><span className="text" style={{ fontSize:'28px' }}>Prepare Your App:</span><br/>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:</div>
<CodeBlock code={`mkdir node_project`} /><br/>
<div className="text">Go to this folder: </div>
<CodeBlock code={` cd node_project`} /><br/>
<div className="text">This folder will be like the main hub of your project.<br/>
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.</div>
<CodeBlock code={`nano package.json`} /><br/>
<div className="text">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!</div>
<CodeBlock code={`{
"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"
}
}
`} /><br/>
<div className="text">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!</div>
<div className="text">Also, in this file, you'll see:</div>
<div className="text"><ol><li>"main": This points to the main file of your app, which will be called "app.js." You'll create this file next.</li><li>"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.</li></ol></div>
<div className="text">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!</div>
<div className="text">Once you're done making changes, save and close the file. To get everything your project needs to run, just run this command:</div>
<CodeBlock code={`npm install`} /><br/>
<div className="text">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!</div><br/>
<span className="text" style={{ fontSize:'28px' }}>Build Your Node.js App:</span>
<div className="text">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.</div><br/>
<div className="text">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.</div><br/>
<div className="text">First things first, open up "app.js" in the main project folder. This is where we'll write the special instructions for our app.</div>
<CodeBlock code={`nano app.js`} /><br/>
<div className="text">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!</div>
<CodeBlock code={`const express = require('express');
const app = express();
const router = express.Router();
const path = __dirname + '/views/';
const port = 8080;
`} /><br/>
<div className="text">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. <br/><br/> We also set up two special names:</div>
<div className="text"><ol><li>"path" tells our app where to find our website files. In this case, it's inside a folder called "views" in our project.</li><li>"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.</li></ol></div>
<div className="text">Next, we'll start giving our app directions on how to handle different requests using the router.</div>
<CodeBlock code={`...
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');
});
`} /><br/>
<div className="text">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.</div> <br/>
<div className="text">After setting up this middleware, we decide what our website should do when someone asks for specific things:</div>
<div className="text"><ul><li>When someone visits the main URL of our website, we want to show them the "index.html" page.</li><li>If someone goes to a specific route called "/sharks" on our site, we'll show them the "sharks.html" page.</li></ul></div>
<div className="text">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!</div>
<CodeBlock code={`...
app.use(express.static(path));
app.use('/', router);
app.listen(port, function () {
console.log('Example app listening on port 8080!')
})
`} /><br/>
<div className="text">The completed app.js file will appear as follows:</div>
<CodeBlock code={`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!')
})
`} /><br/>
<div className="text">Once you're done, remember to save and close the file.<br/>
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":</div>
<CodeBlock code={`mkdir views`} /><br/>
<div className="text">Open the first page of your website, index.html:</div>
<CodeBlock code={`nano views/index.html`} /><br/>
<div className="text">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):</div>
<CodeBlock code={`<!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>
`} /><br/>
<div className="text">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>
<CodeBlock code={`...
<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>
...
`} /><br/>
<div className="text">Also, we've added a button in the jumbotron section that takes you to our page with more information about sharks.</div>
<CodeBlock code={`...
<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>
`} /><br/>
<div className="text">We also included a link to a special style sheet in the header:</div>
<CodeBlock code={`...
<link href="css/styles.css" rel="stylesheet">
`} /><br/>
<div className="text">After you're done, remember to save and close the file.<br/><br/>
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.<br/><br/>
To get started, open up the file:</div>
<CodeBlock code={`nano views/sharks.html`} /><br/>
<div className="text">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.</div>
<CodeBlock code={`<!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>
`} /><br/>
<div className="text">Also, in this file, we're using a special class called "active" to show which page we're currently on.</div>
<div className="text">Once you're done, save and close the file.</div>
<div className="text">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:</div>
<CodeBlock code={`mkdir views/css`} /><br/>
<div className="text">Open the CSS file:</div>
<CodeBlock code={`nano views/css/styles.css`} /><br/>
<div className="text">Now, let's put in the following code. This will give our pages the color and font style we want:</div>
<CodeBlock code={`.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;
}
`} /><br/>
<div className="text">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.</div> <br/>
<div className="text">Remember to save and close the file when you're done.</div> <br/>
<div classsName="text">Now that our application files are ready and the necessary tools are installed, it's time to start the application.</div><br/>
<div className="text">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:</div>
<CodeBlock code={`sudo ufw allow 8080`} /><br/>
<div className="text">To begin using your app, make sure you're inside the main folder of your project:</div>
<CodeBlock code={`cd ~/node_project`} /><br/>
<div className="">Run the program by typing 'node app.js'</div>
<CodeBlock code={`node app.js`} /><br/>
<div className="text">Open your web browser and go to http://your_server_ip:8080. This will take you to the main page of the website.</div>
<div className="text">Press the 'Get Shark Info' button. This will take you to a page with more information about sharks</div>
<div className="text">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.</div><br/>
<div className="text" style={{ fontSize:'28px' }}>Writing the Dockerfile:</div>
<div className="text">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.</div><br/>
<div className="text">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 projects root directory and create the Dockerfile. This file will be crucial in helping Docker understand how to package your application effectively.</div>
<CodeBlock code={`nano Dockerfile`} /><br/>
<div className="text">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.</div> <br/>
<div className="text">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:</div>
<CodeBlock code={`FROM node:10-alpine`} /><br/>
<div className="text">This image already has Node.js and npm installed. Every Dockerfile must start with a FROM instruction.</div> <br/>
<div className="text">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.</div><br/>
<div className="text">For more tips on how to work with the Docker Node image, you can check out this guide on best practices</div><br/>
<div className="text">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.</div>
<CodeBlock code={`...
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app`} /><br/>
<div className="text">To learn more about why it's helpful to combine multiple 'RUN' instructions, check out this discussion on managing container layers.</div> <br/>
<div className="text">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.</div>
<CodeBlock code={`…
WORKDIR /home/node/app`} /><br/>
<div className="text">If we don't specify a working directory, Docker will create one automatically. So, it's better to set it ourselves to be clear.</div><br/>
<div className="text">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.</div>
<CodeBlock code={`...
COPY package*.json ./
`} /><br/>
<div className="text">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.</div><br/>
<div className="text">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.</div>
<CodeBlock code={`...
USER node
`} /><br/>
<div className="text">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.</div>
<CodeBlock code={`...
RUN npm install
`} /><br/>
<div className="text">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.</div>
<CodeBlock code={`...
COPY --chown=node:node . .
`} /><br/>
<div className="text">This step makes sure that all the application files belong to the non-root 'node' user.</div><br/>
<div className="text">Lastly, we'll open up port 8080 on the container and start running the application.</div>
<CodeBlock code={`
...
EXPOSE 8080
CMD [ "node", "app.js" ]
`} /><br/>
<div className="text">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.</div> <br/>
<div className="text">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.</div> <br/>
<div className="text">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.</div> <br/>
<div className="text">Here's how the complete Dockerfile looks:</div> <br/>
<CodeBlock code={`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" ]
`} /><br/>
<div className="text">After you're done making changes, remember to save and close the file.</div> <br/>
<div className="text">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.</div> <br/>
<div className="text">Now, let's open the .dockerignore file.</div>
<CodeBlock code={`nano .dockerignore
`} /><br/>
<div className="text">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.</div>
<CodeBlock code={`node_modules
npm-debug.log
Dockerfile
.dockerignore
`} /><br/>
<div className="text">If you're using Git, it's a good idea to add your .git directory and .gitignore file to the .dockerignore file as well.</div> <br/>
<div className="text">Once you've added all the necessary files to the .dockerignore file, save and close it.</div><br/>
<div className="text">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.</div>
<CodeBlock code={`sudo docker build -t your_dockerhub_username/nodejs-image-demo .
`} /><br/>
<div className="text">The '.' in the command specifies that Docker should use the current directory as the location to build the image from.</div> <br/>
<div className="text">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.</div>
<CodeBlock code={`sudo docker images`} /><br/>
<div className="text">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.</div>
<CodeBlock code={`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
`} /><br/>
<div className="text">Now, we can create a container using the 'docker run' command. We'll add three flags to this command:</div><br/>
<div className="text">-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.</div><br/>
<div ClassName="text">-d: This flag tells Docker to run the container in the background, so it won't tie up your command line.</div><br/>
<div className="text">--name: This flag lets us give the container a name that's easy to remember.</div><br/>
<div className="text">Here's the command to run:</div>
<CodeBlock code={`sudo docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo`} /><br/>
<div className="text">After your container is running, you can check a list of all your running containers using the command 'docker ps'.</div>
<CodeBlock code={`sudo docker ps`} /><br/>
<div className="text">You'll see some information displayed on your screen. This output will show you details about the containers that are currently running.</div> <br/>
<CodeBlock code={`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
`} /><br/>
<div className="text">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.</div>
<CodeBlock code={`http://your_server_ip`} /><br/>
<div className="text">You'll see your application's main page load once more in your web browser.</div><br/>
<div className="text">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.</div> <br/>
<div className="text" style={{ fontSize:'28px' }}>Storing Your App on DockerHub:</div>
<div className="text">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! <br/> <br/> To start, log in to your Docker Hub account, which you should have created earlier.</div><br/>
<div className="text">sudo docker login -u your_dockerhub_username</div> <br/>
<div className="text">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.</div><br/>
<div className="text">Now, you can upload your application image to Docker Hub. Use the tag you created earlier: your_dockerhub_username/nodejs-image-demo.</div>
<CodeBlock code={`sudo docker push your_dockerhub_username/nodejs-image-demo`} /><br/>
<div className="text">Now, let's see which containers are currently running on your computer.</div>
<CodeBlock code={`sudo docker ps`} /><br/>
<div className="text">You'll see some information displayed on your screen. This output will show you details about the containers that are currently running.</div>
<CodeBlock code={`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
`} /><br/>
<div className="text">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:</div>
<CodeBlock code={`sudo docker stop e50ad27074a7`} /><br/>
<div className="text">See a list of all your images by adding the -a flag:</div>
<CodeBlock code={`docker images -a`} /><br/>
<div className="text">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.</div>
<CodeBlock code={`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
`} /><br/>
<div className="text">To clean up, use the following command to remove the stopped container and all images, including the ones that are not being used:</div>
<CodeBlock code={`docker system prune -a`} /><br/>
<div className="text">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.</div><br/>
<div className="text">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.</div><br/>
<div className="text">Now that everything is cleaned up, you can get your application image back from Docker Hub:</div>
<CodeBlock code={`docker pull your_dockerhub_username/nodejs-image-demo`} /><br/>
<div className="text">List your images again to make sure everything has been cleaned up:</div>
<CodeBlock code={`docker images`} /><br/>
<div className="text">Look at the output, and you should see your application image listed:</div>
<CodeBlock code={`Output
REPOSITORY TAG IMAGE ID CREATED SIZE
your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 73MB
`} /><br/>
<div className="text">Now, you can recreate your container by using the command from Step 3:</div>
<CodeBlock code={`docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo`} /><br/>
<div className="text">Check which containers are currently running by using the following command:</div>
<CodeBlock code={`docker ps`} /><br/>
<CodeBlock code={`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
`} /><br/>
<div className="text">Go to http://your_server_ip once more to see your application in action.</div> <br/>
<div className="con">Conclusion</div>
<div className="text">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.</div> <br/>
<div className="text">Great job! Now, you can explore more and create awesome things with Docker.</div><br/>
<div className="text">If you have any questions or want to learn more, feel free to ask or check out additional resources. Happy coding!</div>