I'm using Docker Compose for a React/Express application.
Dockerfile for the server:
FROM node:latest
WORKDIR /app/server
COPY package.json /app/server
COPY package-lock.json /app/server
RUN npm install
COPY . /app/server
CMD [ "npm", "run", "dev" ]
Dockerfile for the client:
FROM node:latest
WORKDIR /app/client
COPY package.json /app/client
COPY package-lock.json /app/client
RUN npm install
COPY . /app/client
CMD [ "npm", "start" ]
And my docker-compose file:
version: '3'
services:
server:
build: ./server
expose:
- "3001"
ports:
- "3001:3001"
volumes:
- ./server/src/:/app/server
command: npm run dev
tty: true
client:
build: ./client
expose:
- "3000"
ports:
- "3000:3000"
volumes:
- ./client/src/:/app/client
links:
- server
command: npm run start
tty: true
After running "docker-compose up" the server crashes:
npm ERR! Missing script: "dev"
However, I DO have a "dev" script inside my package.json:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon index.js",
"start": "node index.js"
},
What is the problem here? The script is there. Is there something wrong with my Docker files? "npm run dev" works just fine without Docker.
Thanks!
When your docker-compose.yml file says
volumes:
- ./server/src/:/app/server
this hides everything the Dockerfile did in the /app/server directory and replaces it with the contents of that host directory. Since the only things your Dockerfile does are in the /app/server directory, you're essentially not using your Docker image at all.
I'd generally recommend removing these volumes:, along with some other unnecessary options. (You do not need to expose: ports in Compose pretty much ever; you do not need to repeat the command: from the image; links: are obsolete networking setup.) You can reduce the file to just
version: '3.8'
services:
server:
build: ./server
ports:
- "3001:3001"
client:
build: ./client
ports:
- "3000:3000"
If you do include volumes:, you need to make sure that the layout of the mounted content exactly matches what's supposed to be in the container. (Try running docker-compose run server ls with and without the volumes: line.) Here you're building the image from the ./server directory, but then mounting its src subdirectory over the whole application. It may work better to mount it only on the src subdirectory inside the container too
volumes:
- ./server/src:/app/server/src
Hmm, apparently, Docker can't find a package.json file that includes a dev script.
My first suggestion would be to ensure that package.json is in the root folder of the project, at the same folder level as the docker-compose.yml.
Related
I'm dockerizing an api container and want it to be able to hot reload whenever I make change in code. I created a volume to handle it but nothing happen.
Here's my docker-compose.yml file:
version: "3.8"
services:
api:
image: xinxo-api:latest
build: ./api
ports:
- "5005:5005"
networks:
- xinxo-network
volumes:
- apibuild:/app/api/build
depends_on:
- db
- redis
env_file:
- ./api/.env
restart: always
networks:
xinxo-network:
driver: bridge
volumes:
pgdata:
cache:
staticbuild:
apibuild:
Here's my Dockerfile
FROM node:16-bullseye-slim
WORKDIR /app/api/build
COPY package*.json ./
COPY yarn.lock ./
COPY tsconfig.json ./
COPY ./prisma prisma
RUN yarn
RUN yarn prisma generate
COPY . .
EXPOSE 5005
CMD ["yarn", "start"]
I only have a screen shot of my package.json file.
I have fixed this issue already by changing 2 places:
docker-compose:
volumes:
apibuild:/app/api/build -> ./api:/app/api/build
My start script in package.json
"start": "ts-node-dev --poll --respawn --transpile-only --exit-child --no-notify --ignore-watch node_modules -r tsconfig-paths/register src/app.ts"
I am creating a docker container on my ec2 instance.
When I run docker-compose up --build, container test-web is not created successfully.
I tried to run docker logs test-web and see the logs, then I see below error
sh: nodemon: not found
I tried to add nodemon dependency on package.json and run docker-compose up --build again but still not working.
Dockerfile
FROM node:lts-alpine
WORKDIR /server
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3030
CMD ["npm", "run", "dev"]
docker-compose.yml
version: '2.1'
services:
test-db:
image: mysql:5.7
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=true
- MYSQL_USER=admin
- MYSQL_PASSWORD=12345
- MYSQL_DATABASE=test
volumes:
- ./db-data:/var/lib/mysql
ports:
- 3306:3306
test-web:
environment:
- NODE_ENV=local
#- DEBUG=*
- PORT=3030
build: .
command: >
./wait-for-db-redis.sh test-db npm run dev
volumes:
- ./:/server
ports:
- "3030:3030"
depends_on:
- test-db
package.json
"scripts": {
"dev": "nodemon --legacy-watch src/",
},
I add RUN npm install --global nodemon in Dockerfile and it works now.
Dockerfile
FROM node:lts-alpine
RUN npm install --global nodemon
WORKDIR /server
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3030
CMD ["npm", "run", "dev"]
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'm using a Docker-compose to initialize ExpressJS + VueJS and the RestFull API
This is docker compose:
version: '3'
services:
webserver:
build: ./webserver
ports:
- "3000:3000"
container_name: boleto_webserver
networks:
- boleto
volumes:
- ./webserver:/app/webserver
- /app/webserver/node_modules
website:
build: ./website
ports:
- "8080:8080"
container_name: boleto_website
networks:
- boleto
volumes:
- ./website:/app/website
- /app/webiste/node_modules
api:
build: ./api
ports:
- "3030:3030"
container_name: boleto_api
networks:
- boleto
volumes:
- ./api:/app/api
- /app/api/node_modules
networks:
boleto:
external: true
name: boleto
In DockerFile inside Website (VueJS) I run a production build:
FROM node:12
WORKDIR /app/website
COPY package*.json ./
COPY . /app/website
RUN npm install
COPY . .
EXPOSE 8080
CMD ["npm","run","build"]
Browsing localhost:3000 here is where the webserve is being launched I have this message:
Error: ENOENT: no such file or directory, stat '/app/website/build/index.html'
Analyzing website logs:
Note that the development build is not optimized.
To create a production build, run npm run build.
If I run this applications separately, all them works well! Throwing inside a docker compose this happens! Anyone can help me?
Updating
The webserver insists on run script dev, if I remove it, it does not compile
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"serve": "nodemon app.js",
"dev": "nodemon app.js"
},
FROM node:12
WORKDIR /app/webserver
COPY package*.json ./
COPY . /app/webserver
RUN npm install && npm install nodemon
EXPOSE 3000
CMD ["npm","run","serve"]
I am using the docker integration tool to run docker-compose to start two containers, one for node and one for mongodb.
Here is the docker-compose.yml file:
version: '2.1'
services:
mongo:
container_name: "app_mongo"
hostname: "mongo"
tty: true
image: mongo:latest
environment:
- MONGO_DATA_DIR=/data/db
- MONGO_LOG_DIR=/dev/null
- MONGO_INITDB_DATABASE=***********
- MONGO_INITDB_ROOT_USERNAME=************
- MONGO_INITDB_ROOT_PASSWORD=********************
volumes:
- /data/db:/data/db
ports:
- 27017:27017
command: "mongod --smallfiles --auth"
networks:
- my-app-network
group:
container_name: "app_api1"
hostname: "api1"
build:
context: .
dockerfile: api1.dev.yml
entrypoint: ["npm", "run", "debug"]
volumes:
- ".:/home/app"
ports:
- 3000:3000
- 56745:56745
depends_on:
- "mongo"
networks:
- my-app-network
networks:
my-app-network:
driver: bridge
Here is the api1.dev.yml file:
FROM node:latest
ADD package.json /tmp/package.json
RUN cd /tmp && npm install --production && npm install -g nodemon
RUN mkdir -p /home/app && cp -a /tmp/node_modules /home/app/ && mkdir -p /home/app/dist
ADD package.json /home/app/package.json
ADD .env /home/app/.env
WORKDIR /home/app
Here is the script entry in package.json:
"scripts": {
"debug": "nodemon --inspect=56745 --require ts-node/register app/app.ts"
// "debug": "nodemon -L --inspect=56745 dist/myapp/app.js"
}
I also added a new "Attach to Node.js/Chrome" item to attach to the debugging port for node.
I run the docker-compose file followed by debugging the "Attach to Node.js/Chrome" item after node is up and listening.
When I try to hit a breakpoint in a .ts file, nothing is happening. I am seeing the endpoint is called.
What are the steps involved in debugging a typescript app from docker and what am I doing wrong?
Where can I find a good tutorial that walks through how to debug typecript for a node.js app hosted inside of a docker container?
An answer was finally provided to me. Ultimately, I had to change the debug script from "debug": "nodemon -L --inspect=56745 dist/myapp/app.js" to "nodemon -L --inspect=0.0.0.0:56745 dist/myapp/app.js".