Если вы активно занимаетесь разработкой приложений, использование Docker может упростить ваш рабочий процесс и процесс развертывания вашего приложения в продакшен. Работа с контейнерами в процессе разработки предоставляет следующие преимущества:
Из этого руководства вы узнаете, как выполнять настройку среды разработки для приложения Node.js с помощью Docker. Вы создадите два контейнера, один для приложения Node, а другой для базы данных MongoDB с помощью Docker Compose. Поскольку это приложение работает с Node и MongoDB, необходимо выполнить следующие настройки:
После изучения данного руководства у вас будет рабочее приложение с информацией об акулах, работающее на контейнерах Docker:
Для данного обучающего модуля вам потребуется следующее:
sudo
и активный брандмауэр. Дополнительную информацию о настройке этих параметров см. в руководстве по первоначальной настройке сервера.Первым, что необходимо сделать при настройке системы, является клонирование кода проекта и изменение файла package.json
, который включает зависимости проекта. Мы добавим nodemon
в devDependencies
проекта, чтобы указать, что мы будем использовать его при разработке. Запуск приложения с nodemon
обеспечивает автоматический перезапуск при внесении изменений в ваш код.
Во-первых, клонируйте репозиторий nodejs-mongo-mongoose
из учетной записи DigitalOcean Community на GitHub. Этот репозиторий включает код настройки, описанной в руководстве Интеграция MongoDB с вашим приложением Node, которое содержит описание процесса интеграции базы данных MongoDB с существующим приложением Node с помощью Mongoose.
Клонируйте репозиторий в директорию с именем node_project
:
- git clone https://github.com/do-community/nodejs-mongo-mongoose.git node_project
Перейдите в директорию node_project
:
- cd node_project
Откройте файл проекта package.json
с помощью nano
или вашего любимого редактора:
- nano package.json
После зависимостей проекта и над закрывающей фигурной скобкой создайте новый объект devDependencies
, который включает nodemon
:
...
"dependencies": {
"ejs": "^2.6.1",
"express": "^4.16.4",
"mongoose": "^5.4.10"
},
"devDependencies": {
"nodemon": "^1.18.10"
}
}
Сохраните и закройте файл после завершения редактирования.
После добавления кода проекта и изменения зависимостей вы можете перейти к рефакторингу кода для контейнеризованного рабочего процесса.
Изменение нашего приложения для контейнеризованного рабочего процесса подразумевает, что код должен быть более модульным. Контейнеры обеспечивают возможность перемещения между рабочими средами, и наш код должен отражать это, оставаясь как можно менее привязанным к лежащей в основе операционной системе. Для этого мы выполним рефакторинг нашего кода, чтобы добиться более эффективного использования свойства Node process.env, которое возвращает объект с информацией о среде пользователя при запуске. Мы можем использовать этот объект в нашем коде для динамического сохранения информации о конфигурации при запуске в переменных среды.
Давайте начнем с app.js
, главной точки входа нашего приложения. Откройте файл:
- 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
, содержащий следующую информацию:
- nano db.js
В настоящее время файл выполняет следующие функции:
mongoose.connect
.Дополнительную информацию о файле см. в шаге 3 руководства Интеграция 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
со значениями, которые вы можете передать вашему приложению при запуске.
Откройте файл:
- 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
:
- nano .dockerignore
Добавьте следующую строку внизу файла:
...
.gitignore
.env
Сохраните и закройте файл после завершения редактирования.
Файл .gitignore
в этом репозитории уже включает .env
, но вы можете убедиться в его наличии:
- nano .gitignore
...
.env
...
На данный момент вы успешно извлекли чувствительную информацию из кода проекта и приняли меры для контроля того, как и куда будет скопирована эта информация. Теперь вы можете добавить дополнительный уровень надежности для кода подключения к базе данных, чтобы оптимизировать его для контейнеризованного рабочего процесса.
Следующим нашим шагом будет повышение надежности работы метода подключения к базе данных с помощью кода, который обрабатывает случаи, когда нашему приложению не удается подключиться к нашей базе данных. Введение данного уровня устойчивости в код приложения является рекомендуемой практикой при работе с контейнерами с помощью Compose.
Откройте db.js
для редактирования:
- nano db.js
Вы увидите добавленный нами ранее код, а также константу url
для URI подключения к Mongo и метод подключения к Mongoose
:
...
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
в методе connect
Mongoose для тонкой настройки подключения Mongoose. Также мы добавим promise для обработки потенциальных ошибок подключения.
В настоящее время метод connect
Mongoose выглядит следующим образом:
...
mongoose.connect(url, {useNewUrlParser: true});
Удалите существующий метод connect
и замените его следующим кодом, который включает константу options
и promise:
...
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.
После выполнения рефакторинга кода вы можете начинать добавлять в файл docker-compose.yml
определения служб. Служба в Compose — это запущенный контейнер, а определения служб, которые вы будете добавлять в ваш файл docker-compose.yml
, содержат информацию о том, как будет запускаться образ каждого контейнера. Compose позволяет вам определять различные службы для создания приложений с несколькими контейнерами.
Прежде чем определять службы, мы добавим в наш проект инструмент с именем wait-for
, чтобы гарантировать, что наше приложение будет пытаться подключиться к нашей базе данных только после завершения всех задач, связанных с запуском базы данных. Этот скрипт обертки использует netcat
для опроса, поддерживает или нет конкретный хост и порт подключение по протоколу TCP. Благодаря этому вы можете контролировать попытки подключения вашего приложения к базе данных, проверяя, готова ли база данных к подключению.
Хотя Compose позволяет вам указывать зависимости между службами с помощью параметра depends_on
, данный порядок определяется тем, запущен контейнер или нет, а не его готовностью. Использование depends_on
при настройке не является оптимальным решением, поскольку мы хотим, чтобы наше приложение подключилось только после того, как все задачи запуска базы данных, включая добавление пользователя и пароля в базу данных аутентификации admin
, будут выполнены. Дополнительную информацию об использовании wait-for
и других инструментов для контроля порядка запуска можно найти в соответствующих разделах с рекомендациями в документации Compose.
Откройте файл с именем wait-for.sh
:
- 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 "$@"
Сохраните и закройте файл после добавления кода.
Создайте исполняемый скрипт:
- chmod +x wait-for.sh
Затем откройте файл docker-compose.yml
:
- 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. Если вы хотите использовать существующий образ из реестра, например, из Docker Hub, вы можете использовать инструкцию image
с информацией об имени пользователя, репозитория и теге образа.
context
: это определение контекста сборки для сборки образа, в этом случае текущая директория проекта.
dockerfile
: данный параметр определяет Dockerfile
в текущей директории проекта в качестве файла, который Compose будет использоваться для сборки образа приложения. Дополнительную информацию об этом файле см. в руководстве Создание приложения Node.js с помощью Docker.
image
, container_name
: эти параметры присваивают имена для образа и контейнера.
restart
: данный параметр определяет политику перезапуска. По умолчанию установлено значение no
, но мы задали значение, согласно которому контейнер будет перезапускаться, пока не будет закрыт.
env_file
: этот параметр указывает Compose, что мы хотим добавить переменные среды из файла с именем .env
, расположенного в контексте сборки.
environment
: с помощью этого параметра вы можете добавить настройки подключения к Mongo, которые вы определили в файле .env
. Обратите внимание, что мы не задаем значение development
для NODE_ENV
, так как это поведение Express по умолчанию, если значение NODE_ENV
не задано. При переходе в продакшен вы можете установить значение production
, чтобы активировать кэширование вида и получать более короткие сообщения об ошибках. Также необходимо отметить, что мы указали в качестве хоста контейнер базы данных db
, как описано в шаге 2.
ports
: данный параметр назначает порт 80
хоста для порта 8080
в контейнере.
volumes
: мы используем два типа монтирования:
/home/node/app
в контейнере. Это упрощает быструю разработку, поскольку любые изменения, которые вы вносите в код хоста, будут немедленно добавлены в контейнер.node_modules
. Когда Docker запускает инструкцию npm install
, присутствующую в Dockerfile
приложения, npm
будет создавать новую директорию 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
на хосте. Это соответствует подходу к разработке приложений с учетом 12 факторов, который минимизирует зависимости между средами исполнения.networks
: данный параметр указывает, что служба приложения будет подключаться к сети app-network
, которую мы определим внизу файла.
command
: данный параметр позволяет вам задавать команду, которая должна быть выполнена при запуске 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
и volumes
:
image
: для создания этой службы Compose будет запрашивать образ 4.1.8-xenial
Mongo из Docker Hub. Мы закрепляем конкретную версию, чтобы избежать возможных будущих конфликтов при изменении образа Mongo. Дополнительную информацию о закреплении версии см. в документации Docker Рекомендации по работе с Dockerfile.MONGO_INITDB_ROOT_USERNAME
, MONGO_INITDB_ROOT_PASSWORD
: образ mongo
делает эти переменные среды доступными, чтобы вы могли изменять порядок инициализации экземпляра вашей базы данных. MONGO_INITDB_ROOT_USERNAME
и MONGO_INITDB_ROOT_PASSWORD
вместе создают root
-пользователя в базе данных аутентификации admin
и гарантируют, что аутентификацию будет активирована при запуске контейнера. Мы задали MONGO_INITDB_ROOT_USERNAME
и MONGO_INITDB_ROOT_PASSWORD
, используя значения из нашего файла .env
, который мы передаем службе db
, используя параметр env_file
. Подобные действия означают, что пользователь нашего приложения sammy
будет root
-пользователем в экземпляре базы данных с доступом ко всем административным и оперативным правам этой роли. При работе в продакшене вы можете захотеть создать специального пользователя приложения с соответствующим набором привилегий.
<$>[note]
Примечание: необходимо помнить, что эти переменные не будут применяться, если вы запускаете контейнер, используя существующую директорию данных.
<$>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:
Сохраните и закройте файл после завершения редактирования.
Когда ваши определения службы будут готовы, вы сможете запустить приложение.
Имея в распоряжении файл docker-compose.yml
, вы можете создать ваши службы с помощью команды docker-compose up
. Также вы можете проверить, что ваши данные будут сохраняться, останавливая работу контейнеров и удаляя их с помощью docker-compose down
.
Во-первых, необходимо выполнить сборку образов и создать службы, запустив docker-compose
с флагом -d
, который будет запускать контейнеры nodejs
и db
в фоновом режиме:
- docker-compose up -d
Вы увидите вывод, подтверждающий, что ваши службы были успешно созданы:
Output...
Creating db ... done
Creating nodejs ... done
Также вы можете получить более подробную информацию о процессах запуска, отобразив вывод журнала из служб:
- 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
:
- 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
в браузере. Вы увидите стартовую страницу, которая будет выглядеть примерно так:
Нажмите кнопку Get Shark Info (Получить информацию об акулах). Вы увидите страницу с формой входа, где вы можете ввести имя акулы и описание общего типа этой акулы:
В этой форме добавьте акулу по вашему выбору. В демонстрационных целях мы добавим Megalodon Shark
в поле Shark Name (Имя акулы) и Ancient
в поле Shark Character (Тип акулы):
Нажмите кнопку Submit (Отправить). Вы увидите страницу с информацией об акуле, отображаемую для вас:
В заключение мы можем проверить, что данные, которые вы только что добавили, будут сохраняться, если вы удалите контейнер базы данных.
Вернитесь в терминал, введите следующую команду для остановки и удаления контейнеров и сети:
- docker-compose down
Обратите внимание, что мы не включаем параметр --volumes,
и поэтому наш том dbdata
не удаляется.
Следующая информация подтверждает, что ваши контейнеры и сеть были удалены:
OutputStopping nodejs ... done
Stopping db ... done
Removing nodejs ... done
Removing db ... done
Removing network node_project_app-network
Повторно создайте контейнеры:
- docker-compose up -d
Затем вернитесь к форме информации об акуле:
Введите новую акулу по вашему выбору. Мы будем использовать значение Whale Shark
и Large
:
После нажатия кнопки **Submit **(Отправить) вы увидите, что новая акула добавлена в коллекцию акул в вашей базе данных без потери ранее введенных данных:
Ваше приложение сейчас запущено в контейнерах Docker с сохранением данных и активацией синхронизации кода.
Выполняя указания данного руководства, вы создали настройку разработки для вашего приложения Node с помощью контейнеров Docker. Вы сделали ваш проект более модульным и портативным с помощью извлечения чувствительной информации и отделив состояние вашего приложения от кода приложения. Вы также настроили шаблонный файл docker-compose.yml
, который вы можете изменять в зависимости от потребностей разработки и изменений требований.
В процессе разработки вы можете захотеть узнать больше о проектировании приложений для контейнеризованных рабочих процессов и процессов Cloud Native. Дополнительную информацию по этим темам вы можете посмотреть в статьях Разработка архитектуры приложений для Kubernetes и Модернизация приложений для Kubernetes.
Дополнительную информацию о коде, используемом в этом руководстве, см. в статьях Сборка приложения Node.js с помощью Docker и Интеграция MongoDB с вашим приложением Node. Дополнительную информацию о развертывании приложения Node с обратным прокси-сервером Nginx с помощью контейнеров см. в статье Обеспечение безопасности контейнеризованного приложения Node.js с Nginx, Let’s Encrypt и Docker Compose.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Thank you so much.