Quiero crear una imagen de Docker que ejecutará mi aplicación node.js. Estoy usando el paquete dotenv npm para almacenar variables de entorno. El .env se encuentra en la raíz del proyecto. Cuando ejecuto mi script npm que inicia la aplicación ( npm run start_in_docker ) desde la máquina host, todo funciona perfectamente. Sin embargo, cuando ejecuto el contenedor Docker, aparece el siguiente error:
internal/modules/cjs/loader.js:584 throw err; ^ Error: Cannot find module 'dotenv' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:582:15) at Function.Module._load (internal/modules/cjs/loader.js:508:25) at Module.require (internal/modules/cjs/loader.js:637:17) at require (internal/modules/cjs/helpers.js:22:18) at Object.<anonymous> (/usr/src/app/src/server/main.js:3:1) at Module._compile (internal/modules/cjs/loader.js:701:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10) at Module.load (internal/modules/cjs/loader.js:600:32) at tryModuleLoad (internal/modules/cjs/loader.js:539:12) at Function.Module._load (internal/modules/cjs/loader.js:531:3)Este es mi Dockerfile:
FROM node:10-alpine # Create app directory WORKDIR /usr/src/app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) COPY package*.json ./ RUN apk add --update python RUN apk add --update vim RUN apk add --update sqlite RUN npm install --only=production # Bundle app source COPY . . EXPOSE 3000 RUN npm install --unsafe-perm=true sqlite3 -g RUN npm install pm2 -g # run node-gyp to build sqlite3 RUN cd /usr/src/app/node_modules/sqlite3 && npm run install WORKDIR /usr/src/appEste es mi archivo docker-compose.yml que ejecuta el Dockerfile anterior:
version: '3' services: appstore-bl-server: container_name: appstore-bl-server-production build: dockerfile: Dockerfile-prod context: . volumes: - ".:/usr/src/app" ports: - "3000:3000" networks: - appstore-net command: npm run start_in_docker networks: appstore-net: driver: bridgeEsta es mi sección de scripts de package.json:
"scripts": { "start_in_docker": "NODE_ENV=development DEBUG=server:*,classes:*,middleware,utils node src/server/main.js", } y así es como requiero dotenv en mi archivo main.js:
require('dotenv').config(); Intenté especificar la ruta absoluta en ('dotenv').config() pero no funcionó. Lo extraño es que si ejecuto el shell del contenedor ( docker run -it myimage /bin/ash ) y luego ejecuto npm run start_in_docker , también funcionará. dotenv está en mi paquete.json, por supuesto.
Creo que esto es causado por:
volumes: - ".:/usr/src/app" en su archivo docker-compose. Esto vincula el directorio actual con la carpeta de la aplicación, lo que significa que se reemplaza todo, incluido node_modules .
Intente eliminar los volúmenes de docker-compose y vea si funciona.
Cuando ejecuta docker run -it myimage /bin/sh , no vinculará el volumen, lo que significa que usará los node_modules correctos, razón por la cual funciona cuando se usa eso.