How to mount a VOLUME with Dockerfile specifying both source and destination?

Hi,

I want to know how to mount a VOLUME in Dockerfile specifying both source and destination paths.

I have read that this can’t be done directly for portability reasons, but I want to know an alternative way in order to do it.

With docker-compose, for example, it’s enough to add the following:

volumes:
  - /path/source/on/host:/path/destination/on/container

Then, when running:

 docker start <image_id>

The container starts with the volume specified.

I want to do the same thing with the Dockerfile instead of docker-compose, and I want to start the container with docker start command, NOT with docker run -v

How can I do it?
Thanks.

You can’t. You can only specify the host-system path (or volume name or whatever else) at docker run time.

Also, you can specify docker run -v on any container-side path, and VOLUME is only meaningful in cases where you don’t give a docker run -v option for that path. I’d probably avoid using VOLUME in almost all cases.

docker start probably shouldn’t be part of your core workflow at all. It’s extremely routine to need to delete containers (for instance, to restart the container with a newer image with updated software). If you need to restart a container, it’s better to docker rm and docker run it again, making sure to store the state that needs to be preserved either in a volume or an external database.

If your biggest concern is just the length of the docker run command line, you can use Docker Compose or a very simple shell script to record the options you use somewhere.

1 Like

The question is that I don’t want to delete the container every time.
I want to use the same container every time, stopping/restarting it only when necessary.
If I install a component in the container, for example, I will lose it every time.

So the combination “docker run/docker rm” option can’t be a useful solution to my scope.

How’s possible that it can’t be configured in the same way as the docker-compose?
It could be considered as a lacuna IMHO.
Agree, it’s projected for another scope, but it should be gave the possibility in any case.

So are you saying that the only option is putting away the Dockerfile and replacing it with a docker-compose?
Awful.

Right. You should install it in the Dockerfile that builds the image you’re running.

To reiterate: sometimes you have to delete and recreate a running container: to change startup-time options like volume mounts, to move it to a different system, to relaunch the container with a newer image, because something in your Docker environment broke. You should plan up front to do this, and having planned to do that, making docker rm part of your default flow isn’t a big deal.

Docker Compose more or less gives a different way to provide the various docker run options. Docker has generally chosen to require containers to be portable across host systems, which means you never get to require things like specific out-of-container host paths.

I’m saying you should have both. In your Dockerfile, install your application and any prerequisites it has (RUN apt-get install a lot). In your Docker Compose YAML file (or a wrapper shell script, or a Kubernetes deployment file, or a Nomad job, or …) specify where the persistent data, any configuration files you need to inject, and any log files you need to directly read back out should go.

Let’s see if I have understood correctly.

I can have both Dockerfile and docker-compose.yml.

So I can keep the Dockerfile that I already have, and I can create a docker-compose.yml that “build” the image instructed with the Dockerfile instructions.

More or less, in the following way:

version: '2'
services:
  exampleservice:
    environment:
      - bootstrap.memory_lock=true
    build: 
	  - context: /path/to/DockerfileDirectory
	  - dockerfile: DockerfileFileName
    ports:
      - "8080:8080"
    volumes:
      - /path/from/host:/path/to/container
    privileged: true

The “build” command should invoke the Dockerfile in the specified directory.
With this configuration, I can mount the volumes in the docker-compose.
I really need the VOLUME command in the Dockerfile with this possible kind of configuration?

Tell me please if I’m wrong.

Right. The docker-compose.yml file you have looks basically right.

You don’t need it, and with this specific setup, it won’t make a difference whether you have it or not.

FROM python:3.7

LABEL maintainer " saahmathworks@gmail.com"

WORKDIR /code

COPY requirements.txt ./

RUN pip install -r requirements.txt

COPY . .

EXPOSE 8050

VOLUME ["/code"]

CMD [“python”, “index.py”]