From 6a2abc6235b5e694ca38e832f30df3455308b9d9 Mon Sep 17 00:00:00 2001
From: "Glenn Y. Rolland" <glenux@glenux.net>
Date: Thu, 27 Mar 2025 10:14:20 +0100
Subject: [PATCH] feat(docker): modularize Docker setup for docs and slides

Introduces distinct Dockerfiles for documentation and slide projects, enhancing modularity and build efficiency. The previous monolithic structure was less flexible and caused longer build times.

- Added `DOCMACHINE_DOCS_ENABLE` and `DOCMACHINE_SLIDES_ENABLE` env variables to toggle features.
- Created `docker/Dockerfile.docs` for documentation builds, including necessary tools and dependencies.
- Created `docker/Dockerfile.slides` for slide builds to streamline setup.
- Updated main Dockerfile to include `python-is-python3` for compatibility, removing redundant symlinks.
- Enhanced LaTeX tools by adding `texlive-xetex` and extra fonts for improved PDF output.
---
 docker-compose.yml       | 28 ++++++++++++++---
 docker/Dockerfile        | 10 +++---
 docker/Dockerfile.docs   | 44 +++++++++++++++++++++++++++
 docker/Dockerfile.slides | 44 +++++++++++++++++++++++++++
 docker/entrypoint.sh     | 66 +++++++++++++++++++++++++---------------
 5 files changed, 159 insertions(+), 33 deletions(-)
 create mode 100644 docker/Dockerfile.docs
 create mode 100644 docker/Dockerfile.slides

diff --git a/docker-compose.yml b/docker-compose.yml
index c43cd44..1500b57 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,14 +2,34 @@
 version: "3.4"
 
 services:
-  app:
+  #  app:
+  #    build:
+  #      context: .
+  #      dockerfile: docker/Dockerfile
+  #    image: glenux/teaching-boilerplate
+  #    environment: {}
+  #    ports:
+  #      - 5100:5100
+  #      - 5200:5200
+
+  slides:
     build:
       context: .
-      dockerfile: docker/Dockerfile
-    image: glenux/teaching-boilerplate
+      dockerfile: docker/Dockerfile.slides
+    image: glenux/docmachine-slides:latest
+    environment: {}
+    ports:
+      - 5200:5200
+
+  docs:
+    build:
+      context: .
+      dockerfile: docker/Dockerfile.docs
+    image: glenux/docmachine-docs:latest
     environment: {}
     ports:
       - 5100:5100
-      - 5200:5200
+
+#  proxy:
 
 #
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 86d42a9..3ce51a0 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,8 +1,11 @@
 FROM node:18-bookworm-slim
 LABEL maintainer="Glenn ROLLAND glenux@glenux.net"
 
+ENV DOCMACHINE_DOCS_ENABLE=1
+ENV DOCMACHINE_SLIDES_ENABLE=1
+
 RUN apt-get update \
