Files
SSW590-DevOps/chapters/devopsLatexDocker.tex
T

87 lines
3.7 KiB
TeX

\chapter{LaTeX Docker}
\ChapterLabel{LatexDocker}
\index{Docker}\index{TeX Live}\index{LaTeX Docker}
\section{Purpose and Scope}
This chapter records a Docker container that compiles a
\LaTeX\ document with \gls{texlive}, the distribution Overleaf uses to compile
projects.\footnote{\url{https://www.overleaf.com/learn/latex/Overleaf_and_TeX_Live}}
Like Overleaf, it drives pdf\LaTeX\ with \texttt{latexmk}, which reruns the
engine until cross-references settle.
The container is a command-line compiler. It reads a
\texttt{.tex} file from a mounted folder, writes the PDF back to that folder,
and exits. It opens no network ports. The image is not deployed to a course
host or published to a registry; it was built and tested locally under WSL on
Payton's workstation.
\section{Design}
\begin{tabularx}{\linewidth}{L{3.6cm}Y}
\toprule \textbf{Decision} & \textbf{Choice and rationale}\\ \midrule
Base image & \texttt{debian:trixie-slim}. Debian packages its TeX Live release, so the image needs no separate TeX Live installer or mirror.\\
TeX Live packages & \texttt{texlive-latex-base}, \texttt{texlive-latex-recommended}, \texttt{texlive-fonts-recommended}, and \texttt{lmodern}, installed without recommended extras. This covers common packages such as \texttt{amsmath}, \texttt{hyperref}, and \texttt{booktabs} while avoiding the multi-gigabyte full distribution.\\
Build driver & \texttt{latexmk} with pdf\LaTeX, nonstop mode, and halt on the first error, so a failed compile returns a nonzero exit status.\\
Interface & The entrypoint is the compiler; the default argument is \texttt{hello.tex}, and any other file name can be passed to \texttt{docker run}.\\
Source and output & The document folder is bind-mounted at \path{/work}, so sources are not baked into the image and the PDF is written to the host.\\
Privilege & The image defaults to an unprivileged \texttt{latex} user; at run time the container uses the invoking user's IDs so output files are owned by that user. The font cache is kept in \path{/tmp}, outside the mounted folder.\\
\bottomrule
\end{tabularx}
\section{Container Sources}
\paragraph{Dockerfile}
\inputminted{docker}{docker/latex-compiler/Dockerfile}
\paragraph{.dockerignore}
The sample folder is mounted at run time, so it is excluded from the build
context.
\begin{minted}{text}
sample
*.pdf
\end{minted}
\paragraph{Sample document: sample/hello.tex}
The document exercises T1 fonts, mathematics, a \texttt{booktabs} table,
hyperlinks, and a forward equation reference that resolves only on a second
pdf\LaTeX\ pass.
\inputminted{latex}{docker/latex-compiler/sample/hello.tex}
\section{Build and Run}
All commands run in a WSL shell from \path{docker/latex-compiler}.
\subsection{Build the Image}
\begin{minted}{bash}
docker build -t ssw590-latex .
docker image ls ssw590-latex
\end{minted}
\subsection{Compile the Sample Document}
\begin{minted}{bash}
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD/sample:/work" ssw590-latex
ls -l sample/hello.pdf
grep "Output written" sample/hello.log
\end{minted}
\texttt{-{}-rm} deletes the container when compilation ends. \texttt{-{}-user}
makes the generated files belong to the WSL user instead of the container
user.
\section{Test Evidence}
\begin{figure}[H]
\centering
\includegraphics[width=\linewidth]{figures/latex-docker-build.png}
\caption{TeX Live image build under WSL.}
\label{fig:latex-docker-build}
\end{figure}
\begin{figure}[H]
\centering
\includegraphics[width=\linewidth]{figures/latex-docker-output.png}
\caption{Information about the produced PDF.}
\label{fig:latex-docker-output}
\end{figure}
\begin{figure}[H]
\centering
\fbox{\includegraphics[width=0.8\linewidth,page=1]{figures/latex-docker-hello.pdf}}
\caption{First page of the PDF produced by the container.}
\label{fig:latex-docker-hello}
\end{figure}