\chapter{Digital Ocean Docker Deployment} \ChapterLabel{DigitalOceanDockerDeployment} This chapter documents the deployment of the Two Buttons Node/Express website to a DigitalOcean Droplet using Docker, and the updated class-based JavaScript. \section{Create the Droplet and Deploy Docker} The Droplet was created using DigitalOcean's Docker 1-Click image on Ubuntu in the New York region. The Basic Regular plan provides one virtual CPU, 1 GiB of RAM, and 25 GiB of SSD storage. The server has a public IPv4 address, \texttt{137.184.97.250}, and uses SSH key authentication. No additional storage or automated backups were configured. The Docker image supplies the Docker environment used to build and run the application. The website is available at the following deployment addresses: \begin{itemize} \item HTTPS: \url{https://137-184-97-250.nip.io/} \item HTTP: \url{http://137.184.97.250/} \end{itemize} \section{Deployment Steps and Commands} \subsection{Upload the Project and Connect to the Droplet} The following commands were run in Windows PowerShell. The first command selects the original project directory, the second copies the application folder to the Droplet, and the third opens an SSH session. The local directory is specific to the computer used for the original deployment. \begin{minted}[fontsize=\small,breaklines,frame=single]{powershell} Set-Location 'D:\Self Projects\SSW590-Docker-Assignment' scp -r .\color-buttons-app root@137.184.97.250:/root/ ssh root@137.184.97.250 \end{minted} \subsection{Build and Run the Application Container} After connecting to the Droplet, Docker was checked and the uploaded project was built into an image tagged \texttt{color-buttons-app:class-based}. The image was then started as the container \texttt{color-buttons-site}. \begin{minted}[fontsize=\small,breaklines,frame=single]{bash} docker --version cd /root/color-buttons-app docker build -t color-buttons-app:class-based . docker run -d --name color-buttons-site --restart unless-stopped -p 80:3000 color-buttons-app:class-based docker ps curl -I http://127.0.0.1/ docker logs --tail 20 color-buttons-site \end{minted} The \texttt{-d} option runs the container in the background. The \texttt{-p 80:3000} mapping sends traffic received on the Droplet's HTTP port 80 to Express on port 3000 inside the container. The restart policy restarts the container after a Droplet reboot unless it was explicitly stopped. The remaining commands inspect the running container, request the local website's HTTP response headers, and display recent application logs. \subsection{Enable HTTPS with Caddy} The hostname \texttt{137-184-97-250.nip.io} resolves to the Droplet's public IP address. Caddy acts as a reverse proxy: it receives HTTPS requests and forwards them to the application over a shared Docker network. The project's \texttt{Caddyfile} configures that proxy. The following commands create the network, download Caddy, validate the configuration, connect the app, and start the HTTPS container. \begin{minted}[fontsize=\small,breaklines,frame=single]{bash} docker network create color-net docker pull caddy:2-alpine docker run --rm -v /root/color-buttons-app/Caddyfile:/etc/caddy/Caddyfile:ro caddy:2-alpine caddy validate --config /etc/caddy/Caddyfile docker network connect color-net color-buttons-site docker run -d --name color-buttons-caddy --restart unless-stopped --network color-net -p 443:443 -v /root/color-buttons-app/Caddyfile:/etc/caddy/Caddyfile:ro -v caddy_data:/data -v caddy_config:/config caddy:2-alpine \end{minted} Caddy publishes HTTPS on port 443 and obtains and renews a publicly trusted certificate. The \texttt{caddy\_data} volume preserves certificate data, while the configuration file is mounted read-only. HTTP on the numeric IP address continues to reach the original application container on port 80. \subsection{Deployment Verification} The handoff records the following successful checks from the deployment: \begin{itemize} \item Both Blue and Red click handlers passed a local behavior check. \item \texttt{docker ps} showed the application container running with port 80 mapped to container port 3000. \item The local HTTP check and a public website request returned \texttt{HTTP/1.1 200 OK}. \item The public site served \path{public/app.js} containing the new class and both button handlers. \item The HTTPS website returned \texttt{HTTP/1.1 200 OK} with normal certificate verification, without bypassing certificate checks. \item The student opened the HTTPS website and confirmed that both buttons changed the background to the corresponding color. \end{itemize} These are the results recorded in the handoff, rather than new checks performed while preparing this chapter. Website screenshots were not included in the handoff and have not been added as evidence. \section{Class-Based JavaScript and UML Design} The updated website uses the \texttt{BackgroundColorController} class in \path{public/app.js} to organize its button behavior. The class holds references to both buttons and the page element being updated. Its constructor accepts these three elements, and its \texttt{setBackgroundColor} method provides the shared operation for changing the page's background. Class-based JavaScript still uses methods; the change groups the relevant data and behavior inside a class instead of leaving the behavior in separate standalone functions. The supplied UML class diagram identifies these public attributes: \begin{itemize} \item \texttt{blueButton: HTMLButtonElement}: the Blue button element. \item \texttt{redButton: HTMLButtonElement}: the Red button element. \item \texttt{page: HTMLElement}: the element whose background is changed. \end{itemize} It also identifies two public operations: \begin{itemize} \item \texttt{constructor(blueButton, redButton, page)} initializes the controller with the three elements. \item \texttt{setBackgroundColor(color: string): void} accepts a color string and changes the background without returning a value. \end{itemize} The Blue and Red click handlers use the controller to apply their respective colors. In the UML notation, a plus sign denotes public visibility, the type after a colon describes an attribute or parameter, and \texttt{void} denotes an operation with no return value. Figure~\ref{Figure:BackgroundColorController} shows the supplied updated design. \begin{figure}[htbp] \centering \includegraphics[width=\linewidth]{png/UML.png} \caption{UML class diagram for the updated Two Buttons website.} \label{Figure:BackgroundColorController} \end{figure} \section{Handoff Notes} The \texttt{nip.io} hostname is provided by a third party; the handoff recommends an owned domain for a long-term project. The handoff does not specify the account owner, billed cost, or cleanup date. Before retiring the deployment, the group should identify the resource owner and preserve any needed files; that owner can then remove the Droplet when it is no longer required.