Введение

Платформа Docker позволяет разработчикам упаковывать и запускать приложения как контейнеры. Контейнер — это изолированный процесс, выполняемый в общей операционной системе, и представляющий из себя облегченную альтернативу виртуальным машинам. Хотя концепция контейнеров существует уже давно, обеспечиваемые ими преимущества изоляции процессов и стандартизации среды становятся все более важными по мере того, как все больше разработчиков начинают использовать распределенные архитектуры приложений.

При создании и масштабировании приложений Docker вначале обычно создается образ приложения, который можно запустить в контейнере. Образ включает код приложения, библиотеки, файлы конфигурации, переменные среды и исполняемый модуль. Благодаря использованию образа среда в контейнере стандартизирована и содержит только то, что необходимо для сборки и выполнения приложения.

В этом обучающем модуле вы создадите образ приложения для статического сайта, использующего систему Express и Bootstrap. Затем вы построите контейнер с этим образом и разместите его в Docker Hub для будущего использования. Наконец, вы извлечете сохраненный образ из хранилища Docker Hub и построите другой контейнер, продемонстрировав возможность воссоздания и масштабирования вашего приложения.

Предварительные требования

Для данного обучающего модуля вам потребуется следующее:

Шаг 1 — Установка зависимостей вашего приложения

Чтобы создать образ, нужно сначала выполнить сборку файлов приложения, а затем скопировать их в контейнер. Эти файлы будут включать статический контент, код и зависимости вашего приложения.

Создайте для вашего проекта каталог в начальном каталоге пользователя, не являющегося пользователем root. Мы назовем наш проект node_project, но вы можете заменить это название на другое:

  • mkdir node_project

Перейдите в этот каталог:

  • cd node_project

Это будет корневой каталог проекта.

Далее создайте файл package.json с зависимостями пакета и другой идентификационной информацией. Откройте файл с помощью nano или своего любимого редактора:

  • nano package.json

Добавьте следующую информацию по проекту, включая его название, автора, лицензию, входную точку и зависимости. Обязательно замените данные автора собственным именем и контактными данными:

~/node_project/package.json
{
  "name": "nodejs-image-demo",
  "version": "1.0.0",
  "description": "nodejs image demo",
  "author": "Sammy the Shark <sammy@example.com>",
  "license": "MIT",
  "main": "app.js",
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}

Файл содержит название проекта, автора и лицензию, по которой он распространяется. Npm рекомендует использовать краткие и содержательные названия проектов и избегать использования дубликатов в реестре npm. Мы указали лицензию MIT в поле license, что дает нам право на свободное использование и распространение кода приложения.

Кроме того в файле указано следующее:

  • "main": точка входа приложения, app.js. Затем вы создадите этот файл.
  • "dependencies": зависимости проекта — в данном случае, Express 4.16.4 или более поздняя версия.

Хотя этот файл не указан в хранилище, вы можете добавить его в соответствии со следующими указаниями по добавлению хранилища в файл package.json. Это хорошее дополнение, если вы задаете версии своего приложения.

Сохраните и закройте файл, когда закончите вносить изменения.

Чтобы установить зависимости проекта, выполните следующую команду:

  • npm install

Пакеты, перечисленные вами в файле package.json, будут установлены в каталог вашего проекта.

Теперь можно перейти к сборке файлов приложения.

Шаг 2 — Создание файлов приложения

Мы создадим сайт, который предоставляет пользователям данные об акулах. В нашем приложении будет основная точка входа, app.js, и каталог views, где будут находиться статичные активы проекта. Начальная страница index.html будет предоставлять пользователям предварительную информацию и ссылку на страницу с более подробной информацией об акулах, sharks.html. В каталоге views мы создадим начальную страницу и файл sharks.html.

Вначале откройте файл app.js в главном каталоге проекта, чтобы определить маршруты проекта:

  • nano app.js

Первая часть файла будет создавать приложение Express и объекты Router, а также определять базовый каталог и порт как постоянные величины:

~/node_project/app.js
const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

Функция require загружает модуль express, который мы используем для создания объектов app и router. Объект router будет выполнять функцию маршрутизации в приложении. Определяя маршруты методов HTTP, мы будем добавлять их в этот объект, чтобы определить, как наше приложение будет обрабатывать запросы.

