I have been working on my local machine with no issue using the Dokerfile
below and docker.compose.ylm
Dokerfile
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5000
CMD [ "npm", "start" ]
compose file
...
app:
build:
context: .
dockerfile: Dockerfile
container_name: app
restart: always
image: nodeapp
ports:
- 5000:5000
volumes:
- ./:/app
- /app/node_modules
networks:
- pnet
...
When I use docker context
to switch to remote host
docker context create --docker "host=ssh://root@hostname" remote
and
docker context use remote
and run docker compose up
I end up with the error
npm ERR! code ENOENT api | npm ERR! syscall open api | npm ERR! path /app/package.json paylign_api | npm ERR! errno -2 api | npm ERR! enoent ENOENT: no such file or directory, open '/app/package.json' api | npm ERR! enoent This is related to npm not being able to find a file. api | npm ERR! enoent api | api | npm ERR! A complete log of this run can be found in: api | npm ERR! /root/.npm/_logs/2022-07-01T14_33_58_429Z-debug.log
How can I fix this so as to deploy to remote host
CodePudding user response:
The volumes:
are always interpreted by the Docker daemon running the container. If you're using contexts to point at a remote Docker daemon, the volumes:
named volumes and file paths are interpreted by that remote daemon, and point at files on the remote host.
While docker build
will send the local build context to a remote Docker daemon, volumes:
cannot be used to copy files between hosts.
The straightforward solution here is to delete the volumes:
from your Compose setup:
version: '3.8'
services:
app:
build: .
restart: always
ports:
- 5000:5000
# volumes: will cause problems
# none of the other options should be necessary
# (delete every networks: block in the file)
Then when you docker-compose build
the image, the builder mechanism will send your local file tree to the remote Docker daemon. When you then run docker-compose up
the remote Docker will use the code built into the image, and not try to overwrite it with content on the remote system.
This same principle applies in other contexts that don't necessarily involve a second host; for example, if you're launching a container from inside another container using the host's Docker daemon, volume mounts are in the host and not the container filesystem. In general I'd recommend not trying to overwrite your application code with volumes:
mounts; run the code that's actually built into the image instead, and use local non-Docker tooling for live development.