Skip to content

Instantly share code, notes, and snippets.

@gus33000
Last active February 13, 2023 15:49
Show Gist options
  • Select an option

  • Save gus33000/fcc1e1023a4261fe408c69c560733b6a to your computer and use it in GitHub Desktop.

Select an option

Save gus33000/fcc1e1023a4261fe408c69c560733b6a to your computer and use it in GitHub Desktop.
Runs a specific command under a given docker container while not modifying the content of a mounted directory on the host
#!/bin/bash
#
# Runs a specific command under a given docker container while not modifying the content of a mounted directory on the host
#
# Inspired by https://devops.stackexchange.com/questions/3872/how-do-i-make-read-only-mount-in-docker-container-writable
#
# ./start.sh <base image name/remote image on docker hub> <directory to mount using overlayfs> <some program with args to run ...>
#
# e.g.: ./run-in-container-without-impact.sh devtest /data/test-docker-gus/target bash
#
# Output:
#
# ====================================================================
#
# [DOCKER BOOTSTRAP] Creating dc-ubuntu-excalibur-devtest-1676298510 based on devtest with /data/test-docker-gus/target mounted as read only into /mnt/lower
# [DOCKER BOOTSTRAP] Starting dc-ubuntu-excalibur-devtest-1676298510
# [DOCKER BOOTSTRAP] Creating /mnt/overlay
# [DOCKER BOOTSTRAP] Mounting tmpfs /mnt/overlay
# [DOCKER BOOTSTRAP] Creating /mnt/overlay/work
# [DOCKER BOOTSTRAP] Creating /mnt/overlay/upper
# [DOCKER BOOTSTRAP] Creating /data/test-docker-gus/target
# [DOCKER BOOTSTRAP] Mounting /data/test-docker-gus/target as read write using overlayfs on /mnt/lower
# [DOCKER BOOTSTRAP] Running bash
#
# ====================================================================
#
# root@dockexcalibur-devtest-1676298510:/data/test-docker-gus/target# ls -l
# total 8
# -rw-rw-r-- 1 1000 1000 5 Feb 9 13:37 test.txt
# -rw-r--r-- 1 root root 8 Feb 13 13:22 wow.txt
# root@dockexcalibur-devtest-1676298510:/data/test-docker-gus/target# uname -a
# Linux dockexcalibur-devtest-1676298510 5.15.0-58-generic #64-Ubuntu SMP Thu Jan 5 11:43:13 UTC 2023 x86_64 GNU/Linux
# root@dockexcalibur-devtest-1676298510:/data/test-docker-gus/target# exit
# exit
#
# ====================================================================
#
# [DOCKER BOOTSTRAP] Stopping dc-ubuntu-excalibur-devtest-1676298510
# [DOCKER BOOTSTRAP] Deleting dc-ubuntu-excalibur-devtest-1676298510
#
# ====================================================================
#
NAME=$(cat /proc/sys/kernel/hostname)-$1-$(date +%s)
BASEIMAGE=$1
TARGET=$2
shift
shift
HOSTNAME=dock${NAME}
CONTAINER=dc-${USER}-${NAME}
OVERLAY=/mnt/overlay
LOWERDIR=/mnt/lower
UPPERDIR=${OVERLAY}/upper
WORKDIR=${OVERLAY}/work
PRIVILEGED="--privileged"
echo
echo ====================================================================
echo
echo [DOCKER BOOTSTRAP] Creating $CONTAINER based on $BASEIMAGE with $TARGET mounted as read only into $LOWERDIR and starting it
docker run --detach --interactive --tty --name $CONTAINER $PRIVILEGED --hostname $HOSTNAME --mount type=bind,source=${TARGET},target=${LOWERDIR},readonly --entrypoint /bin/sh $BASEIMAGE > /dev/null
echo [DOCKER BOOTSTRAP] Remounting $LOWERDIR as $TARGET using OverlayFS
docker exec $PRIVILEGED $CONTAINER bash -c "mkdir -p ${OVERLAY} ; mount -t tmpfs tmpfs ${OVERLAY} ; mkdir -p {${WORKDIR},${UPPERDIR},${TARGET}} ; mount -t overlay overlay -o lowerdir=${LOWERDIR},upperdir=${UPPERDIR},workdir=${WORKDIR} ${TARGET}"
echo [DOCKER BOOTSTRAP] Getting Entrypoint
ENTRYPOINT=$(docker inspect -f '{{join .Config.Entrypoint " ; "}}' $BASEIMAGE)
echo [DOCKER BOOTSTRAP] Getting Environment
ENVIRONMENT="export $(docker inspect -f '{{join .Config.Env " ; export "}}' $BASEIMAGE)"
echo [DOCKER BOOTSTRAP] Getting Commands
COMMANDS=$(docker inspect -f '{{join .Config.Cmd " ; "}}' $BASEIMAGE)
COMMANDLINE=$*
echo [DOCKER BOOTSTRAP] Running "${COMMANDS} ${COMMANDLINE}"
echo
echo ====================================================================
echo
docker exec --interactive --tty --workdir $TARGET $CONTAINER bash -c "${ENVIRONMENT} ; ${ENTRYPOINT} ; ${COMMANDS} ${COMMANDLINE}"
echo
echo ====================================================================
echo
echo [DOCKER BOOTSTRAP] Stopping $CONTAINER
docker stop $CONTAINER > /dev/null
echo [DOCKER BOOTSTRAP] Deleting $CONTAINER
docker rm $CONTAINER > /dev/null
echo
echo ====================================================================
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment