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).
Related
I generated a Gatsby website localy. Then I setup a Docker container to run it. It's a standard setup : copying package.json, installing the modules, copying the local files and starting the dev script with a shared volume.
But when it starts, I run into an error :
gatsby_1 | ERROR
gatsby_1 |
gatsby_1 | There was a problem loading the local develop command. Gatsby may not be installed in your site's "node_modules" directory. Perhaps you need to run "npm install"? You might need to delete your "package-lock.json" as well.
Here is the Dockerfile :
FROM node:14.11.0
RUN npm install -g gatsby-cli
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8000
CMD ["gatsby", "develop", "-H", "0.0.0.0"]
And the docker-compose.yml :
version: "3"
services:
db:
image: mariadb:latest
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- ./db:/var/lib/mysql
adminer:
image: adminer:latest
ports:
- 8082:8080
wordpress:
image: wordpress:5.5.1-php7.4-apache
ports:
- 8081:80
volumes:
- ./wordpess/plugins:/var/www/html/wp-content/plugins
- ./wordpess/themes:/var/www/html/wp-content/themes
gatsby:
build: ./gatsby
ports:
- 8080:8000
volumes:
- ./gatsby:/app
But, if I remove the volume for the Gatsby container, everything rune well.
So my guess is there's something wrong with permissions somewhere, but I can't figure it out.
Here is a repo with the whole project.
I am using Typescript here and using node:latest in Docker, and I am using docker-compose as well,
I always failed to run it with docker-compose, when I run docker run ( manual ) it was work well,
here is my Dockerfile
FROM node:latest
RUN mkdir -p /home/myapp
WORKDIR /home/myapp
RUN npm i -g prisma2
ENV PATH /home/myapp/node_modules/.bin:$PATH
COPY package.json /home/myapp/
RUN npm install
COPY . /home/myapp
RUN prisma2 lift save --name 'init'
RUN prisma2 lift up
EXPOSE 8100
RUN npm run build
RUN pwd
RUN ls
RUN ls dist
CMD node dist/server.js
and my docker-compose.yml:
version: "3"
services:
app:
environment:
DB_URI: postgres://myuser:password#postgres:5555/prod
NODE_ENV: production
build:
context: .
dockerfile: Dockerfile
depends_on:
- postgres
volumes:
- ./home/edupro/:/home/myapp/
- ./node_modules:/home/myapp/node_modules
ports:
- "8100:8100"
postgres:
container_name: postgres
image: postgres:10-alpine
ports:
- "5555:5555"
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: password
POSTGRES_DB: prod
when it finishes doing CMD node /dist/server.js ( which folder I build because I am using TYpescript )
it gets an error like this :
Cannot find module '/home/edupro/dist/server.js'
I have to try to change volumes in docker-compose.yml as well like this:
- /home/myapp/node_modules:/home/myapp/node_modules
or
- ./:/home/myapp/node_modules
but still the same. do I miss something ? or did wrong mount?
how is the correct way to resolve that?
you need to remove the volume sections from your compose since that will overwrite all the files you build in your dockerfile, so delete this:
volumes:
- ./home/edupro/:/home/myapp/
- ./node_modules:/home/myapp/node_modules
It's kind of weird, I didn't see any errors when run docker-compose build but when I access into container, I didn't see node_modules folder, just only package.json and package-lock.json files.
Any the logs when I run docker-compose build show normally. For example:
....
added 552 packages from 678 contributors and audited 4007 packages in 11.2s
found 0 vulnerabilities
....
My Dockerfile:
FROM node:10
ENV APP_PATH /app
WORKDIR $APP_PATH
COPY ./app_front/package*.json ./
RUN npm install -g ts-node typescript
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "run", "start" ]
And docker-compose file
version: "3.5"
services:
mysql:
image: mysql:5.7
container_name: racer_mysql
restart: always
environment:
MYSQL_DATABASE: xxxx
MYSQL_USER: "xxxx"
MYSQL_PASSWORD: "xxxx"
MYSQL_ROOT_PASSWORD: xxxx
ports:
- "3306:3306"
expose:
- "3306"
volumes:
- ./docker/database:/var/lib/mysql
- ./docker/mysql_init:/docker-entrypoint-initdb.d
app_front:
container_name: app_front
build:
context: .
dockerfile: ./docker/app_front/Dockerfile
volumes:
- ./app_front:/app_front
ports:
- "3000:3000"
Note:
But when I add multiple commands in docker-compose, it works. But I want to install packages in Dockerfile, not docker-compose file.
command:
- /bin/bash
- -c
- |
npm install
npm start
My problem is exactly the same with this issue, I have tried, but without success.
Any advice is welcomed!
What might be happening is COPY . . is overwriting your node_modules directory in the image. Create a .dockerignore file in the same directory as your Dockerfile and ignore node_modules.
I think you build your App in /app_front/ folder in build Process then you delete ""overwriting" all the files in that folder by using :
volumes:
- ./app_front:/app_front
in your compose , I suggest you to remove the volumes section and try again.
I created very simple docker file for my nodejs web application:
FROM node:8.11.4
FROM mysql:latest
WORKDIR /ess-explorer
COPY . .
RUN npm install
RUN cd config && cp config.json.example config.json && cp database.json.example database.json && cd ../
RUN npm run migrate
EXPOSE 3000
CMD ["npm", "dev"]
And docker.yml
version: '3'
services:
essblockexplorer:
container_name: ess-explorer
build: .
depends_on:
- db
privileged: true
ports:
- 3000:3000
- 3010:3010
db:
container_name: mysql
image: mysql
restart: always
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: '123'
volumes:
db-data:
After command docker-compose -f docker.yml build evey time I've got an error
Step 5/9 : RUN npm install
---> Running in d3644d792807
/bin/sh: 1: npm: not found
ERROR: Service 'essblockexplorer' failed to build: The command '/bin/sh -c npm install' returned a non-zero code: 127
What am i doing wrong? I found similar issues but i didnt find the real solution for solving this problem
You shouldn't need the mysql image in your Dockerfile at all; ideally your app container (essblockexplorer) accesses the db container (db) via a NodeJS client. All you need to do is;
Remove the FROM mysql:latest line from your Dockerfile.
Access the MySQL database via a NodeJS client using (db) as the hostname (this is automatically loaded as an alias into your container).
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