1. 程式人生 > >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?

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:

FROM openjdk:8-jre-alpine
ENV SCALA_VERSION 2.12.7ENV 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.

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:

RUN addgroup -g 12345 appuser && \    adduser -u 12345 -D -G appuser appuserUSER appuser
WORKDIR /home/appuser

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:

docker build -t sbt .

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:

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 ;)