Поиск по сайту:

Контейнеризация приложения Node.js для разработки с помощью Docker Compose


Введение

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

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

В этом руководстве показано, как настроить среду разработки для Docker Compose. Поскольку это приложение работает с Node и MongoDB, ваша установка будет выполнять следующие действия:

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

В конце этого руководства у вас будет работающее информационное приложение об акулах, работающее в контейнерах Docker:

Предпосылки

Чтобы следовать этому руководству, вам понадобятся:

  • Сервер разработки под управлением Ubuntu 18.04, пользователь без полномочий root с правами sudo и активным брандмауэром. Инструкции по их настройке см. в этом руководстве по начальной настройке сервера.
  • Docker установлен на вашем сервере в соответствии с шагами 1 и 2 инструкции по установке и использованию Docker в Ubuntu 18.04.
  • Docker Compose установлен на вашем сервере в соответствии с шагом 1 инструкции по установке Docker Compose в Ubuntu 18.04.

Шаг 1 — Клонирование проекта и изменение зависимостей

Первым шагом в создании этой установки будет клонирование кода проекта и изменение его devDependencies, указав, что вы будете использовать его во время разработки. Запуск приложения с помощью nodemon гарантирует, что оно будет автоматически перезапускаться всякий раз, когда вы вносите изменения в свой код.

Во-первых, клонируйте Мангуста.

Клонируйте репозиторий в каталог с именем node_project:

  1. git clone https://github.com/do-community/nodejs-mongo-mongoose.git node_project

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

  1. cd node_project

Откройте файл проекта package.json с помощью nano или вашего любимого редактора:

  1. nano package.json

Под зависимостями проекта и над закрывающей фигурной скобкой создайте новый объект devDependencies, который включает nodemon:

...
"dependencies": {
    "ejs": "^2.6.1",
    "express": "^4.16.4",
    "mongoose": "^5.4.10"
  },
  "devDependencies": {
    "nodemon": "^1.18.10"
  }    
}

Сохраните и закройте файл, когда закончите редактирование. Если вы используете nano, нажмите CTRL+X, затем Y, затем ENTER.

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

Шаг 2 — Настройка вашего приложения для работы с контейнерами

Изменение приложения для контейнерного рабочего процесса означает создание более модульного кода. Контейнеры обеспечивают переносимость между средами, и ваш код должен отражать это, оставаясь максимально отделенным от базовой операционной системы. Для этого вы проведете рефакторинг своего кода, чтобы лучше использовать свойство Node process.env. Это возвращает объект с информацией о вашей пользовательской среде во время выполнения. Вы можете использовать этот объект в своем коде для динамического назначения информации о конфигурации во время выполнения с помощью переменных среды.

Начните с app.js, вашей основной точки входа в приложение. Откройте файл:

  1. nano app.js

Внутри вы увидите определение функции port listen, которая использует эту константу для указания порта, который приложение будет прослушивать:

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

Переопределите константу port, чтобы разрешить динамическое назначение во время выполнения с помощью объекта process.env. Внесите следующие изменения в определение константы и функцию listen:

...
const port = process.env.PORT || 8080;
...
app.listen(port, function () {
  console.log(`Example app listening on ${port}!`);
});

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

Когда вы закончите редактирование, сохраните и закройте файл.

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

  1. nano db.js

В настоящее время файл выполняет следующие действия:

  • Импортирует Mongoose, программу сопоставления документов объектов (ODM), которую вы используете для создания схем и моделей данных вашего приложения.
  • Задает учетные данные базы данных как константы, включая имя пользователя и пароль.
  • Подключается к базе данных с помощью метода mongoose.connect.

Дополнительные сведения об этом файле см. в разделе Как интегрировать MongoDB с вашим приложением Node.

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

...
const MONGO_USERNAME = 'sammy';
const MONGO_PASSWORD = 'your_password';
const MONGO_HOSTNAME = '127.0.0.1';
const MONGO_PORT = '27017';
const MONGO_DB = 'sharkinfo';
...

Вместо жесткого кодирования этой информации вы можете использовать объект process.env для захвата значений времени выполнения для этих констант. Измените блок, чтобы он выглядел так:

