Reputation: 11984
I am trying to dockerize a microservice-based application. The api
is built with nestjs and MySQL. The following is the directory structure
.
├── docker-compose.yml
├── api
│ ├── src
│ ├── Dockerfile
│ ├── package.json
│ ├── package-lock.json
│ ├── ormconfig.js
│ └── .env
├── payment
│ ├── src
│ ├── Dockerfile
│ ├── package.json
│ └── package-lock.json
├── notifications
│ ├── src
│ ├── Dockerfile
│ ├── package.json
│ └── package-lock.json
└
The following is the Dockerfile inside the api
directory
FROM node:12.22.3
WORKDIR /usr/src/app
COPY package*.json .
RUN npm install
CMD ["npm", "run", "start:dev"]
The below is the docker-compose.yml
file. Please note that the details for payment & notifications are not added yet in the docker-compose file.
version: '3.7'
networks:
server-network:
driver: bridge
services:
api:
image: api
build:
context: .
dockerfile: api/Dockerfile
command: npm run start:dev
volumes:
- ".:/usr/src/app"
- "/usr/src/app/node_modules"
networks:
- server-network
ports:
- '4000:4000'
depends_on:
- mysql
mysql:
image: mysql:5.7
container_name: api_db
restart: always
environment:
MYSQL_DATABASE: api
MYSQL_ROOT_USER: root
MYSQL_PASSWORD: 12345
MYSQL_ROOT_PASSWORD: root
ports:
- "3307:3306"
volumes:
- api_db_db:/var/lib/mysql
networks:
- server-network
volumes:
api_db:
Now, when I try to start the application using docker-compose up
I'm getting the following error.
no such file or directory, open '/usr/src/app/package.json'
UPDATE
Tried removing the volumes and it didn't help too. Also, try to see what is there in the api
by listing the contents of the directory by running
docker-compose run api ls /usr/src/app
and it shows the following contents in the folder
node_modules package-lock.json
Any help is much appreciated.
Upvotes: 3
Views: 2307
Reputation: 159975
Your build: { context: }
directory is set wrong.
The image build mechanism uses a build context to send files to the Docker daemon. The dockerfile:
location is relative to this directory; within the Dockerfile, the left-hand side of any COPY
(or ADD
) directives is always interpreted as relative to this directory (even if it looks like an absolute path; and you can't step out of this directory with ..
).
For the setup you show, where you have multiple self-contained applications, the easiest thing is to set context:
to the directory containing the application.
build:
context: api
dockerfile: Dockerfile # the default value
Or, if you are using the default value for dockerfile
, an equivalent shorthand
build: api
You need to set the build context to a parent directory if you need to share files between images (see How to include files outside of Docker's build context?). In this case, all of the COPY
instructions need to be qualified with the subdirectory in the combined source tree.
# Dockerfile, when context: .
COPY api/package*.json ./
RUN npm ci
COPY api/ ./
You should not normally need the volumes:
you show. These have the core effect of (1) replacing the application in the image with whatever's on the local system, which could be totally different, and then (2) replacing its node_modules
directory with a Docker anonymous volume, which will never be updated to reflect changes in the package.json
file. In this particular setup you also need to be very careful that the volume mappings match the filesystem layout. I would recommend removing the volumes:
block here; use a local Node for day-to-day development, maybe configuring it to point at the Docker-hosted database.
If you also remove things that are set in the Dockerfile (command:
) and things Compose can provide reasonable defaults for (image:
, container_name:
, networks:
) you could reduce the docker-compose.yml
file to:
version: '3.8'
services:
api: # without volumes:, networks:, image:, command:
build: api # shorthand corrected directory-only form
ports:
- '4000:4000'
depends_on:
- mysql
mysql: # without container_name:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: api
MYSQL_ROOT_USER: root
MYSQL_PASSWORD: 12345
MYSQL_ROOT_PASSWORD: root
ports:
- "3307:3306"
volumes:
- api_db:/var/lib/mysql
volumes:
api_db:
Upvotes: 1