5

I want to use a Docker container to run a utility (specifically Terraform) using local files. In order to quickly iterate on the code (such as my_stuff.tf) I want to bind mount my working directory. However, I want to consider some things as relatively stable and static, such as plugins. Basically there are three ways I want things to be handled:

  1. .terraform/ is stable stuff that should exist in the container but not my host directory, but needs to be preserved even after mounting.
  2. my_stuff.tf exists both within container (because init needs it) and in host dir (because I want to edit it). I want my host directory version of this to override the container version.
  3. terraform.tfstate might not exist in either place to start with, but gets generated during running. I want it to persist in my host directory as soon as it does exist.

(and I guess a 4th category like README.md where I do not care whether it is there or not)

In my case, TF expects both .terraform/ where plugins are configured and terraform.tfstate (one of the outputs I want to catch with my bind-mount) to be in the same directory, so I cannot just use different directories for the container-internal stuff and the bind-mounted stuff.

# Dockerfile
FROM plugin_source AS plugins
FROM terraform_base
COPY --from=plugins terraform-provider-X /bin/
COPY my_stuff.tf /app/
WORKDIR /app
RUN /bin/terraform init

And my run command:

docker run --rm -i -t --mount source=$PWD,target=/app,type=bind my_terraform <some-tf-command>

Is there a slick way to make bind mounts behave how named volumes do on first initialization, as described in https://docs.docker.com/storage/bind-mounts/#mount-into-a-non-empty-directory-on-the-container? At present, it seems like I might have to write a little entrypoint script that symlinks the stable stuff into my work directory.

amacleod
  • 1,450
  • 2
  • 15
  • 23

1 Answers1

3

I used to do this with an old Development Weblogic container running on my computer:

  1. Run the image
  2. docker cp the directories of interest to the local disk
  3. Stop and kill the container
  4. Run the image again with the volume mappings.

This allowed me to get a fresh start with files from a virgin container and preserve all changes within the server.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Paulo Pedroso
  • 3,555
  • 2
  • 29
  • 34
  • So, applying this pattern to my scenario, I would copy the `.terraform/` directory out to my host after I build the image, so that it exists in the bind-mount? – amacleod Jan 10 '20 at 16:34
  • Yes, this is how I solved it on my end. Run once to copy the directory. Delete it. Run again with volume mapping and voilá. – Paulo Pedroso Jan 10 '20 at 21:24
  • 1
    Ok, between your answer and https://stackoverflow.com/a/31316636/447862 I can fully automate this process! 1. build 2. create 3. cp 4. rm 5. run – amacleod Jan 13 '20 at 19:04