...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;
...

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

На данный момент вы изменили db.js для работы с переменными среды вашего приложения, но вам все еще нужен способ передать эти переменные в ваше приложение. Создайте файл .env со значениями, которые вы можете передать своему приложению во время выполнения.

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

  1. nano .env

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

MONGO_USERNAME=sammy
MONGO_PASSWORD=your_password
MONGO_PORT=27017
MONGO_DB=sharkinfo

Обратите внимание, что вы удалили параметр хоста, который первоначально отображался в db.js. Теперь вы определите свой хост на уровне файла Docker Compose вместе с другой информацией о ваших службах и контейнерах.

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

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

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

  1. nano .dockerignore

Добавьте следующую строку в конец файла:

...
.gitignore
.env

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

Файл .gitignore в этом репозитории уже содержит .env, но не стесняйтесь проверить его наличие:

  1. nano .gitignore
...
.env
...

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

Шаг 3 — Изменение настроек подключения к базе данных

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

Откройте db.js для редактирования:

  1. nano db.js

Обратите внимание на добавленный ранее код, а также константу url для URI подключения Mongo и метод Mongoose connect:

...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;

mongoose.connect(url, {useNewUrlParser: true});

В настоящее время ваш метод connect принимает опцию, которая сообщает Mongoose использовать новый анализатор URL-адресов Mongo. Вы можете добавить параметры к этому методу, чтобы определить параметры для попыток повторного подключения. Для этого создайте константу options, которая включает соответствующую информацию, в дополнение к новой опции парсера URL. Под константами Mongo добавьте следующее определение константы options:

...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

const options = {
  useNewUrlParser: true,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 500, 
  connectTimeoutMS: 10000,
};
...

Опция reconnectTries указывает Mongoose продолжать попытки подключения бесконечно, а reconnectInterval определяет период между попытками подключения в миллисекундах. connectTimeoutMS определяет 10 секунд как период, в течение которого драйвер Mongo будет ждать перед неудачной попыткой подключения.

Теперь вы можете использовать новую константу options в методе Mongoose connect для точной настройки параметров подключения Mongoose. Вы также добавите обещание обрабатывать потенциальные ошибки подключения.

В настоящее время метод Mongoose connect выглядит следующим образом:

...
mongoose.connect(url, {useNewUrlParser: true});

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

...
mongoose.connect(url, options).then( function() {
  console.log('MongoDB is connected');
})
  .catch( function(err) {
  console.log(err);
});

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

Готовый файл будет выглядеть так:

const mongoose = require('mongoose');

const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

const options = {
  useNewUrlParser: true,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 500,
  connectTimeoutMS: 10000,
};

const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;

mongoose.connect(url, options).then( function() {
  console.log('MongoDB is connected');
})
  .catch( function(err) {
  console.log(err);
});

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

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

Шаг 4 — Определение сервисов с помощью Docker Compose

После рефакторинга кода вы готовы написать файл docker-compose.yml с определениями службы. Служба в Compose — это работающий контейнер, а определения службы, которые вы включите в свой файл docker-compose.yml, содержат информацию о том, как будет работать каждый образ контейнера. Инструмент Compose позволяет определить несколько служб для создания многоконтейнерных приложений.

Перед определением своих служб вы добавите в свой проект инструмент под названием netcat, чтобы узнать, принимает ли определенный хост и порт TCP-соединения. Его использование позволяет вам контролировать попытки вашего приложения подключиться к вашей базе данных, проверяя, готова ли база данных принимать подключения.

Хотя Compose позволяет указывать зависимости между сервисами, используя рекомендации в документации Compose.

Откройте файл с именем wait-for.sh:

  1. nano wait-for.sh

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

#!/bin/sh

# original script: https://github.com/eficode/wait-for/blob/master/wait-for

TIMEOUT=15
QUIET=0

echoerr() {
  if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
}

usage() {
  exitcode="$1"
  cat << USAGE >&2
Usage:
  $cmdname host:port [-t timeout] [-- command args]
  -q | --quiet                        Do not output any status messages
  -t TIMEOUT | --timeout=timeout      Timeout in seconds, zero for no timeout
  -- COMMAND ARGS                     Execute command with args after the test finishes
USAGE
  exit "$exitcode"
}

