DevDocs v1.0
Technical Log

From Blueprint to Cloud

A visual documentation log charting how a simple idea evolved into a deployed containerized application.

Pipeline Milestones

Pre-Requisite PhaseInception

The Genesis: Project Inception

Starting out with an interest in DevOps rather than traditional software development, I needed a solid, real-world project to practice on. By collaborating with AI, I built a modern Next.js documentation site powered by Velite. This gave me the perfect production-ready codebase to begin experimenting with containerization.
Containerization & Layer OptimizationArchitecture

The Deep Dive Into Docker

Instead of relying on basic local node environments, the documentation site was treated as a proper microservice. To keep environments consistent and minimize image size, we implemented a 3-stage multi-stage Docker build. This separated the heavy compilation tools from the final runtime container.

Stage 1: Dependency Layer (deps)FROM node:20-alpine AS deps → RUN npm ci

Rather than a standard package update, we used npm ci. This locked in the exact dependency tree from the lockfile, creating a clean, reliable cache layer that sped up subsequent builds.

Stage 2: Compilation (builder)FROM node:20-alpine AS builder → RUN npm run build

This environment takes the dependencies, processes the raw source files, and builds the application. It runs the Velite engine to compile markdown into a highly optimized Next.js production bundle.

Stage 3: Runtime Environment (runner)FROM node:20-alpine AS runner → EXPOSE 3000 → CMD ["node", "server.js"]

The final step strips away all source files and development tools. By extracting only the necessary standalone binaries and static assets, we produced a secure, lightweight Alpine-based container.

To keep the Docker daemon running smoothly, we added a strict .dockerignore file. By excluding local artifacts like node_modules/ and .next/, we drastically cut down the build context sent to the engine. This optimization ultimately resulted in a highly efficient output container weighing in at roughly 60MB.

Infrastructure ManagementDeployment

Azure Cloud Provisioning

Transitioning from local development to the cloud, we provisioned an Ubuntu VM on Azure. From there, we established remote SSH access, configured the Docker engine, and deployed the repository directly to a live server environment.

Production Diagnostics

A summary of the real-world bugs encountered during the deployment phase, highlighting what broke and how we patched it.

Build Context Bloat

Root Cause: Initial Docker builds were copying massive local cache folders directly into the engine, slowing down the pipeline and wasting disk space.

✔ Resolution:Added a precise `.dockerignore` file tailored to the multi-stage setup, filtering out unnecessary directories before the build process even started.
Node.js Version Conflict

Root Cause: Next.js threw compilation errors during the build stage due to outdated dependency constraints in the default `node:18-alpine` image.

✔ Resolution:Bumped the base image across all build stages to `node:20-alpine`, aligning the container environment with modern framework requirements.
Port 3000 Collision

Root Cause: Docker failed to bind to host port 3000 with an `address already in use` error, even though no background processes were actively using it.

✔ Resolution:Mapped the internal container port to an alternative host port (`-p 3050:3000`), cleanly bypassing the host-level network collision.
Connection Timeouts (ERR_CONNECTION_TIMED_OUT)

Root Cause: External web traffic couldn't reach the NGINX proxy because default firewalls on both Ubuntu (`ufw`) and Azure (NSG) were blocking incoming requests.

✔ Resolution:Opened ports 80 and 443 in the local firewall and updated Azure's inbound security rules to correctly accept traffic from Cloudflare's proxy network.

Current Infrastructure: Edge Migration

Status: Active

Building and self-hosting the Dockerized application on an Azure VM was a massive success that provided invaluable hands-on systems experience. However, as the infrastructure evolved, we recognized a strategic opportunity to optimize our server compute. To free up our Azure environment for heavier backend services, we transitioned the documentation site to an edge-hosted model.

Server Offloading via VercelThe Next.js execution layer was smoothly migrated to Vercel's global CDN. This move completely delegates the build processes and traffic hosting to a dedicated edge network, automating our CI/CD pipeline while preserving our original Azure server's resources.
Seamless Domain RoutingCloudflare remains our dedicated DNS and security proxy. By simply updating our DNS records to route traffic to Vercel instead of the Azure IP, we seamlessly shifted the underlying infrastructure. The custom docker.unishdhungana.com.np domain remained intact with zero client downtime.