<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: katjuell</title>
    <description>The latest articles on DEV Community by katjuell (@katjuell).</description>
    <link>https://dev.to/katjuell</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F122714%2Fbc8e92e7-cb00-4f2e-981c-d012a2f8a5ac.jpg</url>
      <title>DEV Community: katjuell</title>
      <link>https://dev.to/katjuell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/katjuell"/>
    <language>en</language>
    <item>
      <title>From Containers to Kubernetes with Node.js: A Free eBook</title>
      <dc:creator>katjuell</dc:creator>
      <pubDate>Wed, 13 May 2020 01:19:14 +0000</pubDate>
      <link>https://dev.to/digitalocean/from-containers-to-kubernetes-with-node-js-a-free-ebook-28l6</link>
      <guid>https://dev.to/digitalocean/from-containers-to-kubernetes-with-node-js-a-free-ebook-28l6</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---zfQ5jQ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community-cdn-digitalocean-com.global.ssl.fastly.net/assets/tutorials/images/large/containers-k8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---zfQ5jQ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community-cdn-digitalocean-com.global.ssl.fastly.net/assets/tutorials/images/large/containers-k8s.png" alt="From Containers to Kubernetes banner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We at &lt;a href="https://dev.to/digitalocean"&gt;DigitalOcean&lt;/a&gt; are excited to share with you a free eBook to support you in containerizing and scaling your apps with open source technology. &lt;em&gt;From Containers to Kubernetes with Node.js&lt;/em&gt; is available for download in &lt;a href="https://do.co/containers-k8s-pdf"&gt;PDF&lt;/a&gt; or &lt;a href="https://do.co/containers-k8s-epub"&gt;EPUB&lt;/a&gt; format. &lt;/p&gt;

&lt;h1&gt;
  
  
  About this Book
&lt;/h1&gt;

&lt;p&gt;This book is designed as an introduction to containers and &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; by way of &lt;a href="https://nodejs.org/"&gt;Node.js&lt;/a&gt;. Containers are the basis for distributed, repeatable workflows with orchestrators such as Kubernetes, and they allow developers and operators to develop applications consistently across environments and deploy in a repeatable and predictable fashion.&lt;/p&gt;

&lt;p&gt;The examples in this book focus on Node.js, a JavaScript runtime, and demonstrate how to develop an application that communicates with a &lt;a href="https://www.mongodb.com/"&gt;MongoDB&lt;/a&gt; backend. Though the chapters of the book cover cumulative topics – from how to develop a stateless application, to adding storage, to containerization – they can also be used as independent guides.&lt;/p&gt;

&lt;h1&gt;
  
  
  Motivation for this Book
&lt;/h1&gt;

&lt;p&gt;Often, resources on development and deployment are relatively independent of one another: guides on containers and Kubernetes rarely cover application development, and tutorials on languages and frameworks are often focused on languages and other nuances rather than on deployment.&lt;/p&gt;

&lt;p&gt;This book is designed to be a full-stack introduction to containers and Kubernetes by way of Node.js application development. It assumes that readers want an introduction not only to the fundamentals of containerization, but also to the basics of working with Node and a NoSQL database backend.&lt;/p&gt;

&lt;h1&gt;
  
  
  Learning Goals and Outcomes
&lt;/h1&gt;

&lt;p&gt;The goal for this guide is to serve readers interested in Node application development, as well as readers who would like to learn more about working with containers and container orchestrators. It assumes a shared interest in moving away from highly individuated local environments, and toward repeatable, reproducible application environments that ensure consistency and ultimately resiliency over time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Download the Book
&lt;/h1&gt;

&lt;p&gt;You can download the eBook for free in the following formats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://do.co/containers-k8s-epub"&gt;&lt;em&gt;From Containers to Kubernetes with Node.js&lt;/em&gt; eBook in EPUB format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://do.co/containers-k8s-pdf"&gt;&lt;em&gt;From Containers to Kubernetes with Node.js&lt;/em&gt; eBook in PDF format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/books/details/Kathleen_Juell_From_Containers_to_Kubernetes_with?id=ZUjiDwAAQBAJ"&gt;&lt;em&gt;From Containers to Kubernetes with Node.js&lt;/em&gt; eBook on Google Books&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A9EYAC7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/23m8zn9286imufi6i25y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9EYAC7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/23m8zn9286imufi6i25y.png" alt="From Containers to Kubernetes eBook cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To learn more about the book, check out our &lt;a href="https://www.digitalocean.com/community/books/from-containers-to-kubernetes-with-node-js-ebook"&gt;book landing page&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>containers</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>How To Build a Node.js Application with Docker [Quickstart]</title>
      <dc:creator>katjuell</dc:creator>
      <pubDate>Mon, 17 Feb 2020 14:42:56 +0000</pubDate>
      <link>https://dev.to/digitalocean/how-to-build-a-node-js-application-with-docker-quickstart-432</link>
      <guid>https://dev.to/digitalocean/how-to-build-a-node-js-application-with-docker-quickstart-432</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;This tutorial will walk you through creating an application image for a static website that uses the &lt;a href="https://expressjs.com/"&gt;Express&lt;/a&gt; framework and &lt;a href="https://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt;. You will then build a container using that image, push it to &lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt;, and use it to build another container, demonstrating how you can recreate and scale your application.&lt;/p&gt;

&lt;p&gt;For a more detailed version of this tutorial, with more detailed explanations of each step, please refer to &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-build-a-node-js-application-with-docker"&gt;How To Build a Node.js Application with Docker&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A &lt;code&gt;sudo&lt;/code&gt; user on your server or in your local environment.&lt;/li&gt;
&lt;li&gt;  Docker.&lt;/li&gt;
&lt;li&gt;  Node.js and &lt;code&gt;npm&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  A Docker Hub account.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1 — Installing Your Application Dependencies
&lt;/h2&gt;

&lt;p&gt;First, create a directory for your project in your non-root user’s home directory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir node_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Navigate to this directory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd node_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will be the root directory of the project.&lt;/p&gt;

&lt;p&gt;Next, create a &lt;a href="https://docs.npmjs.com/files/package.json"&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/a&gt; with your project’s dependencies:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add the following information about the project to the file; be sure to replace the author information with your own name and contact details:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node_project/package.json