wait_for() {
  for i in `seq $TIMEOUT` ; do
    nc -z "$HOST" "$PORT" > /dev/null 2>&1
    
    result=$?
    if [ $result -eq 0 ] ; then
      if [ $# -gt 0 ] ; then
        exec "$@"
      fi
      exit 0
    fi
    sleep 1
  done
  echo "Operation timed out" >&2
  exit 1
}

while [ $# -gt 0 ]
do
  case "$1" in
    *:* )
    HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
    PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
    shift 1
    ;;
    -q | --quiet)
    QUIET=1
    shift 1
    ;;
    -t)
    TIMEOUT="$2"
    if [ "$TIMEOUT" = "" ]; then break; fi
    shift 2
    ;;
    --timeout=*)
    TIMEOUT="${1#*=}"
    shift 1
    ;;
    --)
    shift
    break
    ;;
    --help)
    usage 0
    ;;
    *)
    echoerr "Unknown argument: $1"
    usage 1
    ;;
  esac
done

if [ "$HOST" = "" -o "$PORT" = "" ]; then
  echoerr "Error: you need to provide a host and port to test."
  usage 2
fi

wait_for "$@"

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

Сделайте скрипт исполняемым:

  1. chmod +x wait-for.sh

Затем откройте файл docker-compose.yml:

  1. nano docker-compose.yml

Сначала определите службу приложения nodejs, добавив в файл следующий код:

version: '3'

services:
  nodejs:
    build:
      context: .
      dockerfile: Dockerfile
    image: nodejs
    container_name: nodejs
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=db
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB 
    ports:
      - "80:8080"
    volumes:
      - .:/home/node/app
      - node_modules:/home/node/app/node_modules
    networks:
      - app-network
    command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js

