Spacemacs in a Docker Container Ep 1 – Install, Build and Run

Jan 13, 2023 | Docker, HSS

1 Introduction

This blog is the first episode of a multi part series detailing the Harmonic Software Systems setup that allows our engineers to quickly and easily spin up a development environment that utilises the power of Spacemacs, configured to use additional tools to provide top quality software development and testing to our customers.

Docker and spacemacs, two of the most powerful and desirable tools in the ever evolving world of technology. Docker, which is an open-source software platform that makes it easier to create, operate, manage, test, and distribute applications. Spacemacs, which if you didn’t know by now, is one of the best editors in the market. It combines the best features of Vim and Emacs into a fantastic editor.

This blog is divided into several sections, each of which explains the features of Docker and how we used Docker to build a spacemacs editor within a Docker container.

2 Prerequisites

One of the great advantages of Docker is how easy it is to set up and use. So users can follow the instructions on windows, Linux and Mac easily using the command line.

These instructions assume that you are using:

  • A Linux Machine (Ubuntu 22.04 Virtual Machine in our case)
  • Git installed

3 What is Docker?

Docker is defined as “an open-source project that automates the deployment of software applications inside containers by providing an additional layer of abstraction and automation of OS-level virtualization on Linux.” Docker essentially runs the host computer’s operating system as a virtual machine to run applications within a container, rather than the traditional virtualisation of hardware elements.

The process table, network interface, and file system directories mounted, would all be virtual copies. These are carried over from the host’s operating system, where the container is hosted and executed. But, all running containers on the host share the operating system’s kernel. As a result, each container that is present on the same host can be separated from the others. As long as they all have the same operating system needs, it allows numerous containers with various application requirements and dependencies to operate on the same host.

4 Advantages of using Docker

Some of the key benefits of Docker are listed below:

Robust – An operating system is not present on a container. Therefore, compared to a virtual machine, it uses extremely less memory. As opposed to the few minutes needed to start up a virtual computer, this cuts down the bootup time to only a few seconds for helping in faster deployment.

Reduced Cost – In terms of the hardware needed to execute multiple applications, Docker is less hardware demanding compared to a Virtual Machine.

Optimized Storage – Since containers are often only a few megabytes in size and take up relatively little disc space, a large number of programmes may be hosted on the same host.

Scalability – As long as all of the application have the same operating system needs, Docker permits hosting many applications and containers with various application requirements and dependencies on the same host.

Standardisation – One of the big reasons we found for using Docker was to standardise the environment and minimise the inconsistencies when running or setting up on different hosts. This is a big help to ensure all the colleagues working on the same project would have the same standard work environment.

Security – Applications and resources are separated and isolated of each container. You may easily remove an application’s container if you no longer require it and it won’t leave any temporary or configuration files. Each application can only use the resources that have been allocated to them and no Docker container has access to another container’s running processes.

5 Spacemacs

Vim or emacs. A ‘heated’ debate that most of the software community have either heard of or partaken. Spacemacs is the solution. With spacemacs, you get the best of both worlds. As our MD would say, “the business runs on spacemacs”.

Spacemacs could be set up to have as many features and be as powerful as an IDE or a simple text editor or anything in between. One of the biggest pluses is the customisation a user is able to do via the. spacemacs file to add any features that they desire. There is a big online community of experts releasing new tools and addons you can incorporate.

Two things that are guaranteed once you take on spacemacs are, a boost in productivity and unlimited fun

6 Installing Docker

Use the following link to install Docker engine on different platforms.

https://docs.docker.com/engine/install/

Use the link below for the instructions on installing the Docker engine on ubuntu. The command line instructions we used, and our notes are also listed below.

https://docs.docker.com/engine/install/ubuntu/

// Install
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo   "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
// Installing the latest Docker 
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
// Listing the Docker version 
apt-cache madison docker-ce
// Installing specific Docker version
sudo apt-get install docker-ce=5:20.10.20~3-0~ubuntu-focal
// Running Docker 
sudo service docker start
sudo docker run hello-world
// Add the user. Ensure the host machine is restarted post adding the user.
sudo groupadd docker
sudo usermod -aG docker $USER
// Run 
docker run hello-world

