Перезапускающийся контейнер
Мне нужно связать контейнер Laravel с контейнером Node.js. Но для начала было бы неплохо хотя бы успешно запустить контейнер с Node.js. Я на данный момент не очень хорошо понял, каким образом запускаются контейнеры в Docker. Вроде бы, нужно запустить какой-то процесс, который не будет останавливаться. В интернете нашёл разные куски кода, показывающие запуск Node.js в Docker. Переделал это под Docker Compose, но не работает, консоль пишет Exited (2) 10 minutes ago. Ниже добавил куски кода для понимания.
docker-compose.yml
nodejs:
build:
context: .
dockerfile: nodejs/Dockerfile
container_name: nodejs
restart: unless-stopped
ports:
- 80:80
volumes:
- ./nodejs/server:/var/nodejs/server
Dockerfile
FROM node:latest
RUN cd /var/nodejs/server && npm install
CMD ["node", "server.js"]
package.json
{
"name": "docker_nodejs_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
server.js
'use strict';
const express = require('express');
const port = 80;
const host = '0.0.0.0';
const app = express();
app.get('/', (req, res) => {
res.send('Test Docker');
});
app.listen(port, host);
console.log('Running on http://'+host+':'+port);
Пишет такую ошибку:
/bin/sh: 1: cd: can't cd to /var/nodejs/server
ERROR: Service 'nodejs' failed to build: The command '/bin/sh -c cd /var/nodejs/server && npm install' returned a non-zero code: 2
Почему он не видит /var/nodejs/server, если эта директория указана в docker-compose.yml? В ней же как раз и лежит файл server.js.
P.S.: У меня работает связка Nginx + PHP + MariaDB по, примерно, такому же принципу и всё запускается корректно и без ошибок.
Ответы (1 шт):
Для того чтобы связать два контейнера их необходимо правильно настроить в одном файле docker-compose.yaml указав под дерективой services необходимые параметры каждого сервиса. В параметрах конфигурации каждого сервиса также необходимо указать рабочую сеть network, пробрасываемые порты ports и подключаемые тома volumes директорий
Директива volumes должна указывать на директорию а не конкретный файл:
# Не правильно
volumes:
- ./nodejs/server:/var/nodejs/server
# Правильно
volumes:
- ./nodejs:/var/nodejs
Посмотрим пример как должен быть оформлен docker-compose.yml с несколькими контейнерами
version: '3'
services:
#Nodejs Service
nodejs:
container_name: webdev_nodejs
build:
context: .
dockerfile: ./nodejs/Dockerfile
restart: unless-stopped
working_dir: /var/nodejs
networks:
- webdev_network
ports:
- 80:80
volumes:
- ./nodejs:/var/nodejs
#PHP Service
php:
container_name: webdev_php
build:
context: .
dockerfile: ./php/Dockerfile
restart: unless-stopped
working_dir: /var/php
networks:
- webdev_network
ports:
- 81:82
volumes:
- ./php:/var/php
# Данный параметр говорит докеру о том, что текущий контейнер
# зависит от контейнера под именем "nodejs", и запуск текущего
# контейнера не произойдет до тех пор, пока не загрузится
# зависящий от него контейнер.
depends_on:
- nodejs
networks:
webdev_network:
driver: bridge
external: false
Понимание подключения томов (Volumes)
При подключении одного или нескольких томов, докер создает виртуальную файловую систему на которую поочередно налаживает слой подключаемых томов. В первую очередь он берет файловую сестему из уже спроектированного образа, сверху он налаживает еще один том в зависимости от приоритета важности контейнера, которую можно котроллировать с помощью параметра depends_on.
Если тома из разных контейнеров будут совпадать, тогда один из них перезатрется последним наложенным слепком.
А возможно проблема в другом, может быть server.js не зациклен на постоянное выполнение, в таком случае процесс завершится.