Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mount a file in a container, that isn't available before first run?

Tags:

docker

I'm trying to build a Dockerfile for a webapp that uses a file-based database. I would like to be able to mount the file from the host* The file is in the root of the complete software install, so it's not really ideal to mount that complete dir.

Another problem is that before the first use, the database-file isn't created yet. A first time user won't have a database, but another user might. I can't 'mount' anything during a build** I believe.

It could probably work like this:

  • First/new database start:
    • Start the container (without mount).
    • The webapp creates a database.
    • Stop the container
  • subsequent starts:
    • Start the container using a -v to mount the file

It would be better if that extra start/stop isn't needed for a user. Even if it is, I'm still looking for a way to do this userfriendly, possibly having 2 'methods' of starting it (maybe I can define a first-boot thing in docker-compose as well as a 'normal' method?).

How can I do this in a simpel way, so that it's clear for any first time users?

* The reason is that you can copy your Dockerfile and the database file as a backup, and be up and running with just those 2 elements.

** How to mount host volumes into docker containers in Dockerfile during build

like image 939
Nanne Avatar asked Aug 01 '15 19:08

Nanne


People also ask

How do I run a container already made?

Follow these steps: Use docker ps to get the name of the existing container. Use the command docker exec -it <container name> /bin/bash to get a bash shell in the container. Or directly use docker exec -it <container name> <command> to execute whatever command you specify in the container.


2 Answers

One approach that may work is:

  • Start the database in the build file in such a way that it has time to create the default file before exiting.
  • Declare a VOLUME in the Dockerfile for the file after the above instruction. This will cause the file to be copied into the volume when a container is started, assuming you don't explicitly provide a host path
  • Use data-containers rather than volumes. So the normal usage would be:

     docker run --name data_con my_db echo "my_db data container"
     docker run -d --volumes-from  data_con my_db
     ...
    

The first container should exit immediately but set up the volume that is used in the second container.

like image 172
Adrian Mouat Avatar answered Oct 10 '22 23:10

Adrian Mouat


This is probably not the correct approach.

If you have multiple containers that are trying to share some information through the file-system, you should probably let them share some directory.

That way, the flow is simple and very hard to get wrong. You simply mount the same directory, say /data (from the host's perspective) into all the containers that are trying to use it.

When an application starts and it can't find anything inside that directory, it can gracefully stop and exit with a code that says: "Cannot start, DB not initialized yet". You can then configure some mechanism with a growing timeout to try and restart that container until you're successful.

On the other hand, the app that creates the DB can start and create it inside the directory or find an existing file to use.

like image 30
Daniel Trugman Avatar answered Oct 11 '22 00:10

Daniel Trugman