Я новичок в докере. Я пытаюсь создать образ Docker для проекта NodeJS, который я буду загружать / размещать в хранилище Docker. Когда я выполняю docker-compose up -d
все работает нормально, и я могу получить доступ к серверу nodeJS, который находится внутри контейнеров Docker. После этого я остановил все контейнеры и попытался создать образ Docker из файлов Docker, используя следующие команды:
docker build -t adonis-app .
docker run adonis-app
Первая команда выполняется без ошибок, но вторая команда выдает эту ошибку:
> adonis-fullstack-app@4.1.0 start /app
> node server.js
internal/modules/cjs/loader.js:983
throw err;
^
Error: Cannot find module '/app/server.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:980:15)
at Function.Module._load (internal/modules/cjs/loader.js:862:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! adonis-fullstack-app@4.1.0 start: `node server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the adonis-fullstack-app@4.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /app/.npm/_logs/2020-02-09T17_33_22_489Z-debug.log
Может кто-нибудь помочь мне с этой ошибкой и сказать, что с ней не так?
Dockerfile Я использую:
FROM node
ENV HOME=/app
RUN mkdir /app
ADD package.json $HOME
WORKDIR $HOME
RUN npm i -g @adonisjs/cli && npm install
CMD ["npm", "start"]
докер-compose.yaml
version: Ɖ.3'
services:
adonis-mysql:
image: mysql:5.7
ports:
- :3306'
volumes:
- $PWD/data:/var/lib/mysql
environment:
MYSQL_USER: ${DB_USER}
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_RANDOM_ROOT_PASSWORD: 1
networks:
- api-network
adonis-api:
container_name: "${APP_NAME}-api"
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/app
- /app/node_modules
ports:
- "3333:3333"
depends_on:
- adonis-mysql
networks:
- api-network
networks:
api-network:
Всего 2 ответа
В вашем Dockerfile отсутствует шаг COPY
чтобы фактически скопировать код вашего приложения в изображение. Когда вы docker run
образ, нет исходного кода для запуска, и вы получаете сообщение об ошибке.
Ваш Dockerfile должен выглядеть так:
FROM node
WORKDIR /app # creates the directory; no need to set $HOME
COPY package.json package.lock .
RUN npm install # all of your dependencies are in package.json
COPY . . # actually copy the application in
CMD ["npm", "start"]
Теперь, когда ваш образ Docker является автономным, вам не нужны volumes:
которые пытаются внедрить в него содержимое хоста. Вы также можете смело полагаться на некоторые настройки Docker Compose по умолчанию (сеть по default
и сгенерированное имя_ container_name:
оба прекрасно подходят для использования). Более простой docker-compose.yml
выглядит так
version: Ɖ.3'
services:
adonis-mysql:
image: mysql:5.7
# As you have it, except delete the networks: block
adonis-api:
build: . # this directory is context:, use default dockerfile:
ports:
- "3333:3333"
depends_on:
- adonis-mysql
В наборе артефактов и команд, которые вы показываете, есть несколько ключевых проблем:
docker run
и docker-compose ...
- это отдельные команды. В показанной вами команде docker run
образ запускается как есть, с командой по умолчанию, без смонтированных томов и без опубликованных портов. docker run
не знает о файле docker-compose.yml
, поэтому любые параметры, которые вы там указали, не будут иметь docker-compose.yml
эффекта. Вы можете иметь в виду docker-compose up
, который также запустит базу данных. (В вашем приложении не забудьте попробовать несколько раз, чтобы оно появилось, часто это может занять 30-60 секунд.)
Если вы планируете нажать на изображение, вам нужно включить исходный код. По сути, вы создаете два отдельных артефакта в этой настройке: образ Docker с Node и некоторыми библиотеками, а также приложение Javascript на вашем хосте. Если вы docker push
изображение в Docker, оно не будет включать приложение (потому что вы не COPY
его), поэтому вам также придется отдельно распространять исходный код. На этом этапе использование Docker не приносит большой пользы; конечный пользователь может также установить Node, клонировать ваш репозиторий и запустить npm install
самостоятельно.
Вы запрещаете Docker видеть обновления библиотеки. node_modules
в анонимном томе, кажется, является популярной установкой, и Docker будет копировать содержимое из образа в этот каталог при первом запуске приложения. Во второй раз, когда вы запускаете приложение, Docker видит, что каталог уже существует, предполагает, что он содержит ценные пользовательские данные, и отказывается обновлять его. Это приводит к таким вопросам, как «я обновил свой файл package.json
но мой контейнер не обновляется».
Ваш файл docker-compose.yaml имеет две службы:
Только второй элемент использует текущий файл Docker. Как видно из следующего раздела:
build:
context: .
dockerfile: Dockerfile
docker build .
командной docker build .
создаст образ только в текущем файле докера aka adonis-api. И тогда он запускается.
Поэтому, скорее всего, это может быть отсутствующий сервис mysql, который выдает ошибку. Вы можете проверить, запустив
docker ps -aq
проверить, запущен ли контейнер sql. Надеюсь, это поможет.
Вывод: используйте docker-compose.