First Dockerization documentation authored by Daniel Kluge's avatar Daniel Kluge
# Dockerization
TODO
Dockerizing the project is challanging because of two things:
1. the classpath setup done in [start_component.sh](implementation/start_component.sh)
2. the GPIO pins of the Raspberry Pi must be accessable from inside the container for the lights
## Dockerfile walkthrough
The Dockerfile is used to build the container.
It hold instructions which files to copy and commands to run.
I choosed a multistage approach.
This means first in a dedicated container all dependencies get resolved and files compiled.
They are copied to a second container which serves the purpose of the runtime environment.
### Build stage
```Dockerfile
FROM maven:3-jdk-11-slim as build
```
In the first line is defined which container we use for our (build) stage.
The `as build` names the stage.
Because the project uses Maven as dependency manager and Java 11 as version we use the [Apache Maven container](https://hub.docker.com/_/maven) with the tag (a tag is like a version) `3-jdk-11-slim`.
```Dockerfile
WORKDIR /root/app
```
This sets the current working directory inside the container.
When we run a command inside the container it is executed in this context.
```Dockerfile
COPY pom.xml .
```
This copies the `pom.xml` file from our project inside the container.
Because we set a working directory `.` actually means `/root/app`, so the file is located at `/root/app/pom.xml` inside the container.
```Dockerfile
RUN mvn dependency:resolve
```
This downloads all dependencies defined in the `pom.xml`.
As default location they are saved to `$HOME/.m2`.
Because we are the user `root` inside the container the dependencies are saved at `/root/.m2`.
```Dockerfile
RUN mvn dependency:build-classpath -Dmdep.outputFile=classpath.txt
```
This builds the classpath and saves it to `classpath.txt` in the working directory.
```Dockerfile
COPY src src
```
This copies the `src` folder from our project directory to current working directory inside the container.
```Dockerfile
RUN mvn compile
```
Here we finally build all our class files.
Our build stage is done.
It followes the container defintion for our final container.
###
```Dockerfile
FROM openjdk:11-jre
```
For this container we use the [OpenJDK container](https://hub.docker.com/_/openjdk) as base. And because everything is already compiled we only need the `jre` variant.
```Dockerfile
WORKDIR /root/app
```
Again, this sets the current working directory inside the container.
```Dockerfile
COPY --from=build /root/.m2 /root/.m2
COPY --from=build /root/app/classes classes
COPY --from=build /root/app/classpath.txt .
```
Here all files we need from the build stage are copied to our container.
```Dockerfile
COPY start_component_docker.sh start_component.sh
```
This copies the `start_component_docker.sh` file into the container, renaming it in the process.
```Dockerfile
ENTRYPOINT export CLASSPATH=/root/app/classes:$(cat /root/app/classpath.txt) && /root/app/start_component.sh
```
This sets the entrypoint of the container that is executed when the container is started.
The first part of the command exports the `CLASSPATH` that needs to be set to resolve all the used packages inside the Java files.
It would probably be cleaner to use the `ENV` definition in the Dockerfile but setting an environment based on command output is [currently not possible](https://github.com/moby/moby/issues/29110).
\ No newline at end of file