Определение службы nodejs включает следующие параметры:

  • build: определяет параметры конфигурации, включая context и dockerfile, которые будут применяться при сборке Compose образа приложения. Если вы хотите использовать существующий образ из реестра, например инструкцию image, с информацией о вашем имени пользователя, репозитории и теге изображения.
  • context: определяет контекст сборки для сборки образа — в данном случае текущий каталог проекта.
  • dockerfile: указывает Dockerfile в вашем текущем каталоге проекта в качестве файла, который Compose будет использовать для создания образа приложения. Дополнительные сведения об этом файле см. в разделе Как создать приложение Node.js с помощью Docker.
  • image, имя_контейнера: присваивают имена изображению и контейнеру.
  • restart: определяет политику перезапуска. По умолчанию используется нет, но вы настроили перезапуск контейнера, если он не будет остановлен.
  • env_file: указывает Compose, что вы хотите добавить переменные среды из файла с именем .env, расположенного в контексте сборки.
  • environment: использование этого параметра позволяет добавить настройки подключения Mongo, которые вы определили в файле .env. Обратите внимание, что вы не устанавливаете для NODE_ENV значение development, так как это включает кэширование представлений и менее подробные сообщения об ошибках. Также обратите внимание, что вы указали контейнер базы данных db в качестве хоста, как обсуждалось на шаге 2.
  • ports: сопоставляет порт 80 на хосте с портом 8080 в контейнере.
  • тома: здесь вы включаете два типа монтирования:
    • Первый способ — это монтирование с привязкой, которое монтирует код вашего приложения на хосте в каталог /home/node/app в контейнере. Это ускорит разработку, поскольку любые изменения, которые вы вносите в код хоста, будут немедленно внесены в контейнер.
    • Второй — это именованный каталог node_modules в контейнере, содержащий пакеты, необходимые для запуска приложения. Однако только что созданное монтирование привязки скроет этот вновь созданный каталог node_modules. Поскольку node_modules на хосте пуст, привязка сопоставит пустой каталог с контейнером, переопределяя новый каталог node_modules и предотвращая запуск вашего приложения. Именованный том node_modules решает эту проблему, сохраняя содержимое каталога /home/node/app/node_modules и подключая его к контейнеру, скрывая привязку.

    При использовании этого подхода помните о следующих моментах:

    • Ваша привязка смонтирует содержимое каталога node_modules в контейнере на хост, и этот каталог будет принадлежать root, поскольку именованный том был создан Docker.
    • Если у вас уже есть каталог node_modules на хосте, он переопределит каталог node_modules, созданный в контейнере. Настройка, которую вы создаете в этом руководстве, предполагает, что у вас нет ранее существовавшего каталога node_modules и что вы не будете работать с npm на своем хосте. Это соответствует двенадцатифакторному подходу к разработке приложений, который сводит к минимуму зависимости между средами выполнения.

    • networks. Указывает, что служба вашего приложения будет присоединена к сети app-network, которую вы определите в нижней части файла.
    • команда: этот параметр позволяет указать команду, которая должна выполняться, когда Compose запускает изображение. Обратите внимание, что это переопределит инструкцию CMD, которую вы установили в нашем приложении Dockerfile. Здесь вы запускаете приложение с помощью сценария wait-for, который будет опрашивать службу db через порт 27017, чтобы проверить, работает ли служба базы данных. готов. Как только проверка готовности пройдет успешно, скрипт выполнит заданную вами команду /home/node/app/node_modules/.bin/nodemon app.js, чтобы запустить приложение с помощью nodemon. Это гарантирует, что любые будущие изменения, которые вы вносите в свой код, будут перезагружены без перезапуска приложения.

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

    ...
      db:
        image: mongo:4.1.8-xenial
        container_name: db
        restart: unless-stopped
        env_file: .env
        environment:
          - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
          - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
        volumes:  
          - dbdata:/data/db   
        networks:
          - app-network  
    

    Некоторые настройки, определенные для службы nodejs, остались прежними, но вы также внесли следующие изменения в image, environment и тома определения:

    • image. Чтобы создать эту службу, Compose использует рекомендации 4.1.8-xenial Dockerfile.
    • MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD: образ mongo делает этих пользователей root в экземпляре базы данных с доступом к все административные и операционные привилегии этой роли. При работе в производственной среде вам потребуется создать выделенного пользователя приложения с соответствующими привилегиями.

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

    • dbdata:/data/db: именованный том dbdata сохранит данные, хранящиеся в каталоге данных Mongo по умолчанию, /data/db. . Это гарантирует, что вы не потеряете данные в случаях, когда вы останавливаете или удаляете контейнеры.

    Служба db также была добавлена в сеть app-network с параметром networks.

    В качестве последнего шага добавьте определения тома и сети в конец файла:

    ...
    networks:
      app-network:
        driver: bridge
    
    volumes:
      dbdata:
      node_modules:  
    

    Определяемая пользователем мостовая сеть app-network обеспечивает связь между вашими контейнерами, поскольку они находятся на одном хосте демона Docker. Это оптимизирует трафик и обмен данными внутри приложения, поскольку открывает все порты между контейнерами в одной и той же мостовой сети, при этом никакие порты не открываются внешнему миру. Таким образом, ваши контейнеры db и nodejs могут взаимодействовать друг с другом, и вам нужно только открыть порт 80 для внешнего доступа к приложению. .

    Ключ верхнего уровня volumes определяет тома dbdata и node_modules. Когда Docker создает тома, содержимое тома сохраняется в части файловой системы хоста, /var/lib/docker/volumes/, которой управляет Docker. Содержимое каждого тома хранится в каталоге /var/lib/docker/volumes/ и монтируется в любой контейнер, который использует этот том. Таким образом, данные об акулах, которые будут создавать ваши пользователи, сохранятся в томе dbdata, даже если вы удалите и заново создадите контейнер db.

    Готовый файл docker-compose.yml будет выглядеть так:

    version: '3'
    
    services:
      nodejs:
        build:
          context: .
          dockerfile: Dockerfile
        image: nodejs
        container_name: nodejs
        restart: unless-stopped
        env_file: .env
        environment:
          - MONGO_USERNAME=$MONGO_USERNAME
          - MONGO_PASSWORD=$MONGO_PASSWORD
          - MONGO_HOSTNAME=db
          - MONGO_PORT=$MONGO_PORT
          - MONGO_DB=$MONGO_DB
        ports:
          - "80:8080"
        volumes:
          - .:/home/node/app
          - node_modules:/home/node/app/node_modules
        networks:
          - app-network
        command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js 
    
      db:
        image: mongo:4.1.8-xenial
        container_name: db
        restart: unless-stopped
        env_file: .env
        environment:
          - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
          - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
        volumes:     
          - dbdata:/data/db
        networks:
          - app-network  
    
    networks:
      app-network:
        driver: bridge
    
    volumes:
      dbdata:
      node_modules:  
    

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

    Имея определения служб, вы готовы запустить приложение.

    Шаг 5 — Тестирование приложения

    Имея файл docker-compose.yml, вы можете создавать свои службы с помощью docker-compose down.

    Сначала соберите образы контейнеров и создайте службы, запустив docker-compose up с флагом -d, который затем запустит nodejs и Контейнеры db в фоновом режиме:

    1. docker-compose up -d

    Вывод подтверждает, что ваши сервисы созданы:

    Output
    ... Creating db ... done Creating nodejs ... done

    Вы также можете получить более подробную информацию о процессах запуска, отобразив вывод журнала из служб:

    1. docker-compose logs

    Если все запустилось правильно, выводится следующее:

    Output
    ... nodejs | [nodemon] starting `node app.js` nodejs | Example app listening on 8080! nodejs | MongoDB is connected ... db | 2019-02-22T17:26:27.329+0000 I ACCESS [conn2] Successfully authenticated as principal sammy on admin

    Вы также можете проверить статус своих контейнеров с помощью docker-compose ps:

    1. docker-compose ps

    Вывод показывает, что ваши контейнеры работают:

    Output
    Name Command State Ports ---------------------------------------------------------------------- db docker-entrypoint.sh mongod Up 27017/tcp nodejs ./wait-for.sh db:27017 -- ... Up 0.0.0.0:80->8080/tcp

    Когда ваши службы запущены, вы можете посетить http://your_server_ip в браузере:

    Нажмите кнопку «Получить информацию об акуле», чтобы перейти на страницу с формой ввода, где вы можете указать имя акулы и описание общего характера этой акулы:

    В форме добавьте акулу по вашему выбору. Для этой демонстрации добавьте Акула-мегалодон в поле «Имя акулы» и Ancient в символ «Акула». поле:

    Нажмите кнопку «Отправить», и вам отобразится страница с этой информацией об акуле:

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

    Вернувшись к терминалу, введите следующую команду, чтобы остановить и удалить контейнеры и сеть:

    1. docker-compose down

    Обратите внимание, что вы не включаете параметр --volumes; следовательно, ваш том dbdata не удаляется.

    Следующий вывод подтверждает, что ваши контейнеры и сеть были удалены:

    Output
    Stopping nodejs ... done Stopping db ... done Removing nodejs ... done Removing db ... done Removing network node_project_app-network

    Воссоздайте контейнеры:

    1. docker-compose up -d

    Теперь вернитесь к форме информации об акуле:

    Введите новую акулу по вашему выбору. В этом примере будут использоваться Whale Shark и Large:

    Как только вы нажмете «Отправить», вы заметите, что новая акула была добавлена в коллекцию акул в вашей базе данных без потери уже введенных вами данных:

    Теперь ваше приложение работает в контейнерах Docker с включенным сохранением данных и синхронизацией кода.

    Заключение

    Следуя этому руководству, вы создали настройку разработки для своего приложения Node с использованием контейнеров Docker. Вы сделали свой проект более модульным и переносимым, извлекая конфиденциальную информацию и отделяя состояние вашего приложения от кода вашего приложения. Вы также настроили шаблонный файл docker-compose.yml, который вы можете пересматривать по мере изменения ваших потребностей и требований в области разработки.

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

    Чтобы узнать больше о коде, используемом в этом руководстве, см. статью Как защитить контейнерное приложение Node.js с помощью Nginx, Let’s Encrypt и Docker Compose.