Life Codecs @ NamingCrisis.net

Ruminations. Reflections. Refractions. Code.

Mar 14, 2017 - Software dev

Docker Container as a Shell

Most of my work is done either on a Macbook Pro, or my Linux desktop. As much as macOS is a Unix, with supporting tools like MacPorts, Linux is still richer as far as commandline utilities go.

Prior to native Docker support on macOS/OSX, you would resort to running Linux in a virtual machine, and having a share directory.

With Docker, we basically emulate the same, but obviously, native Docker on the Mac, or Windows 10 for that matter, is far more lightweight than a VM. Note that this is not a very container’ey use of Docker where everything you need is ready to deploy right from the image.

The approach I’m taking for this use case is basically to treat a Docker container as a lightweight VM, with adhoc tooling installed — essentially a rolling-release style VM, occasionally taking snapshots, and pushing up to the docker registry so it’s shareable across machines.

The overall approach is:

  • Pull down an existing container, I went with ubuntu
  • Tag it as your own and push to your docker registry. Follow instructions here on this step.
  • Pull down your tagged image
  • Create a script that will mount your home directory as a volume. Thereby providing you with a live workspace to execute your container utilities against. I have nearly all my work in my home directory, so this mount makes sense, but it’s simply a regular mount.
  • Create a user in the container, so you don’t constantly log in as root.
  • Commit and push the container’s changes as needed.

Your data is still in your host’s home, while the utilities are installed in the container.

Running docker commands is a pain if you do the above workflow often. Here I’m providing the scripts and utilities I wrote. Replace with your custom values as needed.

My Docker utility run script. Note that it’s already using my tagged ubuntu image. So the tagging and pushing step is a prerequisite.

#
# ubuntu-docker-start.sh
#

HOST_HOME=/Users/xdyme
CONTAINER_HOME=/home/xdyme/data
TZ=Australia/Melbourne
HOSTNAME=ubuntu-container
CONTAINER_NAME=ubuntu
IMAGE="kva1966/ubuntu:latest"

docker run -dt \
  --name ${CONTAINER_NAME} \
  -h ${HOSTNAME} \
  -e ${TZ} \
  --volume ${HOST_HOME}:${CONTAINER_HOME} \
  ${IMAGE}


I also added a bunch of utility aliases for common container tasks in ~/.bashrc:

#### Local Shell Container ####

alias d=docker
alias ubuntu-deploy-container='~/projects/checkouts/desktop-scripts/ubuntu-docker-start.sh'
alias ubuntu-commit='d commit ubuntu kva1966/ubuntu:latest'
alias ubuntu-push='d push kva1966/ubuntu:latest'
alias ubuntu-stop='d stop ubuntu'
alias ubuntu-start='d start ubuntu'
alias ubuntu-run='ubuntu-stop; d rm ubuntu; ~/projects/checkouts/desktop-scripts/ubuntu-docker-start.sh'
alias ubuntu-delete-container='ubuntu-stop; d rm ubuntu'

ubuntu-login-user() {
  username=$1
  homedir=/home/$username
  if [ -z $username ]; then
    username=root
    homedir=/root
  fi
  
  d exec -it -u $username ubuntu bash -c "cd $homedir; exec ${SHELL} --login"
}

alias ubuntu-login='ubuntu-login-user xdyme'
alias ubuntu-login-root='ubuntu-login-user'

#### END Local Shell Container ####


Some very basic .bashrc and .profile can be found when you login to the xdyme user on my container. Mainly git completion, and a nicer looking default shell.