Home > Enterprise >  How to use properly of COPY and bind-mount
How to use properly of COPY and bind-mount

Time:07-26

When I develop sample app and read docker document and I noticed that what is the difference between COPY command and bind-mount our setting is like follows. I understood that COPY will copy local file to container at initial build time.and bind-mount will sync local directory to container directory.

it seems same functionality. so that I would like to know how to use them properly. if someone has opinion,please let me know. Thanks

docker-compose

version: "3"
services:
  form-api:
    container_name: "api"
    env_file: .env.development
    build:
      context: .
      dockerfile: ./packagesapi/Dockerfile
    tty: true
    ports:
      - 3303:3303
    depends_on:
      - dynamodb-local
      - database
    volumes:
      - ./packages/form-api/:/app/packages/form-api/
      - ./packages/infrastructure/:/app/packages/infrastructure/
      - ./packages/library/:/app/packages/library/

dockerfile

FROM node:16.10-buster
ENV LANG C.UTF-8
ENV TZ 'Asia/Tokyo'
ENV DEBCONF_NOWARNINGS=yes

# Create app directory
WORKDIR /app

RUN apt-get update && apt-get install -y postgresql-client
RUN npm install -g [email protected] serverless serverless-offline

# root
COPY .npmrc ./
COPY ./package*.json ./
COPY ./tsconfig.json ./
COPY ./tsconfig.build.json ./

COPY ./packages/library ./packages/library
COPY ./packages/infrastructure/ ./packages/infrastructure/
COPY ./packages/form-api/ ./packages/form-api/

RUN npm install

CodePudding user response:

You should delete the volumes: from your docker-compose.yml file, and make sure you COPY the application code into your image. Also don't forget to set a CMD in the Dockerfile.

One of Docker's core concepts is that an image is an immutable self-contained copy of an application. In much the same way as you don't download, say, Firefox, then separately download its source code, the image should be runnable on its own. An ideal is to be able to run

docker run --name api -d -p 3000:3000 your-image

and while this isn't always possible, in general if it's reasonable to specify things in either the Dockerfile or runtime options, putting them in the Dockerfile is preferable.

Another consideration is clustered environments like Kubernetes. There it's all but impossible to upload your source code into a volume, but very straightforward to use a Docker image as-is.

I've also seen some problems emerge where there's work being done in the Dockerfile that's hidden by a bind mount. This could be as little as a RUN chmod x that gets lost, or occasionally the image rearranges files more. If you're overwriting the image content with a bind mount, you aren't running the actual image, and you haven't tested the standard setup without the mount.

For Node applications especially, the "pattern" seems to be to overwrite the entire image content with a bind mount. But if you're doing this, then there's nothing in your custom image, and you may as well just run a node image with the bind mount. But if you're doing that, then you're more working around Docker's filesystem isolation than benefiting from it; you may as well just run Node on your host directly and not bother with this setup.

The downside with COPY is that you need to rebuild your image whenever your application code changes, even if your application doesn't otherwise need a build step. Again this is where a local environment can come in handy: Docker sometimes interferes with live-reloading setups but they'll work just fine in an actual local environment, so you can build, develop, and test your application locally, and once it works bring it into Docker for integration testing.

  • Related