Home > Back-end >  Can not copy local directory to remote container with docker using docker context
Can not copy local directory to remote container with docker using docker context

Time:07-02

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.

  • Related