{
  "name": "nodejs-image-demo",
  "version": "1.0.0",
  "description": "nodejs image demo",
  "author": "Sammy the Shark &amp;lt;sammy@example.com&amp;gt;",
  "license": "MIT",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Install your project’s dependencies:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 2 — Creating the Application Files
&lt;/h2&gt;

&lt;p&gt;We will create a website that offers users information about sharks.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;app.js&lt;/code&gt; in the main project directory to define the project’s routes:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add the following content to the file to create the Express application and Router objects, define the base directory, port, and host as variables, set the routes, and mount the &lt;code&gt;router&lt;/code&gt; middleware along with the application’s static assets:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node_project/app.js

var express = require("express");
var app = express();
var router = express.Router();

var path = __dirname + '/views/';

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

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(8080, function () {
  console.log('Example app listening on port 8080!')
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, let’s add some static content to the application. Create the &lt;code&gt;views&lt;/code&gt; directory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir views
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano views/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add the following code to the file, which will import Boostrap and create a &lt;a href="https://getbootstrap.com/docs/4.0/components/jumbotron/"&gt;jumbotron&lt;/a&gt; component with a link to the more detailed &lt;code&gt;sharks.html&lt;/code&gt; info page:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node_project/views/index.html

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
   &amp;lt;head&amp;gt;
      &amp;lt;title&amp;gt;About Sharks&amp;lt;/title&amp;gt;
      &amp;lt;meta charset="utf-8"&amp;gt;
      &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
      &amp;lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"&amp;gt;
      &amp;lt;link href="css/styles.css" rel="stylesheet"&amp;gt;
      &amp;lt;link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'&amp;gt;
      &amp;lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"&amp;gt;&amp;lt;/script&amp;gt;
      &amp;lt;script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"&amp;gt;&amp;lt;/script&amp;gt;
   &amp;lt;/head&amp;gt;
   &amp;lt;body&amp;gt;
      &amp;lt;nav class="navbar navbar-inverse navbar-static-top"&amp;gt;
         &amp;lt;div class="container"&amp;gt;
            &amp;lt;div class="navbar-header"&amp;gt;
               &amp;lt;button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"&amp;gt;
               &amp;lt;span class="sr-only"&amp;gt;Toggle navigation&amp;lt;/span&amp;gt;
               &amp;lt;span class="icon-bar"&amp;gt;&amp;lt;/span&amp;gt;
               &amp;lt;span class="icon-bar"&amp;gt;&amp;lt;/span&amp;gt;
               &amp;lt;span class="icon-bar"&amp;gt;&amp;lt;/span&amp;gt;
               &amp;lt;/button&amp;gt;
               &amp;lt;a class="navbar-brand" href="#"&amp;gt;Everything Sharks&amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"&amp;gt;
               &amp;lt;ul class="nav navbar-nav mr-auto"&amp;gt;
                  &amp;lt;li class="active"&amp;gt;&amp;lt;a href="/"&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                  &amp;lt;li&amp;gt;&amp;lt;a href="/sharks"&amp;gt;Sharks&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
               &amp;lt;/ul&amp;gt;
            &amp;lt;/div&amp;gt;
         &amp;lt;/div&amp;gt;
      &amp;lt;/nav&amp;gt;
      &amp;lt;div class="jumbotron"&amp;gt;
         &amp;lt;div class="container"&amp;gt;
            &amp;lt;h1&amp;gt;Want to Learn About Sharks?&amp;lt;/h1&amp;gt;
            &amp;lt;p&amp;gt;Are you ready to learn about sharks?&amp;lt;/p&amp;gt;
            &amp;lt;br&amp;gt;
            &amp;lt;p&amp;gt;&amp;lt;a class="btn btn-primary btn-lg" href="/sharks" role="button"&amp;gt;Get Shark Info&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
         &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="container"&amp;gt;
         &amp;lt;div class="row"&amp;gt;
            &amp;lt;div class="col-md-6"&amp;gt;
               &amp;lt;h3&amp;gt;Not all sharks are alike&amp;lt;/h3&amp;gt;
               &amp;lt;p&amp;gt;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.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="col-md-6"&amp;gt;
               &amp;lt;h3&amp;gt;Sharks are ancient&amp;lt;/h3&amp;gt;
               &amp;lt;p&amp;gt;There is evidence to suggest that sharks lived up to 400 million years ago.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
         &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
   &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, open a file called &lt;code&gt;sharks.html&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano views/sharks.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add the following code, which imports Bootstrap and the custom style sheet and offers users detailed information about certain sharks:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node_project/views/sharks.html

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
   &amp;lt;head&amp;gt;
      &amp;lt;title&amp;gt;About Sharks&amp;lt;/title&amp;gt;
      &amp;lt;meta charset="utf-8"&amp;gt;
      &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
      &amp;lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"&amp;gt;
      &amp;lt;link href="css/styles.css" rel="stylesheet"&amp;gt;
      &amp;lt;link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'&amp;gt;
      &amp;lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"&amp;gt;&amp;lt;/script&amp;gt;
      &amp;lt;script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"&amp;gt;&amp;lt;/script&amp;gt;
   &amp;lt;/head&amp;gt;
   &amp;lt;nav class="navbar navbar-inverse navbar-static-top"&amp;gt;
      &amp;lt;div class="container"&amp;gt;
         &amp;lt;div class="navbar-header"&amp;gt;
            &amp;lt;button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"&amp;gt;
            &amp;lt;span class="sr-only"&amp;gt;Toggle navigation&amp;lt;/span&amp;gt;
            &amp;lt;span class="icon-bar"&amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="icon-bar"&amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="icon-bar"&amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;a class="navbar-brand" href="#"&amp;gt;Everything Sharks&amp;lt;/a&amp;gt;
         &amp;lt;/div&amp;gt;
         &amp;lt;div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"&amp;gt;
            &amp;lt;ul class="nav navbar-nav mr-auto"&amp;gt;
               &amp;lt;li&amp;gt;&amp;lt;a href="/"&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
               &amp;lt;li class="active"&amp;gt;&amp;lt;a href="/sharks"&amp;gt;Sharks&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
            &amp;lt;/ul&amp;gt;
         &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
   &amp;lt;/nav&amp;gt;
   &amp;lt;div class="jumbotron text-center"&amp;gt;
      &amp;lt;h1&amp;gt;Shark Info&amp;lt;/h1&amp;gt;
   &amp;lt;/div&amp;gt;
   &amp;lt;div class="container"&amp;gt;
      &amp;lt;div class="row"&amp;gt;
         &amp;lt;div class="col-md-6"&amp;gt;
            &amp;lt;p&amp;gt;
            &amp;lt;div class="caption"&amp;gt;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.&amp;lt;/div&amp;gt;
            &amp;lt;img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark"&amp;gt;
            &amp;lt;/p&amp;gt;
         &amp;lt;/div&amp;gt;
         &amp;lt;div class="col-md-6"&amp;gt;
            &amp;lt;p&amp;gt;
            &amp;lt;div class="caption"&amp;gt;Other sharks are known to be friendly and welcoming!&amp;lt;/div&amp;gt;
            &amp;lt;img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark"&amp;gt;
            &amp;lt;/p&amp;gt;
         &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
   &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, create the custom CSS style sheet that you’ve linked to in &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;sharks.html&lt;/code&gt; by first creating a &lt;code&gt;css&lt;/code&gt; folder in the &lt;code&gt;views&lt;/code&gt; directory:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir views/css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open the style sheet and add the following code, which will set the desired color and font for our pages:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node_project/views/css/styles.css

.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;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Start the application:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Navigate your browser to &lt;code&gt;http://your_server_ip:8080&lt;/code&gt; or &lt;code&gt;localhost:8080&lt;/code&gt; if you are working locally. You will see the following landing page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EVWDhAb3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p78.f0.n0.cdn.getcloudapp.com/items/Apurwmpy/Image%2B2020-02-16%2Bat%2B12.15.49%2BPM.png%3Fv%3D89d76edf51d32f09dbd98848663e08eb" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EVWDhAb3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p78.f0.n0.cdn.getcloudapp.com/items/Apurwmpy/Image%2B2020-02-16%2Bat%2B12.15.49%2BPM.png%3Fv%3D89d76edf51d32f09dbd98848663e08eb" alt="Application Landing Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;Get Shark Info&lt;/strong&gt; button. You will see the following information page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wgo0dQ8g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p78.f0.n0.cdn.getcloudapp.com/items/YEuAjwnX/Image%2B2020-02-16%2Bat%2B12.16.41%2BPM.png%3Fv%3D9c3f17211b00e78f4d66a5e4150bdaa9" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wgo0dQ8g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p78.f0.n0.cdn.getcloudapp.com/items/YEuAjwnX/Image%2B2020-02-16%2Bat%2B12.16.41%2BPM.png%3Fv%3D9c3f17211b00e78f4d66a5e4150bdaa9" alt="Shark Info Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You now have an application up and running. When you are ready, quit the server by typing &lt;code&gt;CTRL+C&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Writing the Dockerfile
&lt;/h2&gt;

&lt;p&gt;In your project’s root directory, create the Dockerfile:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add the following code to the file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node_project/Dockerfile

 FROM node:10-alpine

 RUN mkdir -p /home/node/app/node_modules &amp;amp;&amp;amp; 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" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This Dockerfile uses an &lt;a href="https://alpinelinux.org/"&gt;alpine base image&lt;/a&gt; and ensures that application files are owned by the non-root &lt;strong&gt;node&lt;/strong&gt; user that is provided by default by the &lt;a href="https://hub.docker.com/_/node/"&gt;Docker Node image&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, add your local node modules, npm logs, Dockerfile, and &lt;code&gt;.dockerignore&lt;/code&gt; to your &lt;code&gt;.dockerignore&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/node_project/.dockerignore

node_modules
npm-debug.log
Dockerfile
.dockerignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Build the application image using the &lt;a href="https://docs.docker.com/engine/reference/commandline/build/"&gt;&lt;code&gt;docker build&lt;/code&gt;&lt;/a&gt; command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t your_dockerhub_username/nodejs-image-demo .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;.&lt;/code&gt; specifies that the build context is the current directory.&lt;/p&gt;

&lt;p&gt;Check your images:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will see the following output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output

REPOSITORY                                         TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo          latest              1c723fb2ef12        8 seconds ago       895MB
node                                               10                  f09e7c96b6de        17 hours ago        893MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the following command to build a container using this image:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Inspect the list of your running containers with &lt;a href="https://docs.docker.com/engine/reference/commandline/ps/"&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will see the following output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output

CONTAINER ID        IMAGE                                                   COMMAND             CREATED             STATUS              PORTS                  NAMES
e50ad27074a7        your_dockerhub_username/nodejs-image-demo               "npm start"         8 seconds ago       Up 7 seconds        0.0.0.0:80-&amp;gt;8080/tcp   nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With your container running, you can now visit your application by navigating your browser to &lt;code&gt;http://your_server_ip&lt;/code&gt; or &lt;code&gt;localhost&lt;/code&gt;. You will see your application landing page once again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5tkQz4B---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p78.f0.n0.cdn.getcloudapp.com/items/Z4u5vN0N/Image%2B2020-02-16%2Bat%2B12.17.39%2BPM.png%3Fv%3D4a511a7c88e87730c31fd689f78073a2" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5tkQz4B---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p78.f0.n0.cdn.getcloudapp.com/items/Z4u5vN0N/Image%2B2020-02-16%2Bat%2B12.17.39%2BPM.png%3Fv%3D4a511a7c88e87730c31fd689f78073a2" alt="Application Landing Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have created an image for your application, you can push it to Docker Hub for future use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Using a Repository to Work with Images
&lt;/h2&gt;

&lt;p&gt;The first step to pushing the image is to log in to the your Docker Hub account:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker login -u your_dockerhub_username -p your_dockerhub_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Logging in this way will create a &lt;code&gt;~/.docker/config.json&lt;/code&gt; file in your user’s home directory with your Docker Hub credentials.&lt;/p&gt;

&lt;p&gt;Push your image up using your own username in place of &lt;code&gt;your_dockerhub_username&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push your_dockerhub_username/nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you would like, you can test the utility of the image registry by destroying your current application container and image and rebuilding them.&lt;/p&gt;

&lt;p&gt;First, list your running containers:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will see the following output:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output

CONTAINER ID        IMAGE                                       COMMAND             CREATED             STATUS              PORTS                  NAMES
e50ad27074a7        your_dockerhub_username/nodejs-image-demo   "npm start"         3 minutes ago       Up 3 minutes        0.0.0.0:80-&amp;gt;8080/tcp   nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Using the &lt;code&gt;CONTAINER ID&lt;/code&gt; listed in your output, stop the running application container. Be sure to replace the highlighted ID below with your own &lt;code&gt;CONTAINER ID&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker stop e50ad27074a7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;List your all of your images with the &lt;code&gt;-a&lt;/code&gt; flag:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker images -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will see the following output with the name of your image, &lt;code&gt;your_dockerhub_username/nodejs-image-demo&lt;/code&gt;, along with the &lt;code&gt;node&lt;/code&gt; image and the other images from your build:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output

REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo            latest              1c723fb2ef12        7 minutes ago       895MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              e039d1b9a6a0        7 minutes ago       895MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              dfa98908c5d1        7 minutes ago       895MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              b9a714435a86        7 minutes ago       895MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              51de3ed7e944        7 minutes ago       895MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              5228d6c3b480        7 minutes ago       895MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              833b622e5492        8 minutes ago       893MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              5c47cc4725f1        8 minutes ago       893MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              5386324d89fb        8 minutes ago       893MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              631661025e2d        8 minutes ago       893MB
node                                                 10                  f09e7c96b6de        17 hours ago        893MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Remove the stopped container and all of the images, including unused or dangling images, with the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker system prune -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With all of your images and containers deleted, you can now pull the application image from Docker Hub:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull your_dockerhub_username/nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;List your images once again:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will see your application image:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output

REPOSITORY                                     TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo      latest              1c723fb2ef12        11 minutes ago      895MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You can now rebuild your container using the command from Step 3:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;List your running containers:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps

Output

CONTAINER ID        IMAGE                                                   COMMAND             CREATED             STATUS              PORTS                  NAMES
f6bc2f50dff6        your_dockerhub_username/nodejs-image-demo               "npm start"         4 seconds ago       Up 3 seconds        0.0.0.0:80-&amp;gt;8080/tcp   nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Visit &lt;code&gt;http://your_server_ip&lt;/code&gt; or &lt;code&gt;localhost&lt;/code&gt; once again to view your running application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Tutorials
&lt;/h2&gt;

&lt;p&gt;Here are links to more detailed guides related to this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04"&gt;How To Install Docker Compose on Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-provision-and-manage-remote-docker-hosts-with-docker-machine-on-ubuntu-18-04"&gt;How To Provision and Manage Remote Docker Hosts with Docker Machine on Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-share-data-between-docker-containers"&gt;How To Share Data between Docker Containers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-share-data-between-the-docker-container-and-the-host"&gt;How To Share Data Between the Docker Container and the Host&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also look at the longer series on &lt;a href="https://www.digitalocean.com/community/tutorial_series/from-containers-to-kubernetes-with-node-js"&gt;From Containers to Kubernetes with Node.js&lt;/a&gt;, from which this tutorial is adapated.&lt;/p&gt;

&lt;p&gt;Additionally, see our full library of &lt;a href="https://www.digitalocean.com/community/tags/docker?secondary_filter=all&amp;amp;subtype=tutorial"&gt;Docker resources&lt;/a&gt; for more on Docker.&lt;/p&gt;




&lt;p&gt;&lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jgdiKbjy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" alt="CC 4.0 License"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This work is licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>docker</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Closing the Kubernetes Skills Gap with Developer-First Learning</title>
      <dc:creator>katjuell</dc:creator>
      <pubDate>Mon, 25 Nov 2019 15:39:32 +0000</pubDate>
      <link>https://dev.to/digitalocean/closing-the-kubernetes-skills-gap-with-developer-first-learning-5aa7</link>
      <guid>https://dev.to/digitalocean/closing-the-kubernetes-skills-gap-with-developer-first-learning-5aa7</guid>
      <description>&lt;p&gt;How do you begin learning Kubernetes? This is an important question for any organization building, hosting, or managing applications today. For DigitalOcean, which released &lt;a href="https://www.digitalocean.com/products/kubernetes/"&gt;its managed Kubernetes product&lt;/a&gt; in 2018, it's essential.&lt;/p&gt;

&lt;p&gt;The demand for developers with experience building and deploying containerized apps and services continues to grow rapidly. According to &lt;a href="https://insights.dice.com/2019/01/02/kotlin-kubernetes-top-rising-tech-skills/"&gt;Dice&lt;/a&gt;, Kubernetes proficiency was the most listed job requirement in their job posting database in 2018 – by far. However, when DigitalOcean surveyed container usage trends among developers for &lt;a href="https://www.digitalocean.com/currents/june-2018/"&gt;our Currents research report&lt;/a&gt; last year, we found that only 42% of developers working with containers were using Kubernetes.&lt;/p&gt;

&lt;p&gt;DigitalOcean's core philosophy has always been to make the developer experience simple and intuitive – and this applies to how we support developers using Kubernetes. This philosophy underpins our longstanding commitment to education through our &lt;a href="https://www.digitalocean.com/community/"&gt;Community platform&lt;/a&gt; and &lt;a href="https://www.digitalocean.com/community/tutorials"&gt;technical tutorials&lt;/a&gt;. When the internal announcement of our managed Kubernetes service went out, the mission for our Developer Education team was clear: Teach the world Kubernetes! This would support not only DigitalOcean customers, but also the internal teams that worked with these users – as well as anyone who was interested in Kubernetes more broadly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thanks to advances in technologies like containers and Kubernetes, there is a paradigm shift going on in modern software development to move to containers and microservices. As many developers come face-to-face with this shift, it is crucial that they have quality content, thorough instructions, and a supportive community to guide them. Our DigitalOcean community is a great place for anyone looking for help or a collaborative environment with which to share information and experiences.&lt;/p&gt;

&lt;p&gt;– John Kwiatkoski, Senior Developer Support Engineer - Kubernetes at DigitalOcean&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The team set out to write code and tutorials that would walk readers through core concepts and specific tasks related to running applications on Kubernetes. As the body of content grew, so did a pattern: The tutorials followed the steps that any new user would take in learning about and eventually using Kubernetes to run their applications.&lt;/p&gt;

&lt;p&gt;These steps included:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Learning Kubernetes core concepts&lt;/li&gt;
&lt;li&gt; Modernizing applications to work with containers&lt;/li&gt;
&lt;li&gt; Containerizing applications&lt;/li&gt;
&lt;li&gt; Deploying applications to Kubernetes&lt;/li&gt;
&lt;li&gt; Managing cluster operations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The team began to consider how this structure could benefit users if it were presented as a defined curriculum. We continued iterating on it, integrating feedback from users as well as our own experience – and today we are happy to introduce DigitalOcean’s &lt;a href="https://www.digitalocean.com/community/curriculums/kubernetes-for-full-stack-developers"&gt;Kubernetes for Full-Stack Developers&lt;/a&gt;, a self-guided course designed to take you from start to finish in the process of learning Kubernetes.&lt;/p&gt;

&lt;p&gt;This self-guided learning approach is designed to help both newcomers and experienced users learn more about Kubernetes container clusters and running containerized applications on them. With core Kubernetes concepts in hand, running an application on a production cluster can become a familiar, repeatable, and automated process.&lt;/p&gt;

&lt;p&gt;Next up: learning about more advanced Kubernetes topics – like how to manage and monitor a production Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;Ready to get started with Kubernetes? &lt;a href="https://www.digitalocean.com/community/curriculums/kubernetes-for-full-stack-developers"&gt;Sign up now for the course!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We hope you enjoy taking your learning journey with DigitalOcean, and look forward to hearing your feedback.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>containers</category>
      <category>microservices</category>
      <category>learning</category>
    </item>
    <item>
      <title>The DigitalOcean Community Monthly: Go, OctoDNS, Rails on macOS &amp; More</title>
      <dc:creator>katjuell</dc:creator>
      <pubDate>Thu, 01 Aug 2019 19:01:44 +0000</pubDate>
      <link>https://dev.to/digitalocean/the-digitalocean-community-monthly-go-octodns-rails-on-macos-more-5hkn</link>
      <guid>https://dev.to/digitalocean/the-digitalocean-community-monthly-go-octodns-rails-on-macos-more-5hkn</guid>
      <description>&lt;p&gt;Welcome to &lt;strong&gt;The DOCOM Monthly&lt;/strong&gt;, your monthly digest featuring some of the best content published &lt;em&gt;in&lt;/em&gt; and &lt;em&gt;around&lt;/em&gt; the &lt;a href="https://digitalocean.com/community" rel="noopener noreferrer"&gt;DigitalOcean Community&lt;/a&gt; last month. &lt;/p&gt;

&lt;p&gt;I'm Kathleen Juell, a Community Engineer on the Dev Education team. Today's roundup includes Go, OctoDNS, Rails on macOS &amp;amp; more!&lt;/p&gt;

&lt;p&gt;Without further ado, here are this month’s featured posts:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/handling-errors-in-go" rel="noopener noreferrer"&gt;Handling Errors in Go&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fv97nkgg7ievu66dd7s6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fv97nkgg7ievu66dd7s6q.png" alt="Go on DO"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of DigitalOcean’s ongoing collaboration with &lt;a href="https://www.digitalocean.com/community/users/gopherguides" rel="noopener noreferrer"&gt;GopherGuides&lt;/a&gt;, this tutorial guides readers through how to handle errors in &lt;a href="https://golang.org/" rel="noopener noreferrer"&gt;Go&lt;/a&gt;. The tutorial goes over how to examine errors, as well as how to take proper action to protect data and alert users and operators that errors have occurred.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-deploy-and-manage-your-dns-using-octodns-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Deploy and Manage Your DNS using OctoDNS on Ubuntu 18.04&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In this tutorial by &lt;a href="https://www.digitalocean.com/community/users/jamieweb" rel="noopener noreferrer"&gt;Jamie Scaife&lt;/a&gt;, readers will learn how to install and configure &lt;a href="https://github.com/github/octodns/" rel="noopener noreferrer"&gt;OctoDNS&lt;/a&gt;. OctoDNS is a tool that enables users to manage DNS using software development principles: version control, testing, and automated deployment.&lt;/p&gt;

&lt;p&gt;Learn more about publishing a tutorial with DigitalOcean by checking out information on our &lt;a href="https://www.digitalocean.com/write-for-donations/" rel="noopener noreferrer"&gt;Write for DOnations&lt;/a&gt; program!&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby on Rails for macOS
&lt;/h3&gt;

&lt;p&gt;For macOS users, &lt;a href="https://www.digitalocean.com/community/users/tnolan" rel="noopener noreferrer"&gt;Timothy Nolan&lt;/a&gt; has new resources that will help you set up your &lt;a href="https://rubyonrails.org/" rel="noopener noreferrer"&gt;Ruby on Rails&lt;/a&gt; development environment in no time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-macos" rel="noopener noreferrer"&gt;How To Install Ruby on Rails with rbenv on macOS&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-postgresql-with-your-ruby-on-rails-application-on-macos" rel="noopener noreferrer"&gt;How To Use PostgreSQL with Your Ruby on Rails Application on macOS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get started with Rails and configure a PostgreSQL database to work with your application by following these guides. &lt;/p&gt;
&lt;h3&gt;
  
  
  Featured Q&amp;amp;A
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/questions/better-option-upgrade-server-or-add-new-droplet-for-mysql" rel="noopener noreferrer"&gt;Better Option, Upgrade server or add new droplet for Mysql&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/questions/how-to-setup-two-project-in-nginx" rel="noopener noreferrer"&gt;how to setup two project in nginx ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/questions/can-not-ssh-to-my-newly-created-droplet" rel="noopener noreferrer"&gt;Can not ssh to my newly created droplet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get involved yourself on the &lt;a href="https://www.digitalocean.com/community/questions" rel="noopener noreferrer"&gt;Community Q&amp;amp;A&lt;/a&gt; - ask questions and help other members by providing answers!&lt;/p&gt;
&lt;h2&gt;
  
  
  DigitalOcean on the Web
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/jerdog"&gt;Jeremy Meiss&lt;/a&gt; shared how to install and deploy a Solace PubSub+ Event Broker to DigitalOcean with Docker:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/solacedevs" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F636%2F00a14c98-07f3-4270-a819-6221365bd3fa.png" alt="Solace Developers"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F102542%2F0574248e-51b9-4ca0-b2fa-df672e2a1e13.png" alt=""&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/solacedevs/how-to-deploy-a-solace-pubsub-event-broker-to-digitalocean-1afc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to Deploy a Solace PubSub+ Event Broker to DigitalOcean&lt;/h2&gt;
      &lt;h3&gt;Jeremy Meiss for Solace Developers ・ Jul 16 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#digitalocean&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#solace&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#pubsub&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://twitter.com/adi_ghe" rel="noopener noreferrer"&gt;Adrian Gheorghel&lt;/a&gt; went over how to spin up a Jenkins server on DigitalOcean using &lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; and &lt;a href="https://www.ansible.com/" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt; in &lt;a href="https://medium.com/@adrian.gheorghe.dev/how-to-use-terraform-and-ansible-to-raise-a-jenkins-server-on-digitalocean-15246b687666" rel="noopener noreferrer"&gt;How to use Terraform and Ansible to raise a Jenkins Server on DigitalOcean&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/KagundaJM" rel="noopener noreferrer"&gt;Kagunda JM&lt;/a&gt; wrote about how to &lt;a href="https://medium.com/@KagundaJM/deploy-buffalo-app-to-digitalocean-5801d23b8068" rel="noopener noreferrer"&gt;Deploy a Buffalo App to DigitalOcean&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Community IRL
&lt;/h2&gt;

&lt;p&gt;In more Go news, the DO team was on the ground at &lt;a href="https://twitter.com/GopherCon" rel="noopener noreferrer"&gt;GopherCon&lt;/a&gt; in San Diego last week. They talked with developers, handed out Sammy stickers, and spread DO love to attendees.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1154772151968391168-374" src="https://platform.twitter.com/embed/Tweet.html?id=1154772151968391168"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1154772151968391168-374');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1154772151968391168&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: More from DO – Currents &amp;amp; Community Casts
&lt;/h2&gt;

&lt;p&gt;DigitalOcean released its &lt;a href="https://www.digitalocean.com/currents/july-2019/" rel="noopener noreferrer"&gt;Currents Survey: Remote Work Edition&lt;/a&gt;. Check it out for timely information on remote work in tech – how many people are doing it, how they measure engagement with their companies, how they manage burnout, and more.&lt;/p&gt;

&lt;p&gt;And last but not least, check out this Community Casts screencast from our technical writer &lt;a href="https://twitter.com/erikaheidi" rel="noopener noreferrer"&gt;Erika Heidi&lt;/a&gt; on how to do an &lt;a href="https://dev.to/digitalocean/initial-server-setup-with-ubuntu-18-04-1l6d"&gt;Initial Server Setup on Ubuntu 18.04&lt;/a&gt;. By following this screencast, you will learn how to create a new system user with &lt;code&gt;sudo&lt;/code&gt; privileges, how to set up SSH access for this user, and how to enable a firewall with &lt;code&gt;ufw&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/GHB7O12gUcs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Happy hacking, and see you all next month!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>digitalocean</category>
      <category>news</category>
      <category>docom</category>
      <category>docommonthly</category>
    </item>
    <item>
      <title>How To Build a Node.js Application with Docker</title>
      <dc:creator>katjuell</dc:creator>
      <pubDate>Mon, 24 Dec 2018 21:42:03 +0000</pubDate>
      <link>https://dev.to/digitalocean/how-to-build-a-nodejs-application-with-docker-29h9</link>
      <guid>https://dev.to/digitalocean/how-to-build-a-nodejs-application-with-docker-29h9</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; platform allows developers to package and run applications as &lt;em&gt;containers&lt;/em&gt;. A container is an isolated process that runs on a shared operating system, offering a lighter weight alternative to virtual machines. Though containers are not new, they offer benefits — including process isolation and environment standardization — that are growing in importance as more developers use distributed application architectures. &lt;/p&gt;

&lt;p&gt;When building and scaling an application with Docker, the starting point is typically creating an image for your application, which you can then run in a container. The image includes your application code, libraries, configuration files, environment variables, and runtime. Using an image ensures that the environment in your container is standardized and contains only what is necessary to build and run your application.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will create an application image for a static website that uses the &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt; framework and &lt;a href="https://getbootstrap.com/" rel="noopener noreferrer"&gt;Bootstrap&lt;/a&gt;. You will then build a container using that image and push it to &lt;a href="https://hub.docker.com/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt; for future use. Finally, you will pull the stored image from your Docker Hub repository and build another container, demonstrating how you can recreate and scale your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One Ubuntu 18.04 server, set up following this &lt;a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04" rel="noopener noreferrer"&gt;Initial Server Setup guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Docker installed on your server, following Steps 1 and 2 of &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Install and Use Docker on Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Node.js and npm installed, following &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-18-04#installing-using-a-ppa" rel="noopener noreferrer"&gt;these instructions on installing with the PPA managed by NodeSource&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;A Docker Hub account. For an overview of how to set this up, refer to &lt;a href="https://docs.docker.com/docker-hub/" rel="noopener noreferrer"&gt;this introduction&lt;/a&gt; on getting started with Docker Hub.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1 — Installing Your Application Dependencies
&lt;/h2&gt;

&lt;p&gt;To create your image, you will first need to make your application files, which you can then copy to your container. These files will include your application's static content, code, and dependencies.&lt;/p&gt;

&lt;p&gt;First, create a directory for your project in your non-root user's home directory. We will call ours &lt;code&gt;node_project&lt;/code&gt;, but you should feel free to replace this with something else:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir node_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to this directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd node_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will be the root directory of the project. &lt;/p&gt;

&lt;p&gt;Next, create a &lt;a href="https://docs.npmjs.com/files/package.json" rel="noopener noreferrer"&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/a&gt; file with your project's dependencies and other identifying information. Open the file with &lt;code&gt;nano&lt;/code&gt; or your favorite editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following information about the project, including its name, author, license, entrypoint, and dependencies. Be sure to replace the author information with your own name and contact details:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "nodejs-image-demo",
  "version": "1.0.0",
  "description": "nodejs image demo",
  "author": "Sammy the Shark &amp;lt;sammy@example.com&amp;gt;",
  "license": "MIT",
  "main": "app.js",
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file includes the project name, author, and license under which it is being shared. Npm &lt;a href="https://docs.npmjs.com/files/package.json#name" rel="noopener noreferrer"&gt;recommends&lt;/a&gt; making your project name short and descriptive, and avoiding duplicates in the &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm registry&lt;/a&gt;. We've listed the &lt;a href="https://opensource.org/licenses/MIT" rel="noopener noreferrer"&gt;MIT license&lt;/a&gt; in the license field, permitting the free use and distribution of the application code.&lt;/p&gt;

&lt;p&gt;Additionally, the file specifies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"main"&lt;/code&gt;: The entrypoint for the application, &lt;code&gt;app.js&lt;/code&gt;. You will create this file next.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"dependencies"&lt;/code&gt;: The project dependencies — in this case, Express 4.16.4 or above.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though this file does not list a repository, you can add one by following these guidelines on &lt;a href="https://docs.npmjs.com/files/package.json#repository" rel="noopener noreferrer"&gt;adding a repository to your &lt;code&gt;package.json&lt;/code&gt; file&lt;/a&gt;. This is a good addition if you are versioning your application.&lt;/p&gt;

&lt;p&gt;Save and close the file when you've finished making changes. &lt;/p&gt;

&lt;p&gt;To install your project's dependencies, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the packages you've listed in your &lt;code&gt;package.json&lt;/code&gt; file in your project directory. &lt;/p&gt;

&lt;p&gt;We can now move on to building the application files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Creating the Application Files
&lt;/h2&gt;

&lt;p&gt;We will create a website that offers users information about sharks. Our application will have a main entrypoint, &lt;code&gt;app.js&lt;/code&gt;, and a &lt;code&gt;views&lt;/code&gt; directory that will include the project's static assets. The landing page, &lt;code&gt;index.html&lt;/code&gt;, will offer users some preliminary information and a link to a page with more detailed shark information, &lt;code&gt;sharks.html&lt;/code&gt;. In the &lt;code&gt;views&lt;/code&gt; directory, we will create both the landing page and &lt;code&gt;sharks.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, open &lt;code&gt;app.js&lt;/code&gt; in the main project directory to define the project's routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first part of the file will create the Express application and Router objects, and define the base directory, port, and host as variables: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/app.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var express = require("express");
var app = express();
var router = express.Router();

var path = __dirname + '/views/';
const PORT = 8080;
const HOST = '0.0.0.0';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;require&lt;/code&gt; function loads the &lt;code&gt;express&lt;/code&gt; module, which we then use to create the &lt;code&gt;app&lt;/code&gt; and &lt;code&gt;router&lt;/code&gt; objects. The &lt;code&gt;router&lt;/code&gt; object will perform the routing function of the application, and as we define HTTP method routes we will add them to this object to define how our application will handle requests.&lt;/p&gt;

&lt;p&gt;This section of the file also sets a few variables, &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;PORT&lt;/code&gt;, and &lt;code&gt;HOST&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;path&lt;/code&gt;: Defines the base directory, which will be the &lt;code&gt;views&lt;/code&gt; subdirectory within the current project directory. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HOST&lt;/code&gt;: Defines the address that the application will bind to and listen on. Setting this to &lt;code&gt;0.0.0.0&lt;/code&gt; or all IPv4 addresses corresponds with Docker's default behavior of exposing containers to &lt;code&gt;0.0.0.0&lt;/code&gt; unless otherwise instructed. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PORT&lt;/code&gt;: Tells the app to listen on and bind to port &lt;code&gt;8080&lt;/code&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, set the routes for the application using the &lt;code&gt;router&lt;/code&gt; object:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/app.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...

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");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;router.use&lt;/code&gt; function loads a &lt;a href="https://expressjs.com/en/guide/writing-middleware.html" rel="noopener noreferrer"&gt;middleware function&lt;/a&gt; that will log the router's requests and pass them on to the application's routes. These are defined in the subsequent functions, which specify that a GET request to the base project URL should return the &lt;code&gt;index.html&lt;/code&gt; page, while a GET request to the &lt;code&gt;/sharks&lt;/code&gt; route should return &lt;code&gt;sharks.html&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Finally, mount the &lt;code&gt;router&lt;/code&gt; middleware and the application's static assets and tell the app to listen on port &lt;code&gt;8080&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/app.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...

app.use(express.static(path));
app.use("/", router);

app.listen(8080, function () {
  console.log('Example app listening on port 8080!')
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The finished &lt;code&gt;app.js&lt;/code&gt; file will look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/app.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var express = require("express");
var app = express();
var router = express.Router();

var path = __dirname + '/views/';
const PORT = 8080;
const HOST = '0.0.0.0';

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(8080, function () {
  console.log('Example app listening on port 8080!')
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and close the file when you are finished.&lt;/p&gt;

&lt;p&gt;Next, let's add some static content to the application. Start by creating the &lt;code&gt;views&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir views
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the landing page file, &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano views/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following code to the file, which will import Boostrap and create a &lt;a href="https://getbootstrap.com/docs/4.0/components/jumbotron/" rel="noopener noreferrer"&gt;jumbotron&lt;/a&gt; component with a link to the more detailed &lt;code&gt;sharks.html&lt;/code&gt; info page:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/views/index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;

&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;About Sharks&amp;lt;/title&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
    &amp;lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"&amp;gt;
    &amp;lt;link href="css/styles.css" rel="stylesheet"&amp;gt;
    &amp;lt;link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css"&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
    &amp;lt;nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"&amp;gt;
        &amp;lt;div class="container"&amp;gt;
            &amp;lt;button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"&amp;gt; &amp;lt;span class="sr-only"&amp;gt;Toggle navigation&amp;lt;/span&amp;gt;
            &amp;lt;/button&amp;gt; &amp;lt;a class="navbar-brand" href="#"&amp;gt;Everything Sharks&amp;lt;/a&amp;gt;
            &amp;lt;div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"&amp;gt;
                &amp;lt;ul class="nav navbar-nav mr-auto"&amp;gt;
                    &amp;lt;li class="active nav-item"&amp;gt;&amp;lt;a href="/" class="nav-link"&amp;gt;Home&amp;lt;/a&amp;gt;
                    &amp;lt;/li&amp;gt;
                    &amp;lt;li class="nav-item"&amp;gt;&amp;lt;a href="/sharks" class="nav-link"&amp;gt;Sharks&amp;lt;/a&amp;gt;
                    &amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/nav&amp;gt;
    &amp;lt;div class="jumbotron"&amp;gt;
        &amp;lt;div class="container"&amp;gt;
            &amp;lt;h1&amp;gt;Want to Learn About Sharks?&amp;lt;/h1&amp;gt;
            &amp;lt;p&amp;gt;Are you ready to learn about sharks?&amp;lt;/p&amp;gt;
            &amp;lt;br&amp;gt;
            &amp;lt;p&amp;gt;&amp;lt;a class="btn btn-primary btn-lg" href="/sharks" role="button"&amp;gt;Get Shark Info&amp;lt;/a&amp;gt;
            &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="container"&amp;gt;
        &amp;lt;div class="row"&amp;gt;
            &amp;lt;div class="col-lg-6"&amp;gt;
                &amp;lt;h3&amp;gt;Not all sharks are alike&amp;lt;/h3&amp;gt;
                &amp;lt;p&amp;gt;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.
                &amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="col-lg-6"&amp;gt;
                &amp;lt;h3&amp;gt;Sharks are ancient&amp;lt;/h3&amp;gt;
                &amp;lt;p&amp;gt;There is evidence to suggest that sharks lived up to 400 million years ago.
                &amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The top-level &lt;a href="https://getbootstrap.com/docs/4.0/components/navbar/" rel="noopener noreferrer"&gt;navbar&lt;/a&gt; here allows users to toggle between the &lt;strong&gt;Home&lt;/strong&gt; and &lt;strong&gt;Sharks&lt;/strong&gt; pages. In the &lt;code&gt;navbar-nav&lt;/code&gt; subcomponent, we are using Bootstrap's &lt;code&gt;active&lt;/code&gt; class to indicate the current page to the user. We've also specified the routes to our static pages, which match the routes we defined in &lt;code&gt;app.js&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/views/index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
&amp;lt;div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"&amp;gt;
   &amp;lt;ul class="nav navbar-nav mr-auto"&amp;gt;
      &amp;lt;li class="active nav-item"&amp;gt;&amp;lt;a href="/" class="nav-link"&amp;gt;Home&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
      &amp;lt;li class="nav-item"&amp;gt;&amp;lt;a href="/sharks" class="nav-link"&amp;gt;Sharks&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
   &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, we've created a link to our shark information page in our jumbotron's button:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/views/index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
&amp;lt;div class="jumbotron"&amp;gt;
   &amp;lt;div class="container"&amp;gt;
      &amp;lt;h1&amp;gt;Want to Learn About Sharks?&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Are you ready to learn about sharks?&amp;lt;/p&amp;gt;
      &amp;lt;br&amp;gt;
      &amp;lt;p&amp;gt;&amp;lt;a class="btn btn-primary btn-lg" href="/sharks" role="button"&amp;gt;Get Shark Info&amp;lt;/a&amp;gt;
      &amp;lt;/p&amp;gt;
   &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also a link to a custom style sheet in the header:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/views/index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
&amp;lt;link href="css/styles.css" rel="stylesheet"&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create this style sheet at the end of this step.&lt;/p&gt;

&lt;p&gt;Save and close the file when you are finished.&lt;/p&gt;

&lt;p&gt;With the application landing page in place, we can create our shark information page, &lt;code&gt;sharks.html&lt;/code&gt;, which will offer interested users more information about sharks.&lt;/p&gt;

&lt;p&gt;Open the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano views/sharks.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following code, which imports Bootstrap and the custom style sheet and offers users detailed information about certain sharks:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/views/sharks.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;

&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;About Sharks&amp;lt;/title&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
    &amp;lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"&amp;gt;
    &amp;lt;link href="css/styles.css" rel="stylesheet"&amp;gt;
    &amp;lt;link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css"&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"&amp;gt;
    &amp;lt;div class="container"&amp;gt;
        &amp;lt;button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"&amp;gt; &amp;lt;span class="sr-only"&amp;gt;Toggle navigation&amp;lt;/span&amp;gt;
        &amp;lt;/button&amp;gt; &amp;lt;a class="navbar-brand" href="/"&amp;gt;Everything Sharks&amp;lt;/a&amp;gt;
        &amp;lt;div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"&amp;gt;
            &amp;lt;ul class="nav navbar-nav mr-auto"&amp;gt;
                &amp;lt;li class="nav-item"&amp;gt;&amp;lt;a href="/" class="nav-link"&amp;gt;Home&amp;lt;/a&amp;gt;
                &amp;lt;/li&amp;gt;
                &amp;lt;li class="active nav-item"&amp;gt;&amp;lt;a href="/sharks" class="nav-link"&amp;gt;Sharks&amp;lt;/a&amp;gt;
                &amp;lt;/li&amp;gt;
            &amp;lt;/ul&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/nav&amp;gt;
&amp;lt;div class="jumbotron text-center"&amp;gt;
    &amp;lt;h1&amp;gt;Shark Info&amp;lt;/h1&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class="container"&amp;gt;
    &amp;lt;div class="row"&amp;gt;
        &amp;lt;div class="col-lg-6"&amp;gt;
            &amp;lt;p&amp;gt;
                &amp;lt;div class="caption"&amp;gt;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.
                &amp;lt;/div&amp;gt;
                &amp;lt;img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark"&amp;gt;
            &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="col-lg-6"&amp;gt;
            &amp;lt;p&amp;gt;
                &amp;lt;div class="caption"&amp;gt;Other sharks are known to be friendly and welcoming!&amp;lt;/div&amp;gt;
                &amp;lt;img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark"&amp;gt;
            &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in this file, we again use the &lt;code&gt;active&lt;/code&gt; class to indicate the current page.&lt;/p&gt;

&lt;p&gt;Save and close the file when you are finished.&lt;/p&gt;

&lt;p&gt;Finally, create the custom CSS style sheet that you've linked to in &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;sharks.html&lt;/code&gt; by first creating a &lt;code&gt;css&lt;/code&gt; folder in the &lt;code&gt;views&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir views/css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the style sheet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano views/css/styles.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following code, which will set the desired color and font for our pages:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/views/css/styles.css&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.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;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to setting font and color, this file also limits the size of the images by specifying a &lt;code&gt;max-width&lt;/code&gt; of 80%. This will prevent them from taking up more room than we would like on the page.&lt;/p&gt;

&lt;p&gt;Save and close the file when you are finished.&lt;/p&gt;

&lt;p&gt;With the application files in place and the project dependencies installed, you are ready to start the application. &lt;/p&gt;

&lt;p&gt;If you followed the initial server setup tutorial in the prerequisites, you will have an active firewall permitting only SSH traffic. To permit traffic to port &lt;code&gt;8080&lt;/code&gt; run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw allow 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start the application, make sure that you are in your project's root directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/node_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the application with &lt;code&gt;node app.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate your browser to &lt;code&gt;http://your_server_ip:8080&lt;/code&gt;. You will see the following landing page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmppap3558777roxlb65i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmppap3558777roxlb65i.png" alt="Application Landing Page" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;Get Shark Info&lt;/strong&gt; button. You will see the following information page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v4oipio14dkmvwcay8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v4oipio14dkmvwcay8o.png" alt="Shark Info Page" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You now have an application up and running. When you are ready, quit the server by typing &lt;code&gt;CTRL+C&lt;/code&gt;. We can now move on to creating the Dockerfile that will allow us to recreate and scale this application as desired.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Writing the Dockerfile
&lt;/h2&gt;

&lt;p&gt;Your Dockerfile specifies what will be included in your application container when it is executed. Using a Dockerfile allows you to define your container environment and avoid discrepancies with dependencies or runtime versions. &lt;/p&gt;

&lt;p&gt;Following &lt;a href="https://www.digitalocean.com/community/tutorials/building-optimized-containers-for-kubernetes" rel="noopener noreferrer"&gt;these guidelines on building optimized containers&lt;/a&gt;, we will make our image as efficient as possible by minimizing the number of image layers and restricting the image's function to a single purpose — recreating our application files and static content.&lt;/p&gt;

&lt;p&gt;In your project's root directory, create the Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker images are created using a succession of layered images that build on one another. Our first step will be to add the &lt;em&gt;base image&lt;/em&gt; for our application that will form the starting point of the application build.&lt;/p&gt;

&lt;p&gt;Let's use the &lt;a href="https://hub.docker.com/_/node/" rel="noopener noreferrer"&gt;&lt;code&gt;node:10-alpine&lt;/code&gt; image&lt;/a&gt;, since, at the time of writing, this is the &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;recommended LTS version of Node.js&lt;/a&gt;. The &lt;code&gt;alpine&lt;/code&gt; image is derived from the &lt;a href="https://alpinelinux.org/" rel="noopener noreferrer"&gt;Alpine Linux&lt;/a&gt; project, and will help us keep our image size down. For more information about whether or not the &lt;code&gt;alpine&lt;/code&gt; image is the right choice for your project, please see the full discussion under the &lt;strong&gt;Image Variants&lt;/strong&gt; section of the &lt;a href="https://hub.docker.com/_/node/" rel="noopener noreferrer"&gt;Docker Hub Node image page&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Add the following &lt;code&gt;FROM&lt;/code&gt; instruction to set the application's base image:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:10-alpine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This image includes Node.js and npm. Each Dockerfile must begin with a &lt;code&gt;FROM&lt;/code&gt; instruction.&lt;/p&gt;

&lt;p&gt;By default, the Docker Node image includes a non-root &lt;strong&gt;node&lt;/strong&gt; user that you can use to avoid running your application container as &lt;strong&gt;root&lt;/strong&gt;. It is a recommended security practice to avoid running containers as &lt;strong&gt;root&lt;/strong&gt; and to &lt;a href="https://docs.docker.com/engine/security/security/#linux-kernel-capabilities" rel="noopener noreferrer"&gt;restrict capabilities within the container&lt;/a&gt; to only those required to run its processes. We will therefore use the &lt;strong&gt;node&lt;/strong&gt; user's home directory as the working directory for our application and set them as our user inside the container. For more information about best practices when working with the Docker Node image, see this &lt;a href="https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md" rel="noopener noreferrer"&gt;best practices guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To fine-tune the permissions on our application code in the container, let's create the &lt;code&gt;node_modules&lt;/code&gt; subdirectory in &lt;code&gt;/home/node&lt;/code&gt; along with the &lt;code&gt;app&lt;/code&gt; directory. Creating these directories will ensure that they have the permissions we want, which will be important when we create local node modules in the container with &lt;code&gt;npm install&lt;/code&gt;. In addition to creating these directories, we will set ownership on them to our &lt;strong&gt;node&lt;/strong&gt; user:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
RUN mkdir -p /home/node/app/node_modules &amp;amp;&amp;amp; chown -R node:node /home/node/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information on the utility of consolidating &lt;code&gt;RUN&lt;/code&gt; instructions, see this &lt;a href="https://www.digitalocean.com/community/tutorials/building-optimized-containers-for-kubernetes#managing-container-layers" rel="noopener noreferrer"&gt;discussion of how to manage container layers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, set the working directory of the application to &lt;code&gt;/home/node/app&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
WORKDIR /home/node/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a &lt;code&gt;WORKDIR&lt;/code&gt; isn't set, Docker will create one by default, so it's a good idea to set it explicitly.&lt;/p&gt;

&lt;p&gt;Next, copy the &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; (for npm 5+) files:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
COPY package*.json ./
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding this &lt;code&gt;COPY&lt;/code&gt; instruction before running &lt;code&gt;npm install&lt;/code&gt; or copying the application code allows us to take advantage of Docker's caching mechanism. At each stage in the build, Docker will check to see if it has a layer cached for that particular instruction. If we change &lt;code&gt;package.json&lt;/code&gt;, this layer will be rebuilt, but if we don't, this instruction will allow Docker to use the existing image layer and skip reinstalling our node modules. &lt;/p&gt;

&lt;p&gt;After copying the project dependencies, we can run &lt;code&gt;npm install&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
RUN npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy your application code to the working application directory on the container:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
COPY . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure that the application files are owned by the non-root &lt;strong&gt;node&lt;/strong&gt; user, copy the permissions from your application directory to the directory on the container:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
COPY --chown=node:node . .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the user to &lt;strong&gt;node&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
USER node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expose port &lt;code&gt;8080&lt;/code&gt; on the container and start the application:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
EXPOSE 8080

CMD [ "node", "app.js" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;EXPOSE&lt;/code&gt; does not publish the port, but instead functions as a way of documenting which ports on the container will be published at runtime. &lt;code&gt;CMD&lt;/code&gt; runs the command to start the application — in this case, &lt;a href="https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#cmd" rel="noopener noreferrer"&gt;&lt;code&gt;node app.js&lt;/code&gt;&lt;/a&gt;. Note that there should only be one &lt;code&gt;CMD&lt;/code&gt; instruction in each Dockerfile. If you include more than one, only the last will take effect.&lt;/p&gt;

&lt;p&gt;There are many things you can do with the Dockerfile. For a complete list of instructions, please refer to Docker's &lt;a href="https://docs.docker.com/engine/reference/builder/" rel="noopener noreferrer"&gt;Dockerfile reference documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The complete Dockerfile looks like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
FROM node:10-alpine

RUN mkdir -p /home/node/app/node_modules &amp;amp;&amp;amp; chown -R node:node /home/node/app

WORKDIR /home/node/app

COPY package*.json ./

RUN npm install

COPY . .

COPY --chown=node:node . .

USER node

EXPOSE 8080

CMD [ "node", "app.js" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and close the file when you are finished editing.&lt;/p&gt;

&lt;p&gt;Before building the application image, let's add a &lt;a href="https://docs.docker.com/engine/reference/builder/#dockerignore-file" rel="noopener noreferrer"&gt;&lt;code&gt;.dockerignore&lt;/code&gt; file&lt;/a&gt;. Working in a similar way to a &lt;a href="https://git-scm.com/docs/gitignore" rel="noopener noreferrer"&gt;&lt;code&gt;.gitignore&lt;/code&gt; file&lt;/a&gt;, &lt;code&gt;.dockerignore&lt;/code&gt; specifies which files and directories in your project directory should not be copied over to your container.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;.dockerignore&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano .dockerignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the file, add your local node modules, npm logs, Dockerfile, and &lt;code&gt;.dockerignore&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/node_project/.dockerignore&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
npm-debug.log
Dockerfile
.dockerignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are working with &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt; then you will also want to add your &lt;code&gt;.git&lt;/code&gt; directory and &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Save and close the file when you are finished.&lt;/p&gt;

&lt;p&gt;You are now ready to build the application image using the &lt;a href="https://docs.docker.com/engine/reference/commandline/build/" rel="noopener noreferrer"&gt;&lt;code&gt;docker build&lt;/code&gt;&lt;/a&gt; command. Using the &lt;code&gt;-t&lt;/code&gt; flag with &lt;code&gt;docker build&lt;/code&gt; will allow you to tag the image with a memorable name. Because we are going to push the image to Docker Hub, let's include our Docker Hub username in the tag. We will tag the image as &lt;code&gt;nodejs-image-demo&lt;/code&gt;, but feel free to replace this with a name of your own choosing. Remember to also replace &lt;code&gt;your_dockerhub_username&lt;/code&gt; with your own Docker Hub username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t your_dockerhub_username/nodejs-image-demo .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.&lt;/code&gt; specifies that the build context is the current directory.&lt;/p&gt;

&lt;p&gt;It will take a minute or two to build the image. Once it is complete, check your images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is now possible to create a container with this image using &lt;a href="https://docs.docker.com/engine/reference/commandline/run/" rel="noopener noreferrer"&gt;&lt;code&gt;docker run&lt;/code&gt;&lt;/a&gt;. We will include three flags with this command: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt;: This publishes the port on the container and maps it to a port on our host. We will use port &lt;code&gt;80&lt;/code&gt; on the host, but you should feel free to modify this as necessary if you have another process running on that port. For more information about how this works, see this discussion in the Docker docs on &lt;a href="https://docs.docker.com/v17.09/engine/userguide/networking/default_network/binding/" rel="noopener noreferrer"&gt;port binding&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt;: This runs the container in the background.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--name&lt;/code&gt;: This allows us to give the container a memorable name. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the following command to build the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your container is up and running, you can inspect a list of your running containers with &lt;a href="https://docs.docker.com/engine/reference/commandline/ps/" rel="noopener noreferrer"&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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-&amp;gt;8080/tcp   nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With your container running, you can now visit your application by navigating your browser to &lt;code&gt;http://your_server_ip&lt;/code&gt;. You will see your application landing page once again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmppap3558777roxlb65i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmppap3558777roxlb65i.png" alt="Application Landing Page" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have created an image for your application, you can push it to Docker Hub for future use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Using a Repository to Work with Images
&lt;/h2&gt;

&lt;p&gt;By pushing your application image to a registry like Docker Hub, you make it available for subsequent use as you build and scale your containers. We will demonstrate how this works by pushing the application image to a repository and then using the image to recreate our container.&lt;/p&gt;

&lt;p&gt;The first step to pushing the image is to log in to the Docker Hub account you created in the prerequisites:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker login -u your_dockerhub_username -p your_dockerhub_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logging in this way will create a &lt;code&gt;~/.docker/config.json&lt;/code&gt; file in your user's home directory with your Docker Hub credentials.&lt;/p&gt;

&lt;p&gt;You can now push the application image to Docker Hub using the tag you created earlier, &lt;code&gt;your_dockerhub_username/nodejs-image-demo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push your_dockerhub_username/nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test the utility of the image registry by destroying our current application container and image and rebuilding them with the image in our repository.&lt;/p&gt;

&lt;p&gt;First, list your running containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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-&amp;gt;8080/tcp   nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;CONTAINER ID&lt;/code&gt; listed in your output, stop the running application container. Be sure to replace the highlighted ID below with your own &lt;code&gt;CONTAINER ID&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker stop e50ad27074a7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List your all of your images with the &lt;code&gt;-a&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker images -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the following output with the name of your image, &lt;code&gt;your_dockerhub_username/nodejs-image-demo&lt;/code&gt;, along with the &lt;code&gt;node&lt;/code&gt; image and the other images from your build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output

REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo            latest              1c723fb2ef12        7 minutes ago       73MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              2e3267d9ac02        4 minutes ago       72.9MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              8352b41730b9        4 minutes ago       73MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              5d58b92823cb        4 minutes ago       73MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              3f1e35d7062a        4 minutes ago       73MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              02176311e4d0        4 minutes ago       73MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              8e84b33edcda        4 minutes ago       70.7MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              6a5ed70f86f2        4 minutes ago       70.7MB
&amp;lt;none&amp;gt;                                               &amp;lt;none&amp;gt;              776b2637d3c1        4 minutes ago       70.7MB
node                                                 10-alpine           f09e7c96b6de        3 weeks ago         70.7MB

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove the stopped container and all of the images, including unused or dangling images, with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker system prune -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;code&gt;y&lt;/code&gt; when prompted in the output to confirm that you would like to remove the stopped container and images. Be advised that this will also remove your build cache.&lt;/p&gt;

&lt;p&gt;You have now removed both the container running your application image and the image itself. For more information on removing Docker containers, images, and volumes, please see &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes" rel="noopener noreferrer"&gt;How To Remove Docker Images, Containers, and Volumes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With all of your images and containers deleted, you can now pull the application image from Docker Hub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull your_dockerhub_username/nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List your images once again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see your application image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output

REPOSITORY                                     TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/nodejs-image-demo      latest              1c723fb2ef12        11 minutes ago      73MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now rebuild your container using the command from Step 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List your running containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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-&amp;gt;8080/tcp   nodejs-image-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit &lt;code&gt;http://your_server_ip&lt;/code&gt; once again to view your running application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial you created a static web application with Express and Bootstrap, as well as a Docker image for this application. You used this image to create a container and pushed the image to Docker Hub. From there, you were able to destroy your image and container and recreate them using your Docker Hub repository.&lt;/p&gt;

&lt;p&gt;If you are interested in learning more about how to work with tools like Docker Compose and Docker Machine to create multi-container setups, you can look at the following guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Install Docker Compose on Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-provision-and-manage-remote-docker-hosts-with-docker-machine-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Provision and Manage Remote Docker Hosts with Docker Machine on Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For general tips on working with container data, see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-share-data-between-docker-containers" rel="noopener noreferrer"&gt;How To Share Data between Docker Containers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-share-data-between-the-docker-container-and-the-host" rel="noopener noreferrer"&gt;How To Share Data Between the Docker Container and the Host&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are interested in other Docker-related topics, please see our complete library of &lt;a href="https://www.digitalocean.com/community/tags/docker/tutorials" rel="noopener noreferrer"&gt;Docker tutorials&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9dopc8jjbnew6l2xc2j.png" alt="CC 4.0 License" width="88" height="31"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This work is licensed under a &lt;a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener noreferrer"&gt;Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>node</category>
    </item>
  </channel>
</rss>
