Class 7: Using Docker#

In this class we will discuss how to build and optimize a docker supporting creating UML diagrams a Java-based tool plantuml.

Automation: Build and Publish Docker with GitHub Actions#

Working but Suboptimal Docker#

The tool plantuml is shipped as a Java module, and needs Java Runtime Environment along with visualization software graphviz at runtime.

Hence, the content of Dockerfile may look as follows:

# Ubuntu-based image with Java Runtime Environment
FROM eclipse-temurin:20-jre
WORKDIR /usr/local/bin
COPY ./plantuml .
RUN chmod +x plantuml
RUN wget http://sourceforge.net/projects/plantuml/files/plantuml-nodot.1.2023.5.jar/download -O plantuml.jar
RUN apt-get update \
    && apt-get install -y graphviz

where plantuml is a shell wrapper that calls the java module on input files (add it on the top of your repo)

#!/bin/sh -e
java -jar /usr/local/bin/plantuml.jar "$@"

Once you build and publish this image (the size should be ~160 MB), test it (you can use GitHub CodeSpaces):

  • login and pull the docker from the repository

  • run the docker image interactively, e.g. docker run -it plantumldocker:latest

  • create a plantuml diagram diagram.iuml and copy into the docker container, e.g. docker cp diagram.iuml 3689309baac3:/usr/local where 3689309baac3 should be replaced by the container ID (check with docker ps)

  • convert the diagram into a figure inside the container, e.g. plantuml diagram.iuml

  • copy the figure to the host, e.g. docker cp 3689309baac3:/usr/local/diagram.png .

In case of problems, compare with the working version here.

Optimization: Lightweight Docker#

Docker optimization is important to save computational and environmental resources.

Docker optimization techniques

The general optimization strategy for Docker is to avoid any unnecessary content, which means

The following, more sophisticated, docker file consumes only 66 MB

# build a light Java Runtime Environment tailored to run plantuml
FROM eclipse-temurin:17-alpine as java_docker
WORKDIR /usr/local/bin
COPY src/plantuml .
RUN chmod +x plantuml
RUN apk update && apk add wget \
    && wget http://sourceforge.net/projects/plantuml/files/plantuml-nodot.1.2023.5.jar/download -O plantuml.jar
RUN apk add binutils
RUN $JAVA_HOME/bin/jlink \
         --add-modules java.base,java.datatransfer,java.desktop,java.logging,java.prefs,java.scripting,java.xml  \
         --strip-debug \
         --no-man-pages \
         --no-header-files \
         --compress=2 \
         --output ./jre

# move to a lightweight image and add other dependencies
FROM alpine:latest AS base_docker
WORKDIR /usr/local
COPY --from=java_docker /usr/local/bin/plantuml* ./bin/
COPY --from=java_docker /usr/local/bin/jre ./bin/jre
ENV PATH=$PATH:/usr/local/bin:/usr/local/bin/jre/bin
## package for vector grrahics and fonts for off-screen rendering (https://hub.docker.com/r/bellsoft/liberica-openjre-alpine)
RUN apk add --no-cache graphviz fontconfig ttf-dejavu

For more details, visit the DockerHub repo.

More#