В этом разделе файла также содержатся две константы, path и port:

  • path: определяет базовый каталог, в данном случае подкаталог views в каталоге текущего проекта.
  • port: указывает приложению прослушивать и выполнить привязку к порту 8080.

Затем настройте маршруты для приложения с помощью объекта router:

~/node_project/app.js
...

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');
});

Функция router.use загружает промежуточную функцию, которая будет регистрировать запросы маршрутизатора и передавать их на маршруты приложения. Они определяются в последующих функциях, который указывают, что запрос GET базового URL проекта должен возвращать страницу index.html, а запрос GET для маршрута /sharks должен возвращать страницу sharks.html.

Наконец, смонтируйте промежуточный уровень router и статичные ресурсы приложения и укажите приложению прослушивать порт 8080:

~/node_project/app.js
...

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

app.listen(port, function () {
  console.log('Example app listening on port 8080!')
})

Готовый файл app.js будет выглядеть примерно так:

~/node_project/app.js
const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

router.use(function (req,res,next) {
  console.log('/' + req.method);
  next();
});

router.get('/', function(req,res){
  res.sendFile(path + 'index.html');
});

router.get('/sharks', function(req,res){
  res.sendFile(path + 'sharks.html');
});

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

app.listen(port, function () {
  console.log('Example app listening on port 8080!')
})

Сохраните файл и закройте его после завершения.

Далее добавим в приложение статичный контент. Вначале создадим каталог views:

  • mkdir views

Откройте файл начальной страницы, index.html:

  • nano views/index.html

Добавьте в файл следующий код, который импортирует Boostrap и создаст компонент jumbotron со ссылкой на страницу подробной информации о sharks.html:

~/node_project/views/index.html
<!DOCTYPE html>
<html lang="en">

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

<body>
    <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
        <div class="container">
            <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
            </button> <a class="navbar-brand" href="#">Everything Sharks</a>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav mr-auto">
                    <li class="active nav-item"><a href="/" class="nav-link">Home</a>
                    </li>
                    <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="jumbotron">
        <div class="container">
            <h1>Want to Learn About Sharks?</h1>
            <p>Are you ready to learn about sharks?</p>
            <br>
            <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
            </p>
        </div>
    </div>
    <div class="container">
        <div class="row">
            <div class="col-lg-6">
                <h3>Not all sharks are alike</h3>
                <p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.
                </p>
            </div>
            <div class="col-lg-6">
                <h3>Sharks are ancient</h3>
                <p>There is evidence to suggest that sharks lived up to 400 million years ago.
                </p>
            </div>
        </div>
    </div>
</body>

</html>

Навигационная панель верхнего уровня позволяет пользователям переключаться между страницами Home и Sharks. В субкомпоненте navbar-nav мы используем active класс Bootstrap, чтобы указать пользователю текущую страницу. Также мы указали маршруты наших статичных страниц, что соответствует маршрутам, определенным в файле app.js:

~/node_project/views/index.html
...
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
   <ul class="nav navbar-nav mr-auto">
      <li class="active nav-item"><a href="/" class="nav-link">Home</a>
      </li>
      <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
      </li>
   </ul>
</div>
...

Кроме того, мы создали ссылку на страницу с информацией об акулах в нашей кнопке jumbotron:

~/node_project/views/index.html
...
<div class="jumbotron">
   <div class="container">
      <h1>Want to Learn About Sharks?</h1>
      <p>Are you ready to learn about sharks?</p>
      <br>
      <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
      </p>
   </div>
</div>
...

Также в заголовке имеется ссылка на пользовательскую таблицу стилей:

~/node_project/views/index.html
...
<link href="css/styles.css" rel="stylesheet">
...

Мы создадим эту таблицу стилей в конце данного шага.

Сохраните файл и закройте его после завершения.

Подготовив начальную страницу приложения, мы можем создать страницу с информацией об акулах, sharks.html, где заинтересованные пользователи смогут получить больше информации об акулах.

Откройте файл:

  • nano views/sharks.html