7 Building Spacemacs Container on Docker

These sections will go into details on how to create a Docker file that will be used to build and run a spacemacs Docker image in ubuntu.

7.1 Create a directory for the Docker container

Using the command line, navigate to the desired project folder and create a new directory for the spacemacs container image.

cd <WORKSPACE>
mkdir Spacemacs
cd Spacemacs

7.2 Create a Docker file

Create a Docker file from within the project folder. Ensure to name the file “Dockerfile” as the Docker engine looks for this specific file name for build and run.

Use :wq to exit the vim editor

vi Dockerfile

7.3 Choose the environment to run on

At the beginning of every Dockerfile, the user must specify the environment on which to build and execute the subsequent commands. For this blog we used ubuntu, but the user may configure this accordingly.

FROM ubuntu:latest

7.4 Install Emacs and git

Use the apt commands to install git and emacs onto the Docker image. Git will be used later to pull in the spacemacs package and incorporate it into emacs.

The RUN instruction will execute the commands and save the results for it to be used by the following instructions.

RUN apt update && \
    apt install -y software-properties-common
RUN add-apt-repository ppa:kelleyk/emacs
RUN apt update
RUN apt install -y git
RUN apt install -y emacs28
RUN apt install -y global

7.5 Install the packages needed for spacemacs build

Depending on the configurations in your .spacemacs file, (file that holds the spacemacs configurations) packages to support those configurations will need to be downloaded, and in our case, the following packages need to be installed.

RUN apt install -y gcc
RUN apt update
RUN apt install -y pip
RUN apt install -y clangd-13
RUN apt install -y cppcheck
RUN pip install python-lsp-server

7.6 Commands to remove the emacs load errors

In development, we found that some errors appear when running the Docker file to load emacs. Although these errors didn’t result in any failure in spacemacs operations, the following instruction was added to fix it.

RUN apt install -y libcanberra-gtk-module libcanberra-gtk3-module

7.7 Declare the arguments

The ARG instruction is used to define variables that users pass into the Docker file, from the command line during a Docker build. Eg –build-arg XAUTHORITY=$XAUTHORITY. The full docker build command is explained later in the blog.

These variables will be used within the docker file for the docker image configurations.

ARG XAUTHORITY
ARG USERNAME

7.8 Add a new user and define the user configurations

Create a new user and name it the same as the argument $USERNAME passed in during build. The user is added and its home directory and user id are specified.

The user id of XAUTHORITY needs to be the same as the user id set for the new user. This is to ensure spacemacs is opened on a separate window rather than on the command prompt.

RUN useradd -d /home/"$USERNAME" -u $(echo $XAUTHORITY | awk -F/ '{print $4}') -ms /bin/bash "$USERNAME" && usermod -aG "$USERNAME" "$USERNAME"

7.9 Configure the file system permissions

To use spacemacs for a project, the user needs read/write permissions over the file system. The following instructions are used to ensure the user has all the permissions.

USER root
RUN mkdir /home/$USERNAME || echo "Skip over build error"
RUN chown -R $USERNAME /home/$USERNAME

7.10 Adding adobe source code font

 

RUN apt update
RUN apt install -y wget
RUN wget --content-disposition -P /usr/share/fonts/opentype/source-code-pro https://github.com/adobe-fonts/source-code-pro/blob/29fdb884c6e9dc2a312f4a5e2bb3b2dad2350777/OTF/SourceCodePro-Regular.otf?raw=true

7.11 Configure the Docker image Environment

Use the ENV command to add variables into the docker image environment. These environments are then directly accessible in the isolated docker container image.

USER $USERNAME
WORKDIR /home/$USERNAME
ENV UNAME $USERNAME 
ENV GNAME $USERNAME

7.12 Mounting Files

Use the VOLUME command to mount a file or directory to the containers home directory. Mounting the XAUTHORITY file to run the x11 graphics within the container.

VOLUME $XAUTHORITY

7.13 Configure the bashrc file

Configuring the bashrc file with a docker specific red prompt in the terminal. Otherwise with multiple terminals you can get lost and forget you are in a docker continer.

