337 lines
11 KiB
TeX
337 lines
11 KiB
TeX
\documentclass[12pt,a4paper]{article}
|
|
|
|
% ============================================================
|
|
% Packages
|
|
% ============================================================
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[T1]{fontenc}
|
|
\usepackage{lmodern}
|
|
\usepackage[margin=2.5cm]{geometry}
|
|
\usepackage{graphicx}
|
|
\usepackage{hyperref}
|
|
\usepackage{xcolor}
|
|
\usepackage{listings}
|
|
\usepackage{booktabs}
|
|
\usepackage{enumitem}
|
|
\usepackage{fancyhdr}
|
|
\usepackage{titlesec}
|
|
\usepackage{float}
|
|
\usepackage{longtable}
|
|
\usepackage{caption}
|
|
\usepackage{textcomp}
|
|
|
|
\setlength{\headheight}{14pt}
|
|
\addtolength{\topmargin}{-2pt}
|
|
|
|
% ============================================================
|
|
% Colors and Styling
|
|
% ============================================================
|
|
\definecolor{azureblue}{HTML}{0078D4}
|
|
\definecolor{codegray}{HTML}{F5F5F7}
|
|
\definecolor{textdark}{HTML}{1D1D1F}
|
|
\definecolor{linkblue}{HTML}{0071E3}
|
|
|
|
\hypersetup{
|
|
colorlinks=true,
|
|
linkcolor=azureblue,
|
|
urlcolor=linkblue,
|
|
citecolor=azureblue,
|
|
pdftitle={Task Manager -- Cloud Deployment Documentation},
|
|
pdfauthor={Gopi Suvanam}
|
|
}
|
|
|
|
\lstset{
|
|
backgroundcolor=\color{codegray},
|
|
basicstyle=\ttfamily\small,
|
|
breaklines=true,
|
|
frame=single,
|
|
rulecolor=\color{gray!30},
|
|
captionpos=b,
|
|
tabsize=2,
|
|
showstringspaces=false,
|
|
keywordstyle=\color{azureblue}\bfseries,
|
|
commentstyle=\color{gray},
|
|
stringstyle=\color{green!50!black}
|
|
}
|
|
|
|
\pagestyle{fancy}
|
|
\fancyhf{}
|
|
\fancyhead[L]{\small\textcolor{gray}{Task Manager -- Cloud Deployment}}
|
|
\fancyhead[R]{\small\textcolor{gray}{SK1 Final Exam}}
|
|
\fancyfoot[C]{\thepage}
|
|
\renewcommand{\headrulewidth}{0.4pt}
|
|
|
|
\titleformat{\section}{\Large\bfseries\color{azureblue}}{}{0em}{}[\vspace{-0.5em}\textcolor{azureblue}{\rule{\textwidth}{0.5pt}}]
|
|
\titleformat{\subsection}{\large\bfseries\color{textdark}}{}{0em}{}
|
|
|
|
% ============================================================
|
|
\begin{document}
|
|
% ============================================================
|
|
|
|
% ---- Title Page -------------------------------------------
|
|
\begin{titlepage}
|
|
\centering
|
|
\vspace*{3cm}
|
|
{\Huge\bfseries\color{azureblue} Task Manager}\\[0.5cm]
|
|
{\LARGE Cloud Deployment Documentation}\\[2cm]
|
|
|
|
\begin{tabular}{rl}
|
|
\textbf{Course:} & Cloud Technologies / Web Application Deployment \\
|
|
\textbf{Student:} & Gopi Suvanam \\
|
|
\textbf{Login:} & gs699he \\
|
|
\textbf{Date:} & \today \\
|
|
\textbf{Cloud:} & Microsoft Azure (Azure for Students) \\
|
|
\textbf{Repository:} & \url{https://git.kemt.fei.tuke.sk/gs699he/zkt25} \\
|
|
\end{tabular}
|
|
|
|
\vspace{3cm}
|
|
\includegraphics[width=0.65\textwidth]{architecture.png}
|
|
\vfill
|
|
{\small Technical University of Ko\v{s}ice -- KEMT FEI}
|
|
\end{titlepage}
|
|
|
|
\tableofcontents
|
|
\newpage
|
|
|
|
% =============================================================
|
|
\section{Application Overview}
|
|
% =============================================================
|
|
|
|
The \textbf{Task Manager} is a full-stack web application for creating, reading, updating, and deleting (CRUD) tasks. It is deployed to \textbf{Microsoft Azure} using Docker Compose on an Azure Virtual Machine.
|
|
|
|
\subsection{Key Features}
|
|
\begin{itemize}[nosep]
|
|
\item RESTful API with full CRUD operations
|
|
\item Apple-inspired premium UI with glassmorphism
|
|
\item Redis caching (30s TTL) for API optimization
|
|
\item PostgreSQL database with persistent volume and backup scripts
|
|
\item Automatic HTTPS via Caddy + Let's Encrypt
|
|
\item Fully automated deployment via shell scripts
|
|
\item Auto-restart on container failure
|
|
\end{itemize}
|
|
|
|
% =============================================================
|
|
\section{Architecture}
|
|
% =============================================================
|
|
|
|
The application uses a \textbf{5-container microservices architecture} on an Azure VM, orchestrated by Docker Compose.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.72\textwidth]{architecture.png}
|
|
\caption{Architecture -- 5 Docker containers on Azure VM}
|
|
\label{fig:architecture}
|
|
\end{figure}
|
|
|
|
\subsection{Container Descriptions}
|
|
|
|
\begin{longtable}{@{}p{2.8cm}p{3cm}p{7.7cm}@{}}
|
|
\toprule
|
|
\textbf{Container} & \textbf{Image} & \textbf{Purpose} \\
|
|
\midrule
|
|
\endhead
|
|
Caddy & caddy:2-alpine & Reverse proxy with automatic HTTPS/TLS via Let's Encrypt. Ports 80, 443. \\[6pt]
|
|
Frontend & nginx:alpine & Serves static HTML/CSS/JS, proxies \texttt{/api/} to backend. \\[6pt]
|
|
API & node:20-alpine & Express.js REST API with CRUD endpoints. \\[6pt]
|
|
PostgreSQL & postgres:16-alpine & Persistent database with Docker named volume. \\[6pt]
|
|
Redis & redis:7-alpine & In-memory cache with AOF persistence. \\
|
|
\bottomrule
|
|
\end{longtable}
|
|
|
|
\subsection{Network Isolation}
|
|
|
|
\begin{itemize}[nosep]
|
|
\item \texttt{frontend-net} -- Caddy, Frontend, API
|
|
\item \texttt{backend-net} -- API, PostgreSQL, Redis
|
|
\end{itemize}
|
|
|
|
Database and cache are \textbf{not accessible} from the internet. Only the API bridges both networks.
|
|
|
|
% =============================================================
|
|
\section{Azure Services Used}
|
|
% =============================================================
|
|
|
|
\begin{longtable}{@{}p{4.5cm}p{9cm}@{}}
|
|
\toprule
|
|
\textbf{Service} & \textbf{Usage} \\
|
|
\midrule
|
|
\endhead
|
|
Azure VM (Standard\_B1s) & Ubuntu 24.04, 1 vCPU, 1 GB RAM. Runs Docker. \\[6pt]
|
|
Public IP + DNS & \texttt{*.westeurope.cloudapp.azure.com} for HTTPS. \\[6pt]
|
|
Azure for Students & \$100 free credit, no credit card required. \\[6pt]
|
|
Let's Encrypt & Free TLS certificates via Caddy (auto-renewal). \\[6pt]
|
|
cloud-init & Installs Docker on first VM boot automatically. \\
|
|
\bottomrule
|
|
\end{longtable}
|
|
|
|
% =============================================================
|
|
\section{File Descriptions}
|
|
% =============================================================
|
|
|
|
\begin{longtable}{@{}p{4.5cm}p{9cm}@{}}
|
|
\toprule
|
|
\textbf{File} & \textbf{Description} \\
|
|
\midrule
|
|
\endhead
|
|
\texttt{docker-compose.yaml} & 5 services, 2 networks, persistent volumes. \\[4pt]
|
|
\texttt{prepare-app.sh} & Creates Azure VM, installs Docker, deploys app. \\[4pt]
|
|
\texttt{remove-app.sh} & Deletes Azure resource group (all resources). \\[4pt]
|
|
\texttt{backup-db.sh} & SSH + pg\_dump for database backups. \\[4pt]
|
|
\texttt{view-logs.sh} & Retrieves container logs via SSH. \\[4pt]
|
|
\texttt{cloud-init.yaml} & Auto-installs Docker on VM first boot. \\[4pt]
|
|
\texttt{env.example} & Template for secrets (copied to .env). \\[4pt]
|
|
\texttt{caddy/Caddyfile} & HTTPS reverse proxy configuration. \\[4pt]
|
|
\texttt{frontend/} & Nginx Dockerfile, config, static files. \\[4pt]
|
|
\texttt{api/} & Node.js Dockerfile, Express server, DB pool. \\[4pt]
|
|
\texttt{db/init.sql} & Database schema and sample data. \\[4pt]
|
|
\texttt{docs/} & This documentation + architecture diagram. \\
|
|
\bottomrule
|
|
\end{longtable}
|
|
|
|
% =============================================================
|
|
\section{Configuration}
|
|
% =============================================================
|
|
|
|
All settings via environment variables in \texttt{.env} (gitignored).
|
|
|
|
\begin{longtable}{@{}p{4.5cm}p{4.5cm}p{4.5cm}@{}}
|
|
\toprule
|
|
\textbf{Variable} & \textbf{Description} & \textbf{Default} \\
|
|
\midrule
|
|
\endhead
|
|
\texttt{POSTGRES\_PASSWORD} & Database password & \textit{(required)} \\
|
|
\texttt{AZURE\_RESOURCE\_GROUP} & Resource group name & taskmanager-rg \\
|
|
\texttt{AZURE\_LOCATION} & Azure region & westeurope \\
|
|
\texttt{AZURE\_VM\_SIZE} & VM size & Standard\_B1s \\
|
|
\texttt{AZURE\_DNS\_LABEL} & DNS subdomain & taskmanager-gs699he \\
|
|
\bottomrule
|
|
\end{longtable}
|
|
|
|
\subsection{Security}
|
|
\begin{itemize}[nosep]
|
|
\item \texttt{.env} in \texttt{.gitignore} -- secrets never in Git
|
|
\item Databases on isolated Docker network
|
|
\item HTTPS enforced by Caddy (HTTP $\rightarrow$ HTTPS redirect)
|
|
\item Security headers in Nginx
|
|
\item SSH key authentication (no password login)
|
|
\end{itemize}
|
|
|
|
% =============================================================
|
|
\section{Deployment Instructions}
|
|
% =============================================================
|
|
|
|
\subsection{Prerequisites}
|
|
\begin{enumerate}[nosep]
|
|
\item Azure CLI: \texttt{curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash}
|
|
\item Azure for Students subscription activated
|
|
\item \texttt{az login} completed
|
|
\end{enumerate}
|
|
|
|
\subsection{Deploy}
|
|
\begin{lstlisting}[language=bash]
|
|
# Clone and configure
|
|
git clone git@git.kemt.fei.tuke.sk:gs699he/zkt25.git
|
|
cd zkt25/sk1
|
|
cp env.example .env
|
|
nano .env # Set POSTGRES_PASSWORD
|
|
|
|
# Deploy to Azure
|
|
./prepare-app.sh
|
|
# Creates: Resource Group -> VM -> Docker -> Containers
|
|
|
|
# Access:
|
|
# https://taskmanager-gs699he.westeurope.cloudapp.azure.com
|
|
\end{lstlisting}
|
|
|
|
\subsection{Remove (after exam)}
|
|
\begin{lstlisting}[language=bash]
|
|
./remove-app.sh
|
|
# Deletes entire resource group (VM, IP, disk, NSG)
|
|
\end{lstlisting}
|
|
|
|
% =============================================================
|
|
\section{Data Persistence and Backups}
|
|
% =============================================================
|
|
|
|
\subsection{Volumes}
|
|
\begin{itemize}[nosep]
|
|
\item \texttt{taskapp-pgdata} -- PostgreSQL data
|
|
\item \texttt{taskapp-redisdata} -- Redis AOF
|
|
\item \texttt{taskapp-caddy-data} -- TLS certificates
|
|
\end{itemize}
|
|
|
|
\subsection{Backup}
|
|
\begin{lstlisting}[language=bash]
|
|
./backup-db.sh
|
|
# Output: backups/taskmanager_backup_20260519_020000.sql
|
|
\end{lstlisting}
|
|
|
|
\subsection{Auto-Restart}
|
|
All containers: \texttt{restart: always}. Docker starts on boot via systemd.
|
|
|
|
% =============================================================
|
|
\section{Access Logs}
|
|
% =============================================================
|
|
|
|
\begin{lstlisting}[language=bash]
|
|
./view-logs.sh # All logs
|
|
./view-logs.sh --caddy # HTTPS proxy logs
|
|
./view-logs.sh --api -f # Follow API logs real-time
|
|
\end{lstlisting}
|
|
|
|
Log sources:
|
|
\begin{itemize}[nosep]
|
|
\item \textbf{Caddy}: JSON -- client IP, status, TLS version
|
|
\item \textbf{API}: \texttt{METHOD /path STATUS duration}
|
|
\item \textbf{Nginx}: Combined log format
|
|
\end{itemize}
|
|
|
|
% =============================================================
|
|
\section{Cost Analysis}
|
|
% =============================================================
|
|
|
|
\subsection{Azure for Students -- Monthly Costs}
|
|
|
|
\begin{longtable}{@{}p{5cm}p{5cm}r@{}}
|
|
\toprule
|
|
\textbf{Resource} & \textbf{Configuration} & \textbf{Monthly} \\
|
|
\midrule
|
|
\endhead
|
|
Azure VM & Standard\_B1s (1 vCPU, 1 GB) & \$7.59 \\
|
|
Public IP & Static IPv4 & \$3.00 \\
|
|
OS Disk & 30 GB Premium SSD & \$1.20 \\
|
|
TLS Certificate & Let's Encrypt (free) & \$0.00 \\
|
|
\midrule
|
|
\textbf{Total} & & \textbf{\$11.79} \\
|
|
\textbf{Annual} & & \textbf{\$141.48} \\
|
|
\bottomrule
|
|
\end{longtable}
|
|
|
|
Azure for Students provides \$100 free credit -- enough for approximately 8 months of operation.
|
|
|
|
\subsection{Comparison}
|
|
\begin{longtable}{@{}p{4cm}p{5cm}r@{}}
|
|
\toprule
|
|
\textbf{Provider} & \textbf{Plan} & \textbf{Monthly} \\
|
|
\midrule
|
|
\endhead
|
|
Azure (Students) & B1s + \$100 credit & \$11.79 \\
|
|
AWS & t3.micro (free 12mo) & \$8.50 \\
|
|
DigitalOcean & Basic Droplet 2 GB & \$12.00 \\
|
|
Hostinger & KVM 1 (4 GB) & \$5.99 \\
|
|
\bottomrule
|
|
\end{longtable}
|
|
|
|
% =============================================================
|
|
\section{AI Usage Declaration}
|
|
% =============================================================
|
|
|
|
\begin{itemize}[nosep]
|
|
\item \textbf{Google Antigravity (Gemini)}: Generated scripts, Docker Compose, Nginx/Caddy config, and this documentation.
|
|
\item \textbf{Architecture diagram}: AI-generated from technical specification.
|
|
\end{itemize}
|
|
|
|
All content reviewed, tested, and adapted. Student understands all components.
|
|
|
|
\end{document}
|