2

I'm trying to write a Dockerfile for use as a standardized development environment.

Dockerfile:

FROM node:9.5.0

WORKDIR /home/project

# install some stuff...

# clone the repo
RUN git clone https://github.com/... . 

# expose 
VOLUME /home/project

# fetch latest changes from git, install them and fire up a shell.
CMD git pull && npm install && /bin/bash

After building the image (say with tag dev), Running docker run -it dev gives me a shell with the project installed and up-to-date.

Of course changes I make in the container are ephemeral so I want to mount /home/project on the host OS, I go to an empty directory project on the host and run:

docker run -it -v ${pwd}:/home/project dev

But my project folder gets overwritten and is empty inside the container.

How can mount the volume such that the container writes to the host folder and not the opposite?


OS: Windows 10 Pro.

Rob Bednark
  • 25,981
  • 23
  • 80
  • 125
matan tsuberi
  • 145
  • 1
  • 12
  • I'd suggest to look for a different solution than cloning a repository inside a Dockerfile. Otherwise you will face other issues (like, what private key is it used to fetch from the repository? And where are you going to persist such private key? In the repository itself would be insecure. Outside of the repo would break for other users). I usually do the Git operation manually (or inside the CI pipeline), but then rely only on the files that have already been fetched from the repository. **TL;DR: avoid Git operations inside a Dockerfile**. – Kamafeather Oct 06 '21 at 22:52

1 Answers1

2

When you mount a volume, read/write are both bi-directional by default. That means that anything you write in the container will show up in the host directory and vice versa.

But something weird is happening in your case, right?

In your build process, you are cloning a git repository. During the build process, the volume does not get mounted. The git data resides in your docker image.

Now, when you are running the docker container, you are mounting the volume. The mount path in your container will be synced with your source path. That means the container directory will be overwritten with the contents of the host directory. That's why your git data has been lost.

Possible Solution:

Run a script as CMD. That script can clone the git repo, among other things.

run.sh

#!/bin/bash

# clone the repo
RUN git clone https://github.com/... . 

Dockerfile

RUN ADD run.sh /bin

# run run.sh, install them and fire up a shell.
CMD run.sh && npm install && /bin/bash
Rob Bednark
  • 25,981
  • 23
  • 80
  • 125
Shahriar
  • 13,460
  • 8
  • 78
  • 95
  • But I don't want to clone the repo fresh everytime I run the container. It is meant to be only a development environment, the repo should be persisted between runs on the host machine. – matan tsuberi Feb 02 '18 at 20:09
  • Then just mount. In your host directory, clone git. And in script pull git – Shahriar Feb 02 '18 at 23:10
  • In the `CMD` I do a `git clone` or `git fetch` based on if the directory is empty. Take a look: https://github.com/daostack/arc/blob/master/Dockerfile – matan tsuberi Feb 10 '18 at 10:26
  • Did you try my one. Seems like similar to you. I just used script for git command. – Shahriar Feb 10 '18 at 10:29
  • Your solution is similar, bit it clones the project every time, so I needed the conditional clone/fetch. – matan tsuberi Feb 10 '18 at 10:36
  • yea. you are right. also I can add that condition in script. thank you – Shahriar Feb 10 '18 at 10:40