Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a host directory mount with the container directory's contents?

Tags:

docker

What I am trying to do is set up a docker container for ghost where I can easily modify the theme and other content. So I am making /opt/ghost/content a volume and mounting that on the host.

It looks like I will have to manually copy the theme into the host directory because when I mount it, it is an empty directory. So my content directory is totally empty. I am pretty sure I am doing something wrong.

I have tried a few different variations including using ADD with default themes folder, putting VOLUME at the end of the Dockerfile. I keep ending up with an empty content directory.

Does anyone have a Dockerfile doing something similar that is already working that I can look at?

Or maybe I can use the docker cp command somehow to populate the volume?

I may be missing something obvious or have made a silly mistake in my attempts to achieve this. But the basic thing is I want to be able to upload a new set of files into the ghost themes directory using a host-mounted volume and also have the casper theme in there by default.

This is what I have in my Dockerfile right now:

FROM ubuntu:12.04
MAINTAINER Jason Livesay "[email protected]"

RUN apt-get install -y python-software-properties
RUN add-apt-repository ppa:chris-lea/node.js
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get -qq update
RUN apt-get install -y sudo curl unzip nodejs=0.10.20-1chl1~precise1
RUN curl -L https://en.ghost.org/zip/ghost-0.3.2.zip > /tmp/ghost.zip
RUN useradd ghost
RUN mkdir -p /opt/ghost
WORKDIR /opt/ghost
RUN unzip /tmp/ghost.zip
RUN npm install --production

# Volumes
RUN mkdir /data

ADD run /usr/local/bin/run
ADD config.js /opt/ghost/config.js
ADD content /opt/ghost/content/
RUN chown -R ghost:ghost /opt/ghost

ENV NODE_ENV production
ENV GHOST_URL http://my-ghost-blog.com
EXPOSE 2368

CMD ["/usr/local/bin/run"]
VOLUME ["/data", "/opt/ghost/content"]
like image 912
Jason Livesay Avatar asked Feb 15 '23 06:02

Jason Livesay


2 Answers

As far as I know, empty host-mounted (bound) volumes still will not receive contents of directories set up during the build, BUT data containers referenced with --volumes-from WILL.

So now I think the answer is, rather than writing code to work around non-initialized host-mounted volumes, forget host-mounted volumes and instead use data containers.

Data containers use the same image as the one you are trying to persist data for (so they have the same directories etc.).

docker run -d --name myapp_data mystuff/myapp echo Data container for myapp

Note that it will run and then exit, so your data containers for volumes won't stay running. If you want to keep them running you can use something like sleep infinity instead of echo, although this will obviously take more resources and isn't necessary or useful unless you have some specific reason -- like assuming that all of your relevant containers are still running.

You then use --volumes-from to use the directories from the data container:

docker run -d --name myapp --volumes-from myapp_data

https://docs.docker.com/userguide/dockervolumes/

like image 171
Jason Livesay Avatar answered Jun 01 '23 23:06

Jason Livesay


You need to place the VOLUME directive before actually adding content to it.

My answer is completely wrong! Look here it seems there is actually a bug. If the VOLUME command happens after the directory already exists in the container, then changes are not persisted.

The Dockerfile should always end with a CMD or an ENTRYPOINT.

UPDATE

My solution would be to ADD files in the container home directory, then use a shell script as an entry point in which I'll copy the file in the shared volume and do all the other tasks.

like image 21
tommasop Avatar answered Jun 01 '23 23:06

tommasop