Building and Deploying AmigoGomez.com: A Complete Step-by-Step Guide

Warning

This document is an AI-generated draft derived from implementation notes.
It has not yet been fully reviewed or finalized and will be updated.

This post documents the entire end-to-end setup for building, running, and deploying AmigoGomez.com — from local development in WSL and VS Code, to CI/CD with Azure DevOps, to custom domains and HTTPS on Azure App Service.

The goal is repeatability: the same steps work locally, in the pipeline, and in production.


What You’ll End Up With

By the end of this guide, you will have:

  • Local development using WSL + VS Code + uv
  • A Python virtual environment in .venv
  • A MkDocs static site
  • A Flask app that serves the built static site
  • An Azure App Service (Linux) deployment
  • A working Azure DevOps pipeline
  • Custom domains configured:

  • www.amigogomez.com (canonical)

  • amigogomez.com → redirects to www
  • Optional: .net, .org, etc. redirecting to the canonical domain
  • HTTPS enabled with an Azure-managed or custom certificate
  • A universal redirect to enforce the canonical hostname

amigogomez-site/
├── app.py
├── site/
│   ├── mkdocs.yml
│   └── docs/
├── site_out/          # generated
├── build_and_test.sh
├── pyproject.toml + uv.lock
├── azure-pipelines.yml
├── .gitignore
└── .vscode/
    └── settings.json

Phase 1: Local Prerequisites

Required Tools

  • Windows with WSL2
  • Ubuntu installed in WSL
  • VS Code
  • VS Code extensions:

  • Python

  • WSL

Open the project using:

Command Palette → WSL: Open Folder in WSL…

Phase 2: Python and uv Setup

Ensure uv is installed and on your PATH.

Add this to ~/.bashrc if needed:

export PATH="$HOME/.local/bin:$PATH"

Reload:

source ~/.bashrc

Create and Sync the Virtual Environment

If using pyproject.toml:

uv sync

Phase 3: MkDocs Setup

Confirm MkDocs works:

uv run mkdocs --version

Your MkDocs project lives in site/.

Build the Static Site

From the repo root:

cd site
uv run mkdocs build --site-dir ../site_out
cd ..

This generates the static output in site_out/.

Optional: Live Authoring

cd site
uv run mkdocs serve -a 0.0.0.0:8001

Open: http://localhost:8001


Phase 4: Flask App for Static Serving

The Flask app exists solely to serve the built static site.

Key principles:

  • Flask static_folder points to site_out
  • / returns index.html
  • All other paths serve static assets
  • Works identically locally and in Azure

site_out/ must exist before running the app.


Phase 5: Local Build and Test Script

Create build_and_test.sh to standardize everything:

What it should do:

  • Sync Python environment
  • Remove old site_out
  • Build MkDocs into site_out
  • Run the Flask app locally

This ensures local == CI == production.


Phase 6: VS Code Configuration

Create .vscode/settings.json:

{
  "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
  "python.terminal.activateEnvironment": true,
  "python.analysis.autoImportCompletions": true
}

Then in VS Code:

Command Palette → Python: Select Interpreter

Select:

${workspaceFolder}/.venv/bin/python

Verify:

which python
python --version

Phase 7: Azure Resources

Create or use an existing resource group.

Required Azure resources:

  • App Service Plan (Linux)

  • Basic tier or higher recommended

  • Web App for Linux

  • Python runtime


Phase 8: App Service Configuration

Startup Command

Use Gunicorn (recommended):

gunicorn --bind=0.0.0.0:$PORT app:app

App Settings

Ensure:

  • PORT is respected
  • Any redirect or environment variables are defined here

Phase 9: Azure DevOps Pipeline

Pipeline Responsibilities

Build Stage

  • Checkout repo
  • Install Python
  • Install uv
  • Install dependencies
  • Build MkDocs → site_out
  • Create app.zip
  • Publish artifact

Deploy Stage

  • Deploy ZIP to App Service

ZIP deploy / Run-From-Package is the cleanest approach.


Phase 10: Custom Domain Configuration

Canonical Domain

Canonical host:

www.amigogomez.com

DNS Records (Typical)

  • www.amigogomez.com

  • CNAME → <appname>.azurewebsites.net

  • amigogomez.com (apex)

  • A record → App Service IP

  • TXT record for domain verification

Add both domains in:

Azure Portal → App Service → Custom domains

Phase 11: HTTPS / TLS

Option A: Azure Managed Certificate (Preferred)

  • Available after domain verification
  • Free and auto-renewing

Option B: Bring Your Own Certificate

  • Required in some configurations
  • Often stored in Azure Key Vault

Bind certificates to all hostnames you expect to serve.


Phase 12: Canonical Redirect Logic

All traffic should end up at:

https://www.amigogomez.com

Recommended location for redirects:

  • Flask application code

Redirect when the request host is:

  • amigogomez.com
  • <appname>.azurewebsites.net
  • .net, .org, or any alternate domain

Use a 301 redirect, preserving path and query string.

All domains must still be added to App Service so Azure accepts the request.


Phase 13: Adding Additional Domains (.net, .org)

For each domain:

  1. Add DNS records (www + apex)
  2. Add domain in Azure App Service
  3. Bind HTTPS
  4. Include domain in redirect logic

All alternate domains redirect to:

https://www.amigogomez.com

Phase 14: Definition of Done

Local:

  • build_and_test.sh runs clean
  • Flask serves content locally
  • MkDocs rebuilds correctly

Azure:

  • Pipeline succeeds
  • App loads at https://www.amigogomez.com
  • HTTP → HTTPS enforced
  • Apex domain redirects to www
  • Azure default domain redirects to canonical
  • TLS certificate valid

Closing Notes

This setup intentionally favors:

  • Simplicity
  • Predictability
  • Portability
  • Minimal platform lock-in

Everything is reproducible locally and debuggable without Azure.