|
|
# 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 |