I developed a React UI named frontend for a project on a mac:
myproject
├── frontend
│ ├── README.md
│ ├── dev.frontend.dockerfile
│ ├── docker-compose.yml
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── src
│ └── tsconfig.json
From /frontend, I can:
- use
dockerto build an image and run/create a container - use
docker composeto run frontend as a service.
Both work fine!
dev.frontend.dockerfile
FROM node:20-alpine
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY public /app/public
COPY package.json /app
COPY package-lock.json /app
RUN npm install
COPY . ./
RUN pwd && ls -ltra
RUN ls -ltra public
CMD ["npm", "start"]
docker-compose.yml
version: '1.0'
services:
frontend:
container_name: frontend
build:
context: .
dockerfile: dev.frontend.dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- 3001:3000
environment:
- CHOKIDAR_USEPOLLING=true
My goal is to run all services under /myproject with docker compose as I pull other services in. As a first step, I tried moving the docker-compose.yml file up one level to /myproject:
myproject
├── docker-compose.yml <--- moved up
├── frontend
│ ├── README.md
│ ├── dev.frontend.dockerfile
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── src
│ └── tsconfig.json
└── node_modules <--- created during build - huh?
docker-compose.yml at /myproject:
services:
frontend:
container_name: frontend
build:
context: ./frontend <--- only change
dockerfile: dev.frontend.dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- 3001:3000
environment:
- CHOKIDAR_USEPOLLING=true
I only updated the build context. My expectation was that making that one change would tell compose where the frontend service dockerfile was and in which context to build that service, i.e., /frontend. But when I ran it, it returned the error below:
% docker compose up --build --force-recreate
[+] Building 20.3s (15/15) FINISHED
=> [internal] load build definition from dev.frontend.dockerfile 0.0s
=> => transferring dockerfile: 303B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 95B 0.0s
=> [internal] load metadata for docker.io/library/node:20-alpine 1.4s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 1.47MB 0.0s
=> [1/9] FROM docker.io/library/node:20-alpine@sha256:8e015de364a2eb2ed7c52a558e9f716dcb615560ffd132234087c10ccc1f2c63 2.5s
=> => resolve docker.io/library/node:20-alpine@sha256:8e015de364a2eb2ed7c52a558e9f716dcb615560ffd132234087c10ccc1f2c63 0.0s
=> => sha256:7035a9761f602cac8176359dccbac6a752b4da17f56dab1a144a04d9f122cf95 2.34MB / 2.34MB 0.3s
=> => sha256:8e015de364a2eb2ed7c52a558e9f716dcb615560ffd132234087c10ccc1f2c63 1.43kB / 1.43kB 0.0s
=> => sha256:12a9b2ab331c96e57763a15336c1360002d3a2fbca1f6fdc0334581bca20dbea 1.16kB / 1.16kB 0.0s
=> => sha256:1e9578ee4112c5d9884fe0e6adcaf0cf6cf71d9a70f2e68aa0a8ff12f9e1f7d5 6.79kB / 6.79kB 0.0s
=> => sha256:579b34f0a95bb83b3acd6b3249ddc52c3d80f5c84b13c944e9e324feb86dd329 3.33MB / 3.33MB 0.2s
=> => sha256:2b81652d645d4a1301c33f155cdeeb9189182cc89dc4d7e65d7b164a43389dbd 50.03MB / 50.03MB 1.2s
=> => extracting sha256:579b34f0a95bb83b3acd6b3249ddc52c3d80f5c84b13c944e9e324feb86dd329 0.1s
=> => sha256:ccca1742947cf696d50b5e5197157a7aa16a1bf9a9edaefef3db2e10c6da7c41 448B / 448B 0.5s
=> => extracting sha256:2b81652d645d4a1301c33f155cdeeb9189182cc89dc4d7e65d7b164a43389dbd 1.0s
=> => extracting sha256:7035a9761f602cac8176359dccbac6a752b4da17f56dab1a144a04d9f122cf95 0.1s
=> => extracting sha256:ccca1742947cf696d50b5e5197157a7aa16a1bf9a9edaefef3db2e10c6da7c41 0.0s
=> [2/9] WORKDIR /app 0.2s
=> [3/9] COPY public /app/public 0.0s
=> [4/9] COPY package.json /app 0.0s
=> [5/9] COPY package-lock.json /app 0.0s
=> [6/9] RUN npm install 12.9s
=> [7/9] COPY . ./ 0.0s
=> [8/9] RUN pwd && ls -ltra 0.1s
=> [9/9] RUN ls -ltra public 0.3s
=> exporting to image 2.7s
=> => exporting layers 2.7s
=> => writing image sha256:1c386e305c2799f6dda7aad00b243f5ef6ebd614d680aefaac9599395add1517 0.0s
=> => naming to docker.io/library/timeshare-frontend 0.0s
[+] Running 2/2
⠿ Network timeshare_default Created 0.0s
⠿ Container frontend Created 3.1s
Attaching to frontend
frontend | npm ERR! code ENOENT
frontend | npm ERR! syscall open
frontend | npm ERR! path /app/package.json
frontend | npm ERR! errno -2
frontend | npm ERR! enoent Could not read package.json: Error: ENOENT: no such file or directory, open '/app/package.json'
frontend | npm ERR! enoent This is related to npm not being able to find a file.
frontend | npm ERR! enoent
frontend |
frontend | npm ERR! A complete log of this run can be found in: /root/.npm/_logs/2023-11-15T13_41_32_726Z-debug-0.log
frontend exited with code 254
I saw tickets like this, but did not help.
How do I fix this build?
side note: I did not expect node_modules to be created in /myproject
volumes:block. Since your image already contains the application code, there's no need to overwrite it with a bind mount.