I'm trying to set up a unit test run time through docker compose. When I try to run an npm script through docker-compose Node is acting like it can't find the modules on the path:
➜ docker-compose run --rm server npm run test
Starting redis ... done
Starting mongodb ... done
> evolved#1.0.0 test /server
> mocha --recursive tests
sh: mocha: not found
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! evolved#1.0.0 test: `mocha --recursive tests`
npm ERR! spawn ENOENT
I've confirmed that the files are being mounted into the container, so why can't Node find them?
➜ dc run --rm --service-ports server ls node_modules/.bin | grep "mocha"
Starting redis ... done
_mocha mocha
The script in my package.json are very basic:
"test": "mocha --recursive tests",
"build": "gulp default:dev",
docker-compose.yml
version: '3' #compose version
services:
server:
build:
context: .
dockerfile: Dockerfile.test
ports:
- "3000:3000"
volumes:
- ".:/server"
working_dir: "/server"
depends_on:
- mongodb
- redis
environment:
PORT: 3000
NODE_ENV: test
mongodb:
image: mongo:latest
container_name: "mongodb"
environment:
- MONGO_DATA_DIR=/data/db
- MONGO_LOG_DIR=/dev/null
volumes:
- ./localdata/db:/data/db
ports:
- 27017:27017
command: mongod --smallfiles --logpath=/dev/null # --quiet
redis:
container_name: redis
command: redis-server --requirepass testredispassword
image: redis
ports:
- "6379:6379"
volumes:
- ./localdata/redis:/data
entrypoint: redis-server --appendonly yes
restart: always
The Dockerfile.test is different than the prod dockerfile in that it doesn't install / build the front end of the app or pass in any versioning info. I'm trying to make it build quicker with just what it needs to run the unit tests for the server:
FROM node:8-alpine
RUN apk update \
&& apk --update --no-cache add \
git \
python \
build-base
ADD ./ /server WORKDIR /server
RUN rm -rf node_modules && npm install && npm run build
I think this is all pretty straight forward and I've done similar set ups before but on Docker for Mac. This time I'm running Docker For Windows and running the commands through WSL. I've got the drives shared and bound /mnt/c to /c.
For another reference this project I can run the unit tests on Docker for Mac, but get the same sh: mocha: not found when running it through WSL connected to Docker for Windows on Windows 10. It seems to be just the path to the binaries node_modules/.bin that's not found because I can start the project up without any errors, it just can't find any binaries like mocha, nsp, gulp etc...
Sounds like this is similar to a path issue I've experienced with a windows/wsl environment. Try changing your volume definition to the full path and see if that solves it.
volumes:
- /c/Users/username/Code/server:/server
Even though you've copied the files into the container with the Dockerfile, when mounting a volume with docker-compose, it doesn't really care about that. You essentially change the mapping of the source of the directory.
I encountered a similar situation and it had to do with symlink creation in WSL/Docker. According to this Github issue reported to MS, all you should have to do is enable Developer Mode in the system settings.
Edit:
This Microsoft article describes how to enable developer mode on your Windows 10 machine.
Related
I am trying to dockerize nestjs application. I have to use approach of our devops, so I can't give all details of configuration.
Scripts in package.json typical for any nestjs application.
I have Dockerfile.backend:
FROM some.registry.net/docker/node16 as builder
WORKDIR /opt/app
COPY --chown=app:app ./nestjs/nest-project .
RUN yarn install --non-interactive --production --frozen-lockfile
FROM some.registry.net/docker/node16 as serve
WORKDIR /opt/app
ENV NODE_ENV=production
ENV APP_CONFIG=/opt/app/config/config.yaml
COPY --chown=app:app ./build/Procfile /opt/startup/Procfile
COPY --chown=app:app ./build/config.yaml ./config/config.yaml
COPY --chown=app:app --from=builder /opt/app/ ./
COPY --chown=app:app --from=builder /opt/app/node_modules ./node_modules
USER root
##RUN npm install pm2 -g
##RUN npm install -g nodemon
RUN npm run build
CMD ["/opt/startup/entrypoint.sh"]
And I have docker-compose.yml file:
version: "2"
services:
backend:
build:
context: .
dockerfile: ./build/Dockerfile.backend
command: npm run start
##volumes:
##- ./nestjs/nest-project:/app
##- /app/node_modules
ports:
- 4001:4001
- 9229:9229
environment:
- NODE_ENV=development
- PORT=4001
- REACT_APP_PROD=0
- REACT_APP_BACKEND_URL=http://127.0.0.1:4001
- FRONTEND_URL=http://localhost:4000
- APP_CONFIG=/opt/app/config/config.yaml
frontend:
build: ./frontend
command: npm start
##volumes:
##- ./frontend:/app
##- /app/node_modules
environment:
- NODE_ENV=development
- DISABLE_ESLINT_PLUGIN=true
- REACT_APP_BACKEND_URL=http://127.0.0.1:4001/backend
- PORT=4000
- REACT_APP_PROD=0
ports:
- 4000:4000
So the most interesting point lies in backend command part. I am able to start container only with npm run start:dev command. When I enter there npm start or npm run start:prod
container executes (I see in logs that nestjs app starts, successfully connects to database) and exits without any errors. I tried node dist/main and got the same result. I tried nodemon, with nodemon dist/main nodemon, even with verbose flag shows red line something like app crashed... and gives no more information. I tried pm2 with this command pm2 --name nestjs start npm -- start pm2 successfully starts and container exits without any information.
So far I see problem lies somewhere in my configuration, but I have no clue where to seek. Thanks in advance.
I'd like to start 2 containers using docker-compose. One for the database and one for a Node server using the default node image on DockerHub. In the Node container, I'd like to mount a local folder that's source controlled as a volume. I've seen many examples where a Dockerfile is created that copies source files into the image and then a RUN npm install command is used in the Dockerfile. But that results in a new image being created with the source files in it. In my case, I don't want to save source code files in the Node image. So I'd like the entrypoint of the Node container in my docker-compose file to run npm install as well as npm start, but I can't seem to get that combination to work. Here's my docker-compose.yml:
version: "3.8"
services:
server:
container_name: my_server
image: node:12.16.1
ports:
- "8000:8000"
volumes:
- ../my-server-files-source-controlled:/var/www
working_dir: /var/www
entrypoint: ["npm", "start"]
networks:
- my-network
db:
container_name: my_database
image: postgres
environment:
{ommitted}
ports:
- "5432:5432"
networks:
- my-network
networks:
my-network:
driver: bridge
The command above works fine, but when I change the entrypoint to include npm install, it fails. I've tried the following examples, as well as many others, and they all fail:
entrypoint: ["npm", "install", "&&", "npm", "start"]
entrypoint: ["npm install", "npm start"]
entrypoint: "npm install && npm start"
It seems like I can have npm install or npm start in entrypoint, but not both. How can get both those commands to work in my docker-compose file?
If you want to use multiple commands, you can do so with bash -c "commands":
services:
myservice:
command: bash -c "npm install && npm start"
By the way, in a production deployment, I would suggest using npm ci instead of npm install. Also consider using the --only=prod and --no-audit flags (depending on your setup).
I am trying to get NestJS up and running in my container. Currently, I have this set up as my docker-compose.yml
services:
redis-cluster:
image: internal-repo.com/devops/redis-cluster:5.0.5
ports:
- 7000:7000
- 7001:7001
- 7002:7002
- 7003:7003
- 7004:7004
- 7005:7005
- 7006:7006
- 7007:7007
- 7008:7008
environment:
IP: 0.0.0.0
MASTERS: 3
SLAVES_PER_MASTER: 2
app-orders:
image: app-orders
build:
context: ..
dockerfile: $PWD/Dockerfile
working_dir: /workspace
depends_on:
- 'redis-cluster'
environment:
NODE_ENV: development
volumes:
- ..:/workspace
ports:
- 50099:9229
- 3000:3000
command: /bin/sh -c "while sleep 1000; do :; done"
I have this for my Dockerfile
FROM internal-repo.com/devops/node/ubuntu-1804:12.16.2 as build-env
ENV NODE_VERSION 12.16.2
WORKDIR /workspace
RUN apt-get update && apt install python -y
# Ensure the image timezone mirrorsCorp HQ
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY .devcontainer/library-scripts/docker-debian.sh /tmp/library-scripts/
COPY package.json package.json
RUN npm i -g nodemon
RUN npm i -g #nestjs/cli
RUN npm install
# App specific environment
ENV PACKAGE_JSON_PATH ../package.json
I have set my docker to run the sleep command so I can start this container and run an interactive shell with it. If i tried to put the npm command as the run, it would just crash after a few minutes.
In an interactive shell, I have tried running npm start:dev which uses rimraf to remove the dist folder and then run nest start --watch. The problem is, it will run for a little bit, generate the new dist folder and then promptly die. It only says in the npm log Error 147. If i try to run the nest start --watch manually, it sits for a little bit saying 'Starting compilation in Watch Mode' and just says "Killed". I don't know why it is failing or what to fix.
The odd thing is, if I don't try and run it in the container, it will run fine on my mac (assuming i have the redis cluster up and running already in a container)
The build folder is ready to be deployed.
You may serve it with a static server:
serve -s build
---> b252a9088991
Removing intermediate container cb5c1e2629c9
Step 16/16 : RUN serve -s build
---> Running in c27b54b31108
serve: Running on port 5000
created and dockerized react application using react-app and getting output like above on "docker-compose up" command
but nothing is showing on http://0.0.0.0:5000/ or http://localhost:5000/
version: '3'
services:
web:
build: .
image: react-cli
container_name: react-cli
volumes:
- .:/app
ports:
- '3000:3000'
above my docker-compose.yml file
FROM scratch
FROM mhart/alpine-node:6.12.0
RUN npm install -g npm --prefix=/usr/local
RUN ln -s -f /usr/local/bin/npm /usr/bin/npm
CMD [ "/bin/sh" ]
ENV NPM_CONFIG_LOGLEVEL warn
RUN npm install -g serve
CMD serve -s build
EXPOSE 3000
COPY package.json package.json
COPY semantic.json semantic.json
COPY npm-shrinkwrap.json npm-shrinkwrap.json
RUN npm install gulp-header --save-dev
RUN npm install --no-optional
COPY . .
RUN npm run build --production
RUN serve -s build
and this is my Dockerfile
Most likely you are not exposing container port on host. I don't see how your compose file looks, but you probably need to add
ports:
- "5000:5000"
To your container definition in compose file.
From this documentation, it seems like that I can execute a single command from a service like this:
docker-compose run SERVICE CMD
But when I run
docker-compose up pwa npm test
I get the error
ERROR: No such service: npm
From my configurations, it will execute npm start, but I'd like to know how to execute other commands.
Files
Dockerfile:
From node:8
WORKDIR /app
copy package.json /app/
RUN npm install --quiet
CMD npm start
docker-compose.yml:
version: '3'
services:
pwa:
build: .
ports:
- '3000:3000'
volumes:
- ./src:/app/src
- ./public:/app/public
Versions
Docker version: 17.03
Docker compose version: 1.11.2
As docs say, the command is docker-compose run, not docker-compose up. The later expects all service names.
Do as this:
docker-compose run pwa npm test