How to build a project inside a Docker container

How to build a project inside a Docker container

I wanted to participate in the Hacktoberfest 2018, but one thing kept worrying me. I had to download someone’s code from the Internet and run it on my machine. I don’t have time to review a vast project to check if nothing fishy happens while running tests.

Of course, I could choose to work only on well-known projects with many respected contributors. In this case, I could safely assume that there is no harmful code in the repository. What about other projects?

Docker

I decided that the best available option is building and testing the projects inside a Docker container. I did not want to copy the code to a Docker image and download all dependencies every time I want to run tests. So I needed a way to cache them between the runs.

I wanted to contribute to Scala projects, so I needed to run SBT inside Docker. I ended up with this Dockerfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM openjdk:8-jre-alpine
ENV SCALA_VERSION 2.12.7
ENV SBT_VERSION 1.2.3

RUN \
apk add bash && \
apk add --no-cache curl && \
cd /tmp && \
curl -fsSOL https://piccolo.link/sbt-$SBT_VERSION.tgz && \
tar -xvzf sbt-$SBT_VERSION.tgz && \
mv /tmp/sbt /usr/lib && \
rm /tmp/sbt-$SBT_VERSION.tgz && \
ln -s /usr/lib/sbt/bin/* /usr/local/bin && \
sbt sbtVersion

It downloads the necessary dependencies and SBT, extracts the files, removes redundant files and sets symbolic links to the sbt tools.

Are you interested in data engineering?

Check out my other blog https://easydata.engineering

User

Almost good. Such a Dockerfile runs the code as the root user. Still not a good idea, even inside Docker. So I added more code to Dockerfile:

1
2
3
4
5
RUN addgroup -g 12345 appuser && \
    adduser -u 12345 -D -G appuser appuser
USER appuser

WORKDIR /home/appuser

Build the image

What now? Now I have to build the image and set its name to something meaningful, so later I can run it.

To build the Docker image you have to run the following command in terminal:

1
docker build -t sbt .

Run the container

When the image is ready, all I need is to run it in the interactive mode and mount the project directory as one of the directories in the Docker container. I must also mount the .ivy2 directory, so I have a place to cache dependencies between runs of the Docker image.

The next command does the job:

1
docker run -v $(pwd .):/home/appuser -v $(pwd .)/.packages:/home/appuser/.ivy2 -it sbt:latest

Now nothing stops me from contributing to someone else’s projects ;)


Remember to share on social media!
If you like this text, please share it on Facebook/Twitter/LinkedIn/Reddit or other social media.

If you watch programming live streams, check out my YouTube channel.
You can also follow me on Twitter: @mikulskibartosz

If you want to hire me, send me a message on LinkedIn or Twitter.


Bartosz Mikulski
Bartosz Mikulski * data scientist / software/data engineer * conference speaker * organizer of School of A.I. meetups in Poznań * co-founder of Software Craftsmanship Poznan & Poznan Scala User Group