I created a Dockerfile for a nodejs project. It contains a package.json with many scripts.
"scripts": {
"start": "npm run",
"server": "cd server && npm start",
"generator": "cd generator && npm start",
...
},
I need to run server
and genberator
in my docker image. How to achieve this?
I tried:
CMD ls;npm run server; npm run generator
CMD ls;npm run server; npm run generator
this won't find the package json because shellform seems to run within /bin/sh -c
.
CMD ["npm","run","server"]
is also not working and is missing the 2nd command
The ls in first try showed me that all files are in place (incl. the package.json).
For sake of completeness the project in question is https://github.com/seekwhencer/node-bilder-brause (not mine). the current Dockerfile:
FROM node:14
# Create app directory
WORKDIR /usr/src/app
# Bundle app source
COPY ./* ./
RUN npm install
EXPOSE 3050
EXPOSE 3055
CMD ls ; npm run server ; npm run generator
The typical way to run multiple commands in a CMD
or ENTRYPOINT
is to write all of the commands to a file and then run that file. This is demonstrated in the Dockerfile below.
This Dockerfile also install imagemagick, which is a dependency of the package OP is trying to use. I also changed the base image to node:14-alpine
because it is much smaller than node:14
but works just as well for this purpose.
FROM node:14-alpine
# Install system dependencies for this package.
RUN apk add --no-cache imagemagick
# Create app directory
WORKDIR /usr/src/app
# Bundle app source
COPY . .
RUN npm install \
# Install server and generator.
&& npm run postinstall \
# Write entrypoint.
&& printf "ls\nnpm run server\nnpm run generator\n" > entrypoint.sh
EXPOSE 3050
EXPOSE 3055
CMD ["/bin/sh", "entrypoint.sh"]
docker build --tag nodebilderbrause .
docker run --rm -it nodebilderbrause
The contents of entrypoint.sh
are written in the Dockerfile. Here is what the file would look like.
ls
npm run server
npm run generator
I found another way, adding for sake of completeness and reference for me: https://www.npmjs.com/package/concurrently
adding
RUN npm install -g concurrently
enables:
CMD ["concurrently","npm:server", "npm:generator"]
If you need to run two separate processes, the typical approach is to run two separate containers. You can run both containers off the same image; it's very straightforward to override the command part of a container when you start it.
You need to pick something to be the default CMD
. Given the package.json
you show, for example, you can specify
CMD npm start
When you actually go to run the container, you can specify an alternate command: anything after the image name is taken as the command. (If you're using Docker Compose, specify command:
.) A typical docker run
setup might look like:
docker build -t bilder-brause .
docker network create photos
docker run \
--name server \
--net photos \
-d \
-p 3050:3050 \
bilder-brause \
npm run server
docker run \
--name generator \
--net photos \
-d \
-p 3055:3055 \
bilder-brause \
npm run generator
You could build separate images for the different components with separate EXPOSE
and CMD
directives if you really wanted
FROM bilder-brause
EXPOSE 3050
CMD npm run server
Building these is a minor hassle; there is no way to specify in Compose that one local image is built FROM
another so the ordering might not turn out correctly, for example.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.