Добавьте следующий код, который импортирует Bootstrap и пользовательскую таблицу стилей и предлагает пользователям подробную информацию об определенных акулах:

~/node_project/views/sharks.html
<!DOCTYPE html>
<html lang="en">

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

</html>

В этом файле мы снова используем active класс для индикации текущей страницы.

Сохраните файл и закройте его после завершения.

Наконец, создайте пользовательскую таблицу стилей CSS, на которую вы разместили ссылки в файлах index.html и sharks.html. Для этого вначале создайте папку css в каталоге views:

  • mkdir views/css

Откройте таблицу стилей:

  • nano views/css/styles.css

Добавьте следующий код, который задаст желаемые цвет и шрифт для наших страниц:

~/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;
}

В дополнение к настройке шрифта и цвета этот файл также ограничивает размер изображений, указывая max-width 80%. Благодаря этому они не будут занимать больше места на странице, чем нам бы хотелось.

Сохраните файл и закройте его после завершения.

Теперь, когда файлы приложения готовы, а зависимости проекта установлены, вы готовы к запуску приложения.

Если вы следовали указаниям руководства по первоначальной настройке сервера, указанного в предварительных условиях, у вас установлен активный брандмауэр, на котором разрешен только трафик SSH. Чтобы разрешить трафик на порт 8080, выполните команду:

  • sudo ufw allow 8080

Чтобы запустить приложение, перейдите в каталог root вашего проекта:

  • cd ~/node_project

Запустите приложение с node app.js:

  • node app.js

Откройте в браузере адрес http://your_server_ip:8080. Вы увидите следующую начальную страницу:

Начальная страница приложения

Нажмите кнопку Get Shark Info (Получить информацию об акулах). Вы увидите следующую информационную страницу:

Страница информации об акулах

Ваше приложение запущено и работает. Когда вы будете готовы, покиньте сервер, нажав CTRL+C. Теперь мы можем перейти к созданию файла Dockerfile, который позволит нам воссоздать и масштабировать это приложение, когда это потребуется.

Шаг 3 — Создание файла Dockerfile

Ваш файл Dockerfile указывает, что будет включено в контейнер приложения при его выполнении. Использование Dockerfile позволяет определить среду контейнера и избежать расхождений с зависимостями и версиями модуля исполнения.

В соответствии с этими указаниями по построению оптимизированных контейнеров, мы сделаем наше изображение максимально эффективным, минимизируем количество слоев образа и воссоздадим файлы нашего приложения и статичный контент.

Создайте файл Dockerfile в каталоге root вашего проекта:

  • nano Dockerfile

Образы Docker создаются с использованием последовательности многослойных образов, накладывающихся друг поверх друга. Вначале мы добавим базовый образ нашего приложения, который станет начальной точкой сборки приложения.

Мы будем использовать образ node:10-alpine, поскольку на момент написания это рекомендуемая версия LTS Node.js. Образ alpine является производным проекта Alpine Linux, и это помогает уменьшить размер образа. Дополнительную информацию о том, стоит ли использовать образ alpine в вашем проекте, можно получить в полном обсуждении в разделе *Image Variants *(Варианты образов) на странице образов Docker Hub Node.

Добавьте следующую команду FROM, чтобы задать базовый образ приложения:

~/node_project/Dockerfile
FROM node:10-alpine

Этот образ включает Node.js и npm. Каждый Dockerfile должен начинаться с команды FROM.

По умолчанию образ Docker Node включает пользователя node, не являющегося пользователем root, которого вы можете использовать, чтобы контейнер вашего приложения не запускался как root. Для безопасности рекомендуется не запускать контейнеры как пользователь root и ограничить возможности контейнера теми, которые необходимы для запуска его процессов. Мы используем домашний каталог пользователя node как рабочий каталог нашего приложения и зададим его как пользователя внутри контейнера. Дополнительную информацию об оптимальной практике работы с образом Docker Node можно найти в этом руководстве по передовым практикам.

Для тонкой настройки разрешений кода приложения в контейнере создадим подкаталог node_modules в каталоге /home/node вместе с каталогом app. Создание этих каталогов обеспечит наличие желаемых разрешений, что будет важно при создании локальных модулей узла в контейнере с помощью команды npm install. В дополнение к созданию этих каталогов мы зададим пользователя node как их владельца:

