diff --git a/.gitignore b/.gitignore index b2450da..80f8998 100644 --- a/.gitignore +++ b/.gitignore @@ -22,5 +22,6 @@ *.lot *.lol *.pdf +!figures/*.pdf *.data.minted _minted*/ \ No newline at end of file diff --git a/backmatter/glossary.tex b/backmatter/glossary.tex index 6f5d73d..a151158 100644 --- a/backmatter/glossary.tex +++ b/backmatter/glossary.tex @@ -10,4 +10,7 @@ \newglossaryentry{host}{name={host},description={A named machine in the development environment, physical or virtual, with an assigned role and owner}} \newglossaryentry{kanban}{name={Kanban board},description={A visual board that - represents each unit of work as a card in a column denoting its state}} \ No newline at end of file + represents each unit of work as a card in a column denoting its state}} +\newglossaryentry{texlive}{name={TeX Live},description={A cross-platform + distribution of the \TeX\ engines, \LaTeX\ packages, fonts, and tools; the + distribution Overleaf compiles with}} \ No newline at end of file diff --git a/chapters/devopsCloudDockerDeployment.tex b/chapters/devopsCloudDockerDeployment.tex index e6a7488..476512c 100644 --- a/chapters/devopsCloudDockerDeployment.tex +++ b/chapters/devopsCloudDockerDeployment.tex @@ -55,7 +55,12 @@ static public directory. Both outcomes were verified locally and on AWS. \paragraph{Dockerfile} \inputminted{docker}{docker/color-buttons/Dockerfile} \paragraph{.dockerignore} -\inputminted{text}{docker/color-buttons/.dockerignore} +\begin{minted}{text} +node_modules +npm-debug.log +.git +.DS_Store +\end{minted} \section{Deployment Procedure} The commands below reproduce the recorded setup and successful configuration. @@ -116,9 +121,8 @@ to all container interfaces, and the AWS security group permits public HTTP. \section{Verification Evidence} The terminal screenshot shows container \texttt{70ed56f7fae8} running, the \texttt{80->3000/tcp} mapping, the server startup message, and -\texttt{HTTP/1.1 200 OK}. Public-browser screenshots record the initial white -state and the Blue and Red outcomes. These figures are supplied execution -evidence, not generated illustrations. +\texttt{HTTP/1.1 200 OK}. Public-browser screenshots record the Blue and Red outcomes. +These figures are supplied execution evidence, not generated illustrations. \begin{figure}[H] \centering diff --git a/chapters/devopsHosts.tex b/chapters/devopsHosts.tex index 2c57e13..205a6b7 100644 --- a/chapters/devopsHosts.tex +++ b/chapters/devopsHosts.tex @@ -7,11 +7,11 @@ \index{Amazon EC2} \section{Purpose} -This chapter names the hosts that will make up the development environment for -\CourseNumber\ and records the role, platform, and ownership of each. It is an -inventory of intent: no machine listed here has been provisioned, and the chapter therefore -presents no execution \gls{evidence}. It is expected to grow as later -assignments add services to the environment. +This chapter names the hosts that make up the development environment for +\CourseNumber\ and records the role, platform, owner, and status of each. +Hosts in service are described here at inventory level; their configuration +and execution \gls{evidence} are recorded in the chapter for the activity that +uses them. The inventory may grow or change depending on assignment requirements. \section{Naming Convention} \index{hosts!naming} @@ -29,22 +29,23 @@ The \textbf{Status} column distinguishes machines already in use from those that will be configured in a later assignment. A host is marked \emph{In service} only once it exists and is reachable. -\begin{tabularx}{\linewidth}{L{3.0cm}YL{3.3cm}L{2.0cm}} -\caption{Planned Host Inventory\label{Table:HostInventory}}\\ +\begin{tabularx}{\linewidth}{L{3.5cm}YL{3.0cm}L{2.2cm}} +\caption{Host Inventory\label{Table:HostInventory}}\\ \toprule \textbf{Host name} & \textbf{Role} & \textbf{Platform} & \textbf{Status}\\ \midrule \endfirsthead -\multicolumn{4}{l}{\small\itshape Planned Host Inventory (continued)}\\ +\multicolumn{4}{l}{\small\itshape Host Inventory (continued)}\\ \toprule \textbf{Host name} & \textbf{Role} & \textbf{Platform} & \textbf{Status}\\ \midrule \endhead \bottomrule \endlastfoot +\texttt{ssw590-group-web} & Group deployment target. Runs the website in \ChapterRef{CloudDockerDeployment}. & Ubuntu 26.04 LTS on Amazon EC2, \texttt{t3.micro} & In service\\ \texttt{ssw590-dev-01} & Primary Linux host for the course. Target for service configuration, deployment exercises, and command-line work. & Ubuntu Server LTS on Amazon EC2 & Planned\\ -\texttt{ssw590-build-01} & Build and integration host, kept separate from the deployment target so that a failed build cannot disturb a running service. To be provisioned only if a later assignment requires it. & Ubuntu Server LTS on Amazon EC2 & Conditional\\ \end{tabularx} \section{Access and Ownership} \index{hosts!access model} \index{least privilege} -All hosts listed above are owned and administered by the author. The following -rules govern access to the Linux hosts once they are provisioned. +\texttt{ssw590-group-web} is shared by both authors and runs under Victor's AWS account, +where each author has a separate IAM identity. The following rules are the target access policy +for course Linux hosts: \begin{itemize}[leftmargin=*] \item Interactive access is by \gls{ssh} public key only. @@ -55,29 +56,24 @@ rules govern access to the Linux hosts once they are provisioned. \item Day-to-day work is performed by an unprivileged account. Administrative rights are granted per command rather than by general membership in the \texttt{sudo} group. -\item Should a teammate require access after teams are formalized, that person - receives a separate named account rather than a shared login, so that +\item Teammates who require access after teams are formalized + receive a separate named account rather than a shared login, so that access can be revoked individually and actions remain attributable. \end{itemize} \section{Cost and Cleanup} \index{hosts!cost} \index{hosts!teardown} -The Linux hosts are expected to run on the smallest instance size that supports -the coursework, under whatever free-tier or credit allowance the account -provides, with a billing alarm configured before the first instance is -launched. Compute is billed per instance-hour, and attached storage whether or -not the instance is running, so each additional host adds cost independently of -how heavily it is used: provisioning \texttt{ssw590-build-01} alongside -\texttt{ssw590-dev-01} would approximately double the compute cost of the -environment. It is therefore left unprovisioned until an assignment requires -builds to be isolated from the deployment target, and would be stopped between -uses rather than run continuously; only \texttt{ssw590-dev-01} needs to remain -available at all times. +\texttt{ssw590-group-web} runs on a \texttt{t3.micro} instance and is covered +by a monthly AWS budget alert. Compute is billed per +instance-hour, and attached storage and the public IPv4 address are billed as +well, so each additional host adds cost independently of how heavily it is +used: provisioning \texttt{ssw590-build-01} would approximately double the +compute cost of the environment. It is therefore left unprovisioned unless +required in the future, and would be stopped between uses rather than run continuously. -Each planned host is disposable. Teardown consists of terminating the instance, -deleting the attached storage volume, and releasing any static address reserved -for it; a static address left reserved after the instance is gone continues to -be billed. Because the \gls{ami} and the configuration steps are recorded, a -terminated host can be rebuilt rather than preserved, which is why teardown is -treated as routine rather than exceptional. \ No newline at end of file +Course hosts are disposable. Teardown consists of terminating the instance and +deleting its storage volume. \texttt{ssw590-group-web} uses an automatically +assigned public address rather than a reserved static address, so there is no +address to release; its address changes if the instance is stopped and +started. \ No newline at end of file diff --git a/chapters/devopsIntroduction.tex b/chapters/devopsIntroduction.tex index a95ec06..820686b 100644 --- a/chapters/devopsIntroduction.tex +++ b/chapters/devopsIntroduction.tex @@ -10,7 +10,7 @@ This document records the configuration of the development environment used for \CourseNumber\ and the working practices followed to produce it. Each chapter covers one subject, and each assignment adds or revises chapters as recorded in the document history. The latest revision for Assignment~\AssignmentNumber\ -adds \ChapterRef{CloudDockerDeployment} and a draft \ChapterRef{ProjectProposal}. +adds \ChapterRef{CloudDockerDeployment}, \ChapterRef{LatexDocker}, and \ChapterRef{ProjectProposal}. Earlier coursework chapters are retained. \section{Scope and Constraints} @@ -18,8 +18,8 @@ Earlier coursework chapters are retained. The following constraints apply to this revision. \begin{itemize}[leftmargin=*] -\item The earlier hosts chapter records planned machines. The cloud deployment - chapter records the newly provisioned EC2 website and its actual configuration. +\item The hosts chapter inventories the hosts in service and those still planned. + The cloud deployment chapter records the newly provisioned EC2 website and its actual configuration. \item Linux Commands evidence was recorded locally under WSL. Assignment 3 deployment commands were executed on Ubuntu 26.04 on EC2. Supplied screenshots distinguish those environments. @@ -29,8 +29,7 @@ The following constraints apply to this revision. \item This is a group submission. Chapters written before teams were formed were prepared individually and are identified as such in the document history. \item The document is authored in \LaTeX\ and compiled with pdf\LaTeX\ on - Overleaf. The board is hosted in GitHub Projects. The planned environment - targets Amazon EC2. + Overleaf. The board is hosted in GitHub Projects. The group deployment runs on Amazon EC2. \end{itemize} \section{Deliverables and Due Date} @@ -48,10 +47,15 @@ Team policy & Group submission\\ \bottomrule \index{document organization} \ChapterRef{KanbanSetup} describes the tool selected for the board, the steps taken to configure it, the policy governing each column, and the inventory of cards. -\ChapterRef{Hosts} names the hosts to be configured and their roles. +\ChapterRef{Hosts} inventories the hosts in service and those planned, with their roles. \ChapterRef{Passwords} defines the account and password rules for those hosts. \ChapterRef{LinuxCommands} records the Linux working-directory setup and the problem-set solutions. \ChapterRef{AIPromptLog} records AI assistance used in preparing this document. +\ChapterRef{CloudDockerDeployment} records the class-based Color Buttons website, +its container, and its deployment to Amazon EC2. +\ChapterRef{LatexDocker} records a TeX Live container that compiles \LaTeX\ documents +as Overleaf does. +\ChapterRef{ProjectProposal} proposes the course project and the DevSecOps tools it will compare. This document is derived from the \CourseNumber\ assignment template credited on the Template Attribution page. The template's instructional example chapter and diff --git a/chapters/devopsLatexDocker.tex b/chapters/devopsLatexDocker.tex new file mode 100644 index 0000000..64aa70d --- /dev/null +++ b/chapters/devopsLatexDocker.tex @@ -0,0 +1,87 @@ +\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} \ No newline at end of file diff --git a/devopsAssignment.tex b/devopsAssignment.tex index f53869f..a35814b 100644 --- a/devopsAssignment.tex +++ b/devopsAssignment.tex @@ -38,9 +38,9 @@ \definecolor{devopsLightBlue}{RGB}{232,240,247} % Replace these values for each assignment. -\newcommand{\AssignmentTitle}{Cloud Docker Deployment and Project Proposal} +\newcommand{\AssignmentTitle}{Cloud Docker Deployment, LaTeX Docker, and Project Proposal} \newcommand{\AssignmentNumber}{3} -\newcommand{\DocumentVersion}{3.0} +\newcommand{\DocumentVersion}{3.1} \newcommand{\DocumentStatus}{Group Report Draft} \newcommand{\CourseNumber}{SSW 590} \newcommand{\CourseName}{DevOps} @@ -56,7 +56,7 @@ pdfauthor={\Author}, pdfcreator={Darian Muresan, Ph.D., with OpenAI Codex and Anthropic Claude Code}, pdfsubject={Development environment configuration record for \CourseNumber\ Assignment \AssignmentNumber\ }, - pdfkeywords={DevOps, Kanban, password, host, development environment, Amazon EC2, GitHub Projects} + pdfkeywords={DevOps, Kanban, password, host, development environment, Amazon EC2, GitHub Projects, Docker, TeX Live} } \newcolumntype{Y}{>{\raggedright\arraybackslash}X} @@ -122,6 +122,7 @@ \include{chapters/devopsPasswords} \include{chapters/devopsLinuxCommands} \include{chapters/devopsCloudDockerDeployment} +\include{chapters/devopsLatexDocker} \include{chapters/devopsProjectProposal} \appendix diff --git a/docker/latex-compiler/.dockerignore b/docker/latex-compiler/.dockerignore new file mode 100644 index 0000000..f0809a6 --- /dev/null +++ b/docker/latex-compiler/.dockerignore @@ -0,0 +1,2 @@ +sample +*.pdf diff --git a/docker/latex-compiler/Dockerfile b/docker/latex-compiler/Dockerfile new file mode 100644 index 0000000..0fc876c --- /dev/null +++ b/docker/latex-compiler/Dockerfile @@ -0,0 +1,20 @@ +FROM debian:trixie-slim + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + texlive-latex-base \ + texlive-latex-recommended \ + texlive-fonts-recommended \ + lmodern \ + latexmk \ + && rm -rf /var/lib/apt/lists/* + +# Run as an unprivileged user; keep TeX's font cache out of the mounted folder. +RUN useradd --create-home --uid 1000 latex +ENV TEXMFVAR=/tmp/texmf-var +USER latex +WORKDIR /work + +ENTRYPOINT ["latexmk", "-pdf", "-interaction=nonstopmode", "-halt-on-error"] +CMD ["hello.tex"] diff --git a/docker/latex-compiler/sample/hello.tex b/docker/latex-compiler/sample/hello.tex new file mode 100644 index 0000000..fb1599d --- /dev/null +++ b/docker/latex-compiler/sample/hello.tex @@ -0,0 +1,44 @@ +\documentclass[11pt]{article} +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{amsmath} +\usepackage{booktabs} +\usepackage[colorlinks=true]{hyperref} + +\title{SSW 590 --- LaTeX Docker Test} +\author{Payton Bates and Victor Del Rio Foces} +\date{\today} + +\begin{document} +\maketitle + +\section{Purpose} +This document was compiled by pdf\LaTeX\ from TeX Live inside a Docker +container. Section~\ref{sec:checks} lists its features. + +\section{Checks}\label{sec:checks} +\begin{itemize} + \item Mathematics: $e^{i\pi} + 1 = 0$ and + \begin{equation} + \sum_{k=1}^{n} k = \frac{n(n+1)}{2}. + \end{equation} + \item Cross-reference: Equation~\eqref{eq:area} resolves. + \item Table: +\end{itemize} + +\begin{center} +\begin{tabular}{lr} +\toprule +Item & Value \\ +\midrule +Engine & pdf\LaTeX \\ +Distribution & TeX Live \\ +\bottomrule +\end{tabular} +\end{center} + +\begin{equation}\label{eq:area} + A = \pi r^2 +\end{equation} + +\end{document} diff --git a/figures/latex-docker-build.png b/figures/latex-docker-build.png new file mode 100644 index 0000000..b8e8ecb Binary files /dev/null and b/figures/latex-docker-build.png differ diff --git a/figures/latex-docker-hello.pdf b/figures/latex-docker-hello.pdf new file mode 100644 index 0000000..9f00ce2 Binary files /dev/null and b/figures/latex-docker-hello.pdf differ diff --git a/figures/latex-docker-output.png b/figures/latex-docker-output.png new file mode 100644 index 0000000..89a7533 Binary files /dev/null and b/figures/latex-docker-output.png differ diff --git a/frontmatter/abstract.tex b/frontmatter/abstract.tex index 22a9ff8..d15c062 100644 --- a/frontmatter/abstract.tex +++ b/frontmatter/abstract.tex @@ -2,8 +2,9 @@ This document records the development environment and working practices used in SSW 590. It is extended with each assignment, and the document history identifies what each revision changed. Its chapters currently cover planning and tracking the work, the hosts and accounts that make up the environment, and the -command-line and operational work performed in it. Environments specified here -are plans, and the actual provisioning will be done in the future. +command-line and operational work performed in it. The host inventory +distinguishes machines in service from those still planned. Assignment 3 adds the class-based Color Buttons application deployed in Docker -on Amazon EC2, with public browser and terminal verification evidence, and a -draft proposal to compare GitHub Actions with Jenkins. +on Amazon EC2, with public browser and terminal verification evidence; +a Docker container that compiles \LaTeX\ documents as Overleaf does; +and a proposal to compare GitHub Actions with Jenkins. diff --git a/frontmatter/devopsDocumentHistory.tex b/frontmatter/devopsDocumentHistory.tex index 59e53b8..2eea9e5 100644 --- a/frontmatter/devopsDocumentHistory.tex +++ b/frontmatter/devopsDocumentHistory.tex @@ -11,6 +11,7 @@ link each entry to the changed chapter, table, figure, or controlled artifact. \multicolumn{4}{l}{\small\itshape Document Update History (continued)}\\ \toprule \textbf{Date / Version} & \textbf{Author Initials} & \textbf{Change} & \textbf{Changed At}\\ \midrule \endhead \bottomrule \endlastfoot +October 5, 2026 / 3.1 & PCB & Added the LaTeX Docker chapter for compiling a sample document with its sources, build and run commands, and test evidence. Updated the document title, keywords, glossary, abstract, introduction, and hosts. & \ChapterRef{LatexDocker}, \ChapterRef{Hosts}, \ChapterRef{Introduction}, \ChapterRef{CloudDockerDeployment}\\ October 5, 2026 / 3.0 & VDRF & Added AWS Docker deployment, class-based website sources, execution evidence, and a draft tool-comparison proposal. Updated Assignment 3 metadata and AI log. & \ChapterRef{CloudDockerDeployment}, \ChapterRef{ProjectProposal}, \ChapterRef{AIPromptLog}\\ September 27, 2026 / 2.1 & VDRF & Added Victor's Q1--Q40 execution screenshots and result interpretation; distinguished the two environments and command variants. & \ChapterRef{LinuxCommands}, \ChapterRef{AIPromptLog}\\ September 26, 2026 / 2.0 & PCB, VDRF & Added the Linux Commands chapter: working-directory setup with terminal input/output figures, command explanations and interpretation of results, and solutions to the Linux problem set. Updated document metadata and authorship for Assignment 2 and the two-person team. & \ChapterRef{LinuxCommands}, \ChapterRef{Introduction}, \ChapterRef{Hosts}, \ChapterRef{AIPromptLog}\\