- && apt-get install -y --no-install-recommends python3 python3-pip pipenv python3-pypandoc \
+ && apt-get install -y --no-install-recommends python3 python3-pip python-is-python3 pipenv python3-pypandoc \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
  && truncate -s 0 /var/log/*log
@@ -16,7 +19,7 @@ RUN apt-get update \
 
 # Tools for building pdfs
 RUN apt-get update \
- && apt-get install -y --no-install-recommends make m4 chromium pandoc ghc libghc-pandoc-dev lmodern texlive-latex-recommended texlive-latex-base texlive-latex-extra \
+ && apt-get install -y --no-install-recommends make m4 chromium pandoc ghc libghc-pandoc-dev lmodern texlive-xetex texlive-fonts-extra texlive-fonts-recommended librsvg2-bin fonts-noto-mono \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
  && truncate -s 0 /var/log/*log
@@ -36,8 +39,7 @@ ENV LANG=C.UTF-8 \
     PIPENV_HIDE_EMOJIS=1 \
     PIPENV_VENV_IN_PROJECT=1
 
-RUN ln -sf python3 /usr/bin/python \
- && make prepare SYSTEM_INSTALL=1
+RUN make prepare SYSTEM_INSTALL=1
 
 ENTRYPOINT ["/app/docker/entrypoint.sh"]
 CMD ["watch"]
diff --git a/docker/Dockerfile.docs b/docker/Dockerfile.docs
new file mode 100644
index 0000000..86d42a9
--- /dev/null
+++ b/docker/Dockerfile.docs
@@ -0,0 +1,44 @@
+FROM node:18-bookworm-slim
+LABEL maintainer="Glenn ROLLAND glenux@glenux.net"
+
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends python3 python3-pip pipenv python3-pypandoc \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
+ && truncate -s 0 /var/log/*log
+
+# Tools for running the common parts
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends make build-essential inotify-tools gosu unzip curl rsync \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
+ && truncate -s 0 /var/log/*log
+
+# Tools for building pdfs
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends make m4 chromium pandoc ghc libghc-pandoc-dev lmodern texlive-latex-recommended texlive-latex-base texlive-latex-extra \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
+ && truncate -s 0 /var/log/*log
+
+# External tools
+# yq => manage YML
+RUN curl -sSL -o /usr/local/bin/yq \
+         https://github.com/mikefarah/yq/releases/download/v4.44.6/yq_linux_amd64 \
+ && chmod +x /usr/local/bin/yq
+
+COPY . /app
+COPY .marp /app/.marp
+WORKDIR /app
+
+ENV LANG=C.UTF-8 \
+    LC_ALL=C.UTF-8 \
+    PIPENV_HIDE_EMOJIS=1 \
+    PIPENV_VENV_IN_PROJECT=1
+
+RUN ln -sf python3 /usr/bin/python \
+ && make prepare SYSTEM_INSTALL=1
+
+ENTRYPOINT ["/app/docker/entrypoint.sh"]
+CMD ["watch"]
+
diff --git a/docker/Dockerfile.slides b/docker/Dockerfile.slides
new file mode 100644
index 0000000..ae5727c
--- /dev/null
+++ b/docker/Dockerfile.slides
@@ -0,0 +1,44 @@
+FROM node:18-bookworm-slim
+LABEL maintainer="Glenn ROLLAND glenux@glenux.net"
+
+# RUN apt-get update \
+#  && apt-get install -y --no-install-recommends python3 python3-pip pipenv python3-pypandoc \
+#  && apt-get clean \
+#  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
+#  && truncate -s 0 /var/log/*log
+
+# # Tools for running the common parts
+# RUN apt-get update \
+#  && apt-get install -y --no-install-recommends make build-essential inotify-tools gosu unzip curl rsync \
+#  && apt-get clean \
+#  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
+#  && truncate -s 0 /var/log/*log
+
+# Tools for building pdfs
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends make m4 chromium \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
+ && truncate -s 0 /var/log/*log
+
+# External tools
+# yq => manage YML
+RUN curl -sSL -o /usr/local/bin/yq \
+         https://github.com/mikefarah/yq/releases/download/v4.44.6/yq_linux_amd64 \
+ && chmod +x /usr/local/bin/yq
+
+COPY . /app
+COPY .marp /app/.marp
+WORKDIR /app
+
+ENV LANG=C.UTF-8 \
+    LC_ALL=C.UTF-8 \
+    PIPENV_HIDE_EMOJIS=1 \
+    PIPENV_VENV_IN_PROJECT=1
+
+RUN ln -sf /usr/bin/python3 /usr/bin/python \
+ && make prepare SYSTEM_INSTALL=1
+
+ENTRYPOINT ["/app/docker/entrypoint.sh"]
+CMD ["watch"]
+
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
index 224e8ea..2054080 100755
--- a/docker/entrypoint.sh
+++ b/docker/entrypoint.sh
@@ -6,36 +6,43 @@ set -e
 ARGS="$*"
 echo "Arguments: $ARGS"
 
-EXT_UID=${EXT_UID:-999}
-EXT_GID=${EXT_GID:-999}
+EXT_UID="${EXT_UID:-999}"
+EXT_GID="${EXT_GID:-999}"
+DOCMACHINE_DOCS_ENABLE="${DOCMACHINE_DOCS_ENABLE:-1}"
+DOCMACHINE_SLIDES_ENABLE="${DOCMACHINE_SLIDES_ENABLE:-1}"
 
+gx_workdir_prepare() {
+	# Create missing directories
+	mkdir -p _cache
+	mkdir -p _build
+	if [ "$DOCMACHINE_SLIDES_ENABLE" = "1" ]; then
+		mkdir -p .marp
+	fi
+	mkdir -p /home/appuser
+}
 
-# Create missing directories
-mkdir -p _cache
-mkdir -p _build
-mkdir -p .marp
-mkdir -p /home/appuser
+gx_users_prepare() {
+	# Create user with given ID if needed
+	if ! grep -q "^[^:]*:[^:]*:$EXT_UID:" /etc/group ; then
+  		groupadd -g "$EXT_GID" appuser
+	fi
 
-# Create user with given ID if needed
-if ! grep -q "^[^:]*:[^:]*:$EXT_UID:" /etc/group ; then
-  groupadd -g "$EXT_GID" appuser
-fi
+	# Create group with given ID if needed
+	if ! grep -q "^[^:]*:[^:]*:$EXT_UID:" /etc/passwd ; then
+  		useradd -r -u "$EXT_UID" -g appuser appuser
+	fi
 
-# Create group with given ID if needed
-if ! grep -q "^[^:]*:[^:]*:$EXT_UID:" /etc/passwd ; then
-  useradd -r -u "$EXT_UID" -g appuser appuser
-fi
-
-# echo "Setting permissions to $EXT_UID:$EXT_GID"
-# chown -R "$EXT_UID:$EXT_GID" _cache
-# chown -R "$EXT_UID:$EXT_GID" _build
-# chown -R "$EXT_UID:$EXT_GID" .marp
-# chown -R "$EXT_UID:$EXT_GID" /home/appuser
-# chown -R "$EXT_UID:$EXT_GID" slides
-# chown -R "$EXT_UID:$EXT_GID" docs
+	# echo "Setting permissions to $EXT_UID:$EXT_GID"
+	# chown -R "$EXT_UID:$EXT_GID" _cache
+	# chown -R "$EXT_UID:$EXT_GID" _build
+	# chown -R "$EXT_UID:$EXT_GID" .marp
+	# chown -R "$EXT_UID:$EXT_GID" /home/appuser
+	# chown -R "$EXT_UID:$EXT_GID" slides
+	# chown -R "$EXT_UID:$EXT_GID" docs
+}
 
+gx_docs_configure() {
 # Patch mkdocs configuration 
-# set -x
 if [ -f mkdocs-patch.yml ]; then
   # patch reference mkdocs with user-provided options
   yq eval-all '. as $item ireduce ({}; . * $item)' \
@@ -46,7 +53,16 @@ else
   # use reference mkdocs only (no options)
   ln -s mkdocs-source.yml mkdocs.yml
 fi
-# set +x
+}
+
+##
+## Main
+## 
+gx_workdir_prepare
+gx_users_prepare
+if [ "$DOCMACHINE_DOCS_ENABLE" = "1" ]; then
+	gx_docs_configure
+fi
 
 if [ "$1" = "supershell" ]; then
   exec bash