RUN echo 'alias ll="ls -hal --color"' >> ~/.bashrc
RUN echo 'export PS1="\[\033[01;31m\]\u@docker\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ "' >> /home/$USERNAME/.bashrc

7.14 Import the spacemacs package

Pull the most stable version of spacemacs from git into the local repository.

RUN git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d

7.15 Configure spacemacs

The following instructions are used to configure the default spacemacs with the configurations we here at HSS use. This pulls a known working version of Spacemacs as of 13 Nov 2022.

RUN cd .emacs.d && git checkout 57a7a0e63c4aecf810b19ca3fd49e5ae1a838126
RUN cd ~
RUN git init
RUN git remote add origin https://github.com/harmonicss/spacemacs.git
RUN git pull origin master
RUN cp .spacemacs.linux .spacemacs
RUN mkdir ~/.emacs.d/backup
RUN mkdir ~/.emacs.d/undo

For the users of windows, the following instruction is needed instead of the cp .spacemacs.linux command.

RUN cp .spacemacs.win .spacemacs

7.16 Install spacemacs

Spacemacs is installed with all its packages. The following command is run twice, as we found there are some packages that get skipped on the first install.

RUN emacs -nw -batch -u "$USERNAME" -q -kill
RUN emacs -nw -batch -u "$USERNAME" -q -kill

7.17 Configure the git environment

 

RUN git config --global user.name $USERNAME \
    && git config --global user.email $USERNAME@harmonicss.co.uk

7.18 Setup ENTRYPOINT

ENTRYPOINT is used to ensure emacs is always run when the container is initiated.

ENTRYPOINT ["emacs"]

NOTE: This can be replaced with CMD (below) which allows a the docker container to be started with a bash shell, allowing emacs to be launched with debug.

CMD ["emacs"]

7.19 Build the Docker image

Use the following command to build the Dockerfile. In the command below –build-arg is used to pass in the arguments into the Dockerfile and ‘harmonicss/spacemacs’ is the name of the docker image. The docker image name can be anything the user wants.

This build will take a while as it downloads emacs and builds and installs the spacemacs lisp files.

docker build -t harmonicss/spacemacs --build-arg XAUTHORITY=$XAUTHORITY --build-arg USERNAME=$USER .

7.20 Run the Docker image

The argument of -v is used to mount the directory to the docker image. Configure the argument according to the users file system.

docker run  -it --rm  -e DISPLAY --net=host -v ~/Projects:/home/$USER/Projects harmonicss/spacemacs 

Screenshot Of Spacemacs Running On Docker Container

7.21 Features on Spacemacs

There are endless features that can be added to your spacemacs. Some of the key features we make use of are git, gtags, flymake and lsp mode. An example of LSP (Language Server Protocol) mode is shown below. See more here https://emacs-lsp.github.io/lsp-mode/

Screenshot Of Spacemacs With LSP Showing Live Error

We have also integrated cppcheck and valgrind into our workflow, but that is for a future installment.

8 Full Dockerfile

Use the following command to pull the latest Dockerfile entry from our git repository.

git clone https://github.com/harmonicss/docker-spacemacs.git

################################################################################
#
# Spacemacs Docker Container
# ==========================
#
# Ed Liversidge, Harmonic Software Systems Ltd harmonicss.co.uk
#
# Installs a spacemacs docker continer with the following features:
#
# - fixed spacemacs version as of Nov 12 2022
# - .spacemacs config file used at HSS
# - git
# - gnu global for tagging
# - clangd, gcc and cppcheck for live syntax checking usng lsp-mode 
# - source code pro font
#
#
#  build using : (dont forget the .)
#  ===========
#
#  docker build -t harmonicss/spacemacs --build-arg XAUTHORITY=$XAUTHORITY --build-arg USERNAME=$USER .
#
#  Run using :
#  ===========
#
#  docker run  -it --rm  -e DISPLAY --net=host -v ~/Projects:/home/$USER/Projects harmonicss/spacemacs
#
#
################################################################################

################################################################################
# Change this to use fast emacs-native-comp, needs to be
# built from docker beforehand. Not on dockerhub yet, but on
# github here : https://github.com/harmonicss/docker-emacs-native
################################################################################
FROM ubuntu:latest
################################################################################
# Install emacs and git
################################################################################
RUN apt update && \
    apt install -y software-properties-common
RUN add-apt-repository ppa:kelleyk/emacs
RUN apt update
RUN apt install -y git
RUN apt install -y emacs28
RUN apt install -y global

################################################################################
# Install lsp clangd-13 (C language LSP server for code completion)
# and gcc for syntax checking
################################################################################
RUN apt install -y gcc
RUN apt update
RUN apt install -y pip
RUN apt install -y clangd-13
RUN apt install -y cppcheck
RUN pip install python-lsp-server

################################################################################
# To Remove emacs loading warnings
################################################################################
RUN apt install -y libcanberra-gtk-module libcanberra-gtk3-module 

################################################################################
# XAUTHORITY and USERNAME is passsed in via cmd line
# eg docker build -t spacemacs --build-arg XAUTHORITY=$XAUTHORITY \
#    --build-arg USERNAME=$USERNAME .
################################################################################
ARG XAUTHORITY
ARG USERNAME

################################################################################
# Add a new user with the USERID of XAUTHORITY thats parsed
# from the string passed in and also give it group privileges
################################################################################
RUN useradd -d /home/"$USERNAME" -u $(echo $XAUTHORITY | awk -F/ '{print $4}') -ms /bin/bash "$USERNAME" && usermod -aG "$USERNAME" "$USERNAME"

################################################################################
# Configure file system properties 
################################################################################
USER root
RUN mkdir /home/$USERNAME || echo "Skip over build error"
RUN chown -R $USERNAME /home/$USERNAME

################################################################################
# Install source code pro font
# https://askubuntu.com/questions/193072/how-to-use-the-adobe-source-code-pro-font
################################################################################
RUN apt update
RUN apt install -y wget
RUN wget --content-disposition -P /usr/share/fonts/opentype/source-code-pro https://github.com/adobe-fonts/source-code-pro/blob/29fdb884c6e9dc2a312f4a5e2bb3b2dad2350777/OTF/SourceCodePro-Regular.otf?raw=true

################################################################################
# Setup the environment
################################################################################
USER $USERNAME
WORKDIR /home/$USERNAME
ENV UNAME $USERNAME 
ENV GNAME $USERNAME

################################################################################
# Mounting the XAUTHORITY file allow the x11 graphics to work
################################################################################
VOLUME $XAUTHORITY 

################################################################################
# Configure .bashrc properties
################################################################################
RUN echo 'alias ll="ls -hal --color"' >> ~/.bashrc

################################################################################
# Set the prompt for the bash shell
################################################################################
RUN echo 'export PS1="\[\033[01;31m\]\u@docker\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ "' >> /home/$USERNAME/.bashrc

################################################################################
# get .spacemacs
################################################################################
RUN git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d
################################################################################
# lock spacemacs at latest as of Nov 13 2022
################################################################################
RUN cd .emacs.d && git checkout 57a7a0e63c4aecf810b19ca3fd49e5ae1a838126
RUN cd ~
RUN git init
RUN git remote add origin https://github.com/harmonicss/spacemacs.git
RUN git pull origin master
RUN cp .spacemacs.linux .spacemacs
RUN mkdir ~/.emacs.d/backup
RUN mkdir ~/.emacs.d/undo
################################################################################
# Install all the .spacemacs packages, twice as there as always stragglers to update
################################################################################
RUN emacs -nw -batch -u "$USERNAME" -q -kill
RUN emacs -nw -batch -u "$USERNAME" -q -kill

################################################################################
# Configure git
################################################################################
RUN git config --global user.name $USERNAME \
    && git config --global user.email $USERNAME@harmonicss.co.uk
ENTRYPOINT ["emacs"]

Browse Category

Join our DO-178C group on LinkedIn

Got A Project In Mind?

We fix, develop and test embedded software for the aerospace & defence industry specialising in DO-178C safety-critical testing. Speak to us. We have laser focus, unprecedented attention-to-detail and provide phenomenal value.