Перезапускающийся контейнер

Мне нужно связать контейнер 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 шт):

Автор решения: Alexander Yukal

Для того чтобы связать два контейнера их необходимо правильно настроить в одном файле 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 не зациклен на постоянное выполнение, в таком случае процесс завершится.

→ Ссылка