Контейнеризация приложения 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
:
- 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"
}
}
Сохраните и закройте файл, когда закончите редактирование. Если вы используете nano
, нажмите CTRL+X
, затем Y
, затем ENTER
.
Имея готовый код проекта и измененные его зависимости, вы можете перейти к рефакторингу кода для контейнерного рабочего процесса.
Шаг 2 — Настройка вашего приложения для работы с контейнерами
Изменение приложения для контейнерного рабочего процесса означает создание более модульного кода. Контейнеры обеспечивают переносимость между средами, и ваш код должен отражать это, оставаясь максимально отделенным от базовой операционной системы. Для этого вы проведете рефакторинг своего кода, чтобы лучше использовать свойство 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, программу сопоставления документов объектов (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
со значениями, которые вы можете передать своему приложению во время выполнения.
Откройте файл:
- 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
...
На данный момент вы успешно извлекли конфиденциальную информацию из кода вашего проекта и приняли меры для контроля того, как и где эта информация копируется. Теперь вы можете добавить код подключения к базе данных, чтобы оптимизировать его для контейнерного рабочего процесса.
Шаг 3 — Изменение настроек подключения к базе данных
Следующим шагом будет сделать ваш метод подключения к базе данных более надежным, добавив код, который обрабатывает случаи, когда вашему приложению не удается подключиться к вашей базе данных. Внедрение этого уровня устойчивости в код вашего приложения является рекомендуемой практикой при работе с контейнерами с помощью Compose.
Откройте db.js
для редактирования:
- 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
:
- 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 образа приложения. Если вы хотите использовать существующий образ из реестра, например инструкцию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
в фоновом режиме:- 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
Вывод показывает, что ваши контейнеры работают:
OutputName 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
в символ «Акула». поле:Нажмите кнопку «Отправить», и вам отобразится страница с этой информацией об акуле:
В качестве последнего шага проверьте, что данные, которые вы только что ввели, сохранятся, если вы удалите контейнер базы данных.
Вернувшись к терминалу, введите следующую команду, чтобы остановить и удалить контейнеры и сеть:
- 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
:Как только вы нажмете «Отправить», вы заметите, что новая акула была добавлена в коллекцию акул в вашей базе данных без потери уже введенных вами данных:
Теперь ваше приложение работает в контейнерах Docker с включенным сохранением данных и синхронизацией кода.
Заключение
Следуя этому руководству, вы создали настройку разработки для своего приложения Node с использованием контейнеров Docker. Вы сделали свой проект более модульным и переносимым, извлекая конфиденциальную информацию и отделяя состояние вашего приложения от кода вашего приложения. Вы также настроили шаблонный файл
docker-compose.yml
, который вы можете пересматривать по мере изменения ваших потребностей и требований в области разработки.По мере разработки вам может быть интересно узнать больше о разработке приложений для контейнеров и модернизации приложений для Kubernetes, чтобы получить дополнительную информацию по этим темам.
Чтобы узнать больше о коде, используемом в этом руководстве, см. статью Как защитить контейнерное приложение Node.js с помощью Nginx, Let’s Encrypt и Docker Compose.
- Первый способ — это монтирование с привязкой, которое монтирует код вашего приложения на хосте в каталог