Spacemacs in a Docker Container Ep 1 – Install, Build and Run
Table of Contents
- 1. Introduction
- 2. Prerequisites
- 3. What is Docker?
- 4. Advantages of using Docker
- 5. Spacemacs
- 6. Installing Docker
- 7. Building Spacemacs Container on Docker
- 7.1. Create a directory for the Docker container
- 7.2. Create a Docker file
- 7.3. Choose the environment to run on
- 7.4. Install Emacs and git
- 7.5. Install the packages needed for spacemacs build
- 7.6. Commands to remove the emacs load errors
- 7.7. Declare the arguments
- 7.8. Add a new user and define the user configurations
- 7.9. Configure the file system permissions
- 7.10. Adding adobe source code font
- 7.11. Configure the Docker image Environment
- 7.12. Mounting Files
- 7.13. Configure the bashrc file
- 7.14. Import the spacemacs package
- 7.15. Configure spacemacs
- 7.16. Install spacemacs
- 7.17. Configure the git environment
- 7.18. Setup ENTRYPOINT
- 7.19. Build the Docker image
- 7.20. Run the Docker image
- 7.21. Features on Spacemacs
- 8. Full Dockerfile
- 9. Related Documentation
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
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/
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"]