Docker-compose volume mount before run

2019-01-22 13:10发布

问题:

I have a Dockerfile I'm pointing at from a docker-compose.yml.

I'd like the volume mount in the docker-compose.yml to happen before the RUN in the Dockerfile.

Dockerfile:

FROM node

WORKDIR /usr/src/app

RUN npm install --global gulp-cli \
 && npm install

ENTRYPOINT gulp watch

docker-compose.yml

version: '2'

services:
  build_tools:
    build: docker/gulp
    volumes_from:
      - build_data:rw

  build_data:
    image: debian:jessie
    volumes:
      - .:/usr/src/app

It makes complete sense for it to do the Dockerfile first, then mount from docker-compose, however is there a way to get around it.

I want to keep the Dockerfile generic, while passing more specific bits in from compose. Perhaps that's not the best practice?

回答1:

Erik Dannenberg's is correct, the volume layering means that what I was trying to do makes no sense. (There is another really good explaination on the Docker website if you want to read more). If I want to have Docker do the npm install then I could do it like this:

FROM node

ADD . /usr/src/app
WORKDIR /usr/src/app

RUN npm install --global gulp-cli \
 && npm install

CMD ["gulp", "watch"]

However, this isn't appropriate as a solution for my situation. The goal is to use NPM to install project dependencies, then run gulp to build my project. This means I need read and write access to the project folder and it needs to persist after the container is gone.


I need to do two things after the volume is mounted, so I came up with the following solution...

docker/gulp/Dockerfile:

FROM node

RUN npm install --global gulp-cli

ADD start-gulp.sh .

CMD ./start-gulp.sh

docker/gulp/start-gulp.sh:

#!/usr/bin/env bash

until cd /usr/src/app && npm install
do
    echo "Retrying npm install"
done
gulp watch

docker-compose.yml:

version: '2'

services:
  build_tools:
    build: docker/gulp
    volumes_from:
      - build_data:rw

  build_data:
    image: debian:jessie
    volumes:
      - .:/usr/src/app

So now the container starts a bash script that will continuously loop until it can get into the directory and run npm install. This is still quite brittle, but it works. :)



回答2:

You can't mount host folders or volumes during a Docker build. Allowing that would compromise build repeatability. The only way to access local data during a Docker build is the build context, which is everything in the PATH or URL you passed to the build command. Note that the Dockerfile needs to exist somewhere in context. See https://docs.docker.com/engine/reference/commandline/build/ for more details.