Docker container for Ubuntu development - GoldenCheetah/GoldenCheetah GitHub Wiki

Summary

This How-To describes how to create a Docker image with the whole environment needed to compile for Ubuntu. It is not necessary to create a Virtual Machine. Docker allows to execute code in an isolated framework (the container), sharing the kernel with the host machine, but with a different operating system version, if required.

The advantage is that the configuration or steps needed to have the container running is reduced to a single file (Dockerfile) that is in charge of installing all the packages and configure the environment inside the docker container, not affecting the host machine

This has been tested in a host machine with Ubuntu 23.04.

The image is based on Ubuntu 20.04, the current version used to generate the development version binaries for Golden Cheetah 3.6 as of september 2023.

Requirements

  • It has been tested on x64 architecture and Ubuntu as host machine, although potentially it should work with another Linux dist. and with arm architectures.
  • It is necessary to have Docker installed in the host machine. It is documented in Docker's installation guide page.
  • This is the content of Dockerfile:
FROM ubuntu:20.04

RUN useradd --create-home appuser

#Install necessary packages
RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y sudo git wget automake libtool bison flex curl software-properties-common fuse libfuse2 && usermod -aG sudo appuser
RUN rm -rf /var/lib/apt/lists/*

#User must have 'sudo' privileges
#Also, it is necessary to set a timezone to avoid interruptions during script execution (can be an environment variable)
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && rm -f /etc/localtime && ln -s /usr/share/zoneinfo/Europe/Madrid /etc/localtime

WORKDIR /home/appuser
USER appuser
#$TRAVIS_BUILD_DIR is used by before_install.sh script
ENV TRAVIS_BUILD_DIR=/home/appuser/Git/GoldenCheetah

#Clone the repository
#To avoid ssh confirmation of github.com
RUN mkdir ~/Git && mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN git clone https://github.com/GoldenCheetah/GoldenCheetah.git $TRAVIS_BUILD_DIR


#Changes in the script to work unattended and with no errors
RUN sed -i "/E298A3A825C0D65DFD57CBB651716619E084DAB9/c\mkdir -p ~/.gnupg && echo \"disable-ipv6\" >> ~/.gnupg/dirmngr.conf && sudo apt-key adv --homedir ~/.gnupg --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9" $TRAVIS_BUILD_DIR/travis/linux/before_install.sh
RUN sed -i "/r-base-dev/c\sudo apt-get install -qq r-base-dev" $TRAVIS_BUILD_DIR/travis/linux/before_install.sh

RUN mkdir $TRAVIS_BUILD_DIR/D2XX

# This is to avoid interaction when installing VLC (from https://stackoverflow.com/questions/63476497/docker-build-with-ubuntu-18-04-image-hangs-after-prompting-for-country-of-origin)
RUN echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections

## To avoid error installing sip-4.19.8 (fails: from distutils import sysconfig)
#(https://stackoverflow.com/questions/63823964/importerror-cannot-import-name-sysconfig-from-distutils-usr-lib-python3-8)
RUN sed -i '/python3.7 configure.py/ i sudo apt-get install -qq python3.7-distutils' $TRAVIS_BUILD_DIR/travis/linux/before_install.sh
RUN cd $TRAVIS_BUILD_DIR && DEBIAN_FRONTEND=noninteractive ./travis/linux/before_install.sh
RUN cd $TRAVIS_BUILD_DIR && rm awscliv2.zip libftd2xx-x86_64-1.4.27.tgz sip-4.19.8.tar.gz v0.1.1git1.tar.gz


#For after_success.sh script
RUN sudo addgroup fuse && sudo adduser appuser fuse

#Adjust the number of parallel processes in make to the physical processors
RUN sed -i "s/-j4/-j$(lscpu -p | egrep -v '^#' | sort -u -t, -k 2,4 | wc -l)/" $TRAVIS_BUILD_DIR/travis/linux/script.sh

Build the image and compile Golden Cheetah

  • Copy Dockerfile in a directory and cd to that directory

  • Generate the image. This step needs only been run once. The image is stored in the local Docker library

    docker build -t ubuntu_20.04_goldencheetah .

  • Then, you can run a container based on that image. In fact you can run as many containers as you want, just giving them different names. It is necessary to add some options in order to fuse devices to be managed by the container (needed by appimage stuff, I guess):

    docker run -d -it --device /dev/fuse --cap-add SYS_ADMIN --security-opt apparmor:unconfined -h ubuntu20.04_GC --name ubuntu20.04_GC ubuntu_20.04_goldencheetah sleep infinity

    This command is an example of starting the container, and leaving it running, but you can decide to start in any other way

  • Enter in a terminal of the container, executing bash command:

    docker exec -it ubuntu20.04_GC bash

  • Then, in the container, you can follow the steps to build the binary and the appimage. For example:

 cd $TRAVIS_BUILD_DIR
 git pull
 ./travis/linux/before_script.sh
 ./travis/linux/script.sh
 ./travis/linux/after_success.sh

Next Steps

It follows the steps to build Golden Cheetah with the current scripts and configuration. The procedure can be adapted to the user with knowledge in Docker. For example, compiling with the start of the container, no need to execute anything manually, exporting the binary, etc

Also, other OS can be taken into account. I do not have the necessary knowlwdge on them nor on Dockerfile

The container itselt behaves as a system running Ubuntu 20.04. With Visual Studio Code it is possible to debug code remotely inside a docker container, also git works the same as in a physical machine,... you can use the container as a complete development environment.