~/node_project/Dockerfile
...
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

Дополнительную информацию о полезности консолидации команд RUN можно найти в этой дискуссии об управлении слоями контейнеров.

Далее установите рабочий каталог приложения /home/node/app:

~/node_project/Dockerfile
...
WORKDIR /home/node/app

Если WORKDIR не задан, Docker создаст рабочий каталог по умолчанию, и поэтому лучше явно задать его.

Далее скопируйте файлы package.json и package-lock.json (для npm 5+):

~/node_project/Dockerfile
...
COPY package*.json ./

Добавление этой команды COPY перед запуском npm install или копированием кода приложения позволяет использовать механизм кэширования Docker. На каждом этапе сборки Docker проверяет наличие кэшированного слоя для этой конкретной команды. Если мы изменим файл package.json, этот слой будет построен заново, но если мы не будем его менять, данная команда позволит Docker использовать существующий слой образа и пропустить повторную установку модулей узла.

Чтобы все файлы приложения принадлежали пользователю node, не являющемуся пользователем root, включая содержимое каталога node_modules, переключитесь на пользователя *node *перед запуском npm install:

~/node_project/Dockerfile
...
USER node

После копирования зависимостей проекта и переключения пользователя можно запустить npm install:

~/node_project/Dockerfile
...
RUN npm install

Затем скопируйте код приложения с надлежащими разрешениями в каталог приложения в контейнере:

~/node_project/Dockerfile
...
COPY --chown=node:node . .

В этом случае файлы приложения будут принадлежать пользователю node, не являющемуся пользователем root.

Наконец, откройте порт 8080 в контейнере и запустите приложение:

~/node_project/Dockerfile
...
EXPOSE 8080

CMD [ "node", "app.js" ]

Команда EXPOSE не публикует порт, но служит для документирования портов контейнера, которые будут публиковаться во время исполнения. CMD выполняет команду пуска приложения, в данном случае node app.js. Обратите винмание, что в каждом файле Dockerfile должна быть только одна команда CMD. Если вы включите несколько команд, действовать будет только последняя.

С помощью Dockerfile можно сделать много разных вещей. Полный список команд можно найти в справочной документации по Dockerfile.

Полный файл Dockerfile выглядит следующим образом:

~/node_project/Dockerfile

FROM node:10-alpine

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

WORKDIR /home/node/app

COPY package*.json ./

USER node

RUN npm install

COPY --chown=node:node . .

EXPOSE 8080

CMD [ "node", "app.js" ]

Сохраните и закройте файл после завершения редактирования.

Прежде чем строить образ приложения, добавим файл .dockerignore. Работая аналогично файлу .gitignore, файл .dockerignore указывает, какие файлы и каталоги в каталоге проекта не следует копировать в контейнер.

Откройте файл .dockerignore:

  • nano .dockerignore

Внутри файла добавьте модули локального узла, журналы npm, файл Dockerfile и файл .dockerignore:

~/node_project/.dockerignore
node_modules
npm-debug.log
Dockerfile
.dockerignore

Если вы работаете с Git, также следует добавить каталог .git и файл .gitignore.

Сохраните файл и закройте его после завершения.

Теперь вы готовы к созданию образа прложения с помощью команды docker build. Использование флага -t с командой docker build позволяет присвоить образу метку с запоминающимся названием. Поскольку мы планируем размещать образ в Docker Hub, добавим в метку имя пользователя Docker Hub. Мы пометим образ меткой nodejs-image-demo, но вы можете использовать любое другое название на свое усмотрение. Также замените your_dockerhub_username своим именем пользователя Docker Hub:

  • docker build -t your_dockerhub_username/nodejs-image-demo .

Символ . указывает, что контекст команды build — текущий каталог.

Создание образа займет одну или две минуты. После завершения проверьте образы:

  • docker images

Результат будет выглядеть следующим образом:

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

Теперь вы можете создать контейнер с этим образом, используя команду docker run. Мы добавим к этой команде три флага:

  • -p: публикует порт контейнера и сопоставляет его с портом хоста. Мы используем порт 80 на нашем хосте, но вы можете использовать любой другой порт, если этот порт занят каким-то другим процессом. Дополнительную информацию по принципам привязки портов можно найти в соответствующей документации Docker.
  • -d: запускает контейнер в фоновом режиме.
  • --name: позволяет присвоить контейнеру запоминающееся имя.

Запустите следующую команду для построения контейнера:

  • docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

После запуска контейнера вы можете проверить список запущенных контейнеров с помощью команды docker ps:

  • docker ps

Результат будет выглядеть следующим образом:

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "node app.js" 8 seconds ago Up 7 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

Во время работы контейнера вы можете открыть свое приложение, указав в браузере адрес http://your_server_ip. После этого откроется начальная страница вашего приложения:

Начальная страница приложения

Вы создали образ приложения, и теперь можете опубликовать его в Docker Hub для будущего использования.

Шаг 4 — Использование хранилища для работы с образами

При публикации образа приложения в таком реестре как Docker Hub вы делаете его доступным для последующего использования при построении и масштабировании контейнеров. Для примера мы покажем, как разместить образ приложения в хранилище и использовать его для воссоздания контейнера.

Прежде всего необходимо войти в учетную запись Docker Hub, созданную в соответствии с предварительными требованиями:

  • docker login -u your_dockerhub_username

Введите пароль учетной записи Docker Hub в соответствующем диалоговом окне. При входе в каталоге home вашего пользователя будет создан файл ~/.docker/config.json с вашими учетными данными Docker Hub.

Теперь вы можете записать образ приложения в Docker Hub, используя ранее созданную метку your_dockerhub_username/nodejs-image-demo:

  • docker push your_dockerhub_username/nodejs-image-demo

Давайте проверим использование реестра образов. Для этого уничтожим текущий контейнер приложения и образ и воссоздадим их на основе образа из хранилища.

Вначале перечислите запущенные контейнеры:

  • docker ps

Результат будет выглядеть следующим образом:

Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "node app.js" 3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp nodejs-image-demo

Остановите запущенный контейнер приложения, используя идентификатор CONTAINER ID, показанный в результатах. Обязательно замените выделенный ниже идентификатор собственным идентификатором CONTAINER ID:

  • docker stop e50ad27074a7

Перечислите все образы, используя флаг -a:

  • docker images -a

Вы увидите следующие результаты с именем образа your_dockerhub_username/nodejs-image-demo, а также образом узла и другими образами из вашей сборки:

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

Удалите остановленный контейнер и все образы, включая неиспользуемые или недействительные образы, с помощью следующей команды:

  • docker system prune -a

Введите y в диалоговом окне, чтобы подтвердить удаление остановленного контейнера и образов. Помните, что при этом также будет удален кэш вашей сборки.

Теперь вы удалили контейнер с образом приложения и сам образ. Дополнительную информацию об удалении контейнеров Docker, образов и томов можно найти в документе «Удаление образов, контейнеров и томов Docker».

Удалив все образы и контейнеры, вы можете извлечь образ приложения из Docker Hub:

  • docker pull your_dockerhub_username/nodejs-image-demo

Еще раз перечислите образы:

  • docker images

Вы увидите образ вашего приложения:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 73MB

Теперь вы можете воссоздать свой контейнер, используя команду из шага 3:

  • docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

Перечислите запущенные контейнеры:

  • docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "node app.js" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo

Посетите http://your_server_ip еще раз, чтобы просмотреть запущенное приложение.

Заключение

В этом обучающем руководстве вы создали статическое веб-приложение с Express и Bootstrap, а также образ Docker для этого приложения. Вы использовали этот образ для создания контейнера и разместили его в Docker Hub. Затем вы смогли уничтожить образ и контейнер и воссоздать их с помощью хранилища Docker Hub.

Если вы хотите узнать больше о работе с такими инструментами, как Docker Compose и Docker Machine для создания мультиконтейнерных систем, вы можете ознакомиться со следующими руководствами:

Общие советы по работе с данными контейнера можно найти здесь:

Если вы интересуетесь другими темами по Docker, ознакомьтесь с нашей полной библиотекой обучающих пособий по Docker.

0 Comments

Creative Commons License