My Docker development shell

21 Dec 2021

I just made a simple docker container to use as a development shell. This will make it easier and faster for me to just build the docker container and run it when I need a development shell environment.

Dockerfile

I will base my Docker container on Debian bullseye because I mostly run Debian.

FROM debian:bullseye

Simple start, my next step was to make sure my environment is setup as I want it. US English as language, but with my Swedish locale for everything else time, date etc.

# Variables
ARG LOCALE="sv_SE.UTF-8"
ENV TZ=Europe/Stockholm

# Install locales and make sure tzdata exists
RUN apt-get update && apt-get install -y locales tzdata
RUN sed -i "/en_US.UTF-8/s/^#//g" /etc/locale.gen
RUN sed -i "/sv_SE.UTF-8/s/^#//g" /etc/locale.gen
RUN locale-gen

ENV LANG="en_US.UTF-8" \
    LANGUAGE="en_US:en" \
    LC_NUMERIC="$LOCALE" \
    LC_TIME="$LOCALE" \
    LC_COLLATE="$LOCALE" \
    LC_MONETARY="$LOCALE" \
    LC_PAPER="$LOCALE" \
    LC_NAME="$LOCALE" \
    LC_ADDRESS="$LOCALE" \
    LC_TELEPHONE="$LOCALE" \
    LC_MEASUREMENT="$LOCALE" \
    LC_IDENTIFICATION="$LOCALE"

RUN update-locale
  • ARG is a local variable in Dockerfile and is not available in the Docker container when it is running
  • ENV is an environment variable and will be available in the Docker container when it is running.

I’m using the ARG to create a local LOCALE variable for easy change of the locale for everything except language.

The next step is to set the timezone

# Timezone
RUN echo $TZ > /etc/timezone
RUN rm /etc/localtime && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata

Finally it’s time to install some basic stuff and some dev packages

# Install dev packages
RUN apt-get install -y \
    build-essential \
    wget \
    curl \
    git \
    nano

# Install Node.js 16.x
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs

# Install yarn
RUN npm install --global yarn
RUN npm install --global gulp

And yes I am running nano, I don’t know how to quit from vi..

Complete Dockerfile

FROM debian:bullseye

# Variables
ARG LOCALE="sv_SE.UTF-8"
ENV TZ=Europe/Stockholm

# Install locales and make sure tzdata exists
RUN apt-get update && apt-get install -y locales tzdata
RUN sed -i "/en_US.UTF-8/s/^#//g" /etc/locale.gen
RUN sed -i "/sv_SE.UTF-8/s/^#//g" /etc/locale.gen
RUN locale-gen

ENV LANG="en_US.UTF-8" \
    LANGUAGE="en_US:en" \
    LC_NUMERIC="$LOCALE" \
    LC_TIME="$LOCALE" \
    LC_COLLATE="$LOCALE" \
    LC_MONETARY="$LOCALE" \
    LC_PAPER="$LOCALE" \
    LC_NAME="$LOCALE" \
    LC_ADDRESS="$LOCALE" \
    LC_TELEPHONE="$LOCALE" \
    LC_MEASUREMENT="$LOCALE" \
    LC_IDENTIFICATION="$LOCALE"

RUN update-locale

# Timezone
RUN echo $TZ > /etc/timezone
RUN rm /etc/localtime && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata

# Install dev packages
RUN apt-get install -y \
    build-essential \
    wget \
    curl \
    git \
    nano

# Install Node.js 16.x
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs

# Install yarn
RUN npm install --global yarn
RUN npm install --global gulp

Helper scripts

Some helper scripts because I don’t always remember how to use stuff.

Build script

Super simple bash script to build the docker container

#!/bin/bash

docker build -t docker-dev-shell .

This way I don’t have to remember how to build the container. I just have to clone my repo and run ./build.sh to build the container

Run script

If I can’t remember how to build the container, I can’t remember how to run it. So I need a script to run the container as well. This script is a bit more complex because I made the script to run the container as the current user, with the current users home folder mounted as persistent storage.

#!/bin/sh

UID=$(id -u)
GID=$(id -g)

docker run \
       --user $UID:$GID \
       -v /etc/group:/etc/group:ro \
       -v /etc/passwd:/etc/passwd:ro \
       -v /etc/shadow:/etc/shadow:ro \
       -v /home/$USER:/home/$USER \
       --workdir="/home/$USER" \
       --hostname dev-shell \
       -it --rm docker-dev-shell
  • –user Parameter will run the docker container as the current user
  • -v /etc/* Parameters will mount the local passwd,group,shadow files from host, so the local user will be available in the container.
  • -v /home/$USER Parameter will mount the current user Home folder to use as persistent storage.
  • –hostname Parameter gives the container an internal hostname, just to make the interactive prompt have a pretty hostname. Makes it clear we are in a dev-shell as well.
  • -it –rm Parameters will create an interactive container and will remove it when we exit so make sure you save your stuff in your home folder.