Search code examples
dockercontainersibm-cloud

How to force a docker container in IBM Bluemix to connect a volume?


is there any way to refuse to start a container where there is no volume connected to certain path?

I have a mysql container and want to block starting the container (exit with an error) where there is no volume connected to /var/lib/mysql to host volume. There is an option in IBM Bluemix for adding a volume to the container with the container's specified path. I need to prevent starting the container if someone forget to add the volume.

Alternatively, is it possible to find out if there is a volume from the host to the container from inside the container? (Adding a check to the entrypoint)


Solution

  • Container volumes contain the name of the container in the mount path, so basically you can create an entry point script in your Dockerfile that checks for the presence of the volume name. I used df | grep volume-name to check if volume is mounted in the entry point script. This is an example of running df on container with volume mounted (volume here is adsdatabase):

    # df
    Filesystem 1K-blocks Used Available Use% Mounted on
    /dev/mapper/docker-8:16-212573961-302136b327f5923d7c9b8c6c2cf62c0783 10190136 466892 9182572 5% /
    tmpfs 132022832 0 132022832 0% /dev
    shm 65536 0 65536 0% /dev/shm
    nfsdal0901d.service.softlayer.com:/IBM01SV531277_366/adsdatabase 20971520 23168 20948352 1% /data
    /dev/sdb 11522552336 200321280 10741487072 2% /etc/hosts
    udev 132009268 4 132009264 1% /dev/tty
    

    I recommend you don't use a common name, like "data", for the volume name or the grep would match that.

    Here are the steps I did:

    1. Create an entry point script that checks for the presence of the volume using df command (see sample entrypoint.sh file below)
    2. Create a Dockerfile and add ENTRYPOINT command to run your entry point script (see sample Dockerfile file below)
    3. Create a new image and push to your Bluemix registry, for example:

      $ docker build -t ads-volumesample . $ docker tag ads-volumesample registry.ng.bluemix.net/namespace/ads-volumesample $ docker push registry.ng.bluemix.net/namespace/ads-volumesample

    4. Create a volume - the name of the volume matches the check in the entry point script, for example:

      $ cf ic volume create adsdatabase

    5. Create a new container and add the new volume:

      $ cf ic run -v adsdatabase:/data --name ads-volumesample1 registry.ng.bluemix.net/namespace/ads-volumesample

    If you do not add the volume when creating the container, the container will fail and will automatically shutdown in a few minutes.

    entrypoint.sh

    #!/bin/bash
    set -e
    
    if df | grep adsdatabase > /dev/null; then
       echo "Found volume"
    else
       echo "Volume not found"
       exit 1
    fi
    
    exec "$@"
    

    Dockerfile

    FROM registry.ng.bluemix.net/ibmnode
    
    ADD ./app /node
    
    ENV NODE_ENV production
    
    RUN cd /node && npm install
    COPY entrypoint.sh /
    ENTRYPOINT ["/entrypoint.sh"]
    
    EXPOSE 3000
    
    CMD ["node", "/node/app.js"]