VCF Insider Site Operations Runbook

VCF Insider Site Operations Runbook

This document is the working development, validation, and production deployment runbook for VCF Insider.

Repository:

https://github.com/krieg121/VCFInsider

Production site:

https://www.vcfinsider.com/

Community:

https://community.vcfinsider.com/

VCF Insider is a Jekyll site built locally and deployed to DreamHost.

GitHub is the source of truth. DreamHost serves the production site. GitHub Pages is not the production host.


1. Production rules

main is production.

Do not modify, merge into, force-update, or otherwise change main unless the specific production change has been reviewed and explicitly approved by Chris.

Normal workflow:

  1. Verify the current production main.
  2. Create a focused test branch from that exact commit.
  3. Make only the approved changes.
  4. Build and preview locally.
  5. Validate desktop and mobile behavior.
  6. Review the complete branch-to-main diff.
  7. Merge through a reviewed pull request only after explicit approval.
  8. Verify the resulting main commit.
  9. Run the DreamHost deployment from a clean local main that exactly matches origin/main.
  10. Smoke-test the live site.

Do not mix unrelated fixes into the same branch.

GitHub is the source of truth.

Local checkouts may contain untracked, experimental, backup, or temporary files. Do not delete or overwrite those files simply to obtain a clean working tree.


2. Verify production before starting

Always fetch the current remote state first:

git fetch origin
git log -1 --oneline origin/main

Record or verify the production commit before creating a new branch.

Do not assume a previously remembered main SHA is still current.


3. Create a focused test branch

Create each site change from the current verified origin/main.

Example:

git switch -c <test-branch> origin/main

Use a branch name that describes one task, for example:

homepage-category-cards-test
blog-layout-fix-test
deployment-guide-refresh

If the normal checkout contains unrelated local files, do not disturb them just to start a new task. Use a separate worktree instead.


4. Safe local worktrees

Editing locally in an isolated worktree

For a new local task:

git fetch origin
git worktree add -b <test-branch> ..\VCFInsider-<task> origin/main
cd ..\VCFInsider-<task>

This creates the task branch in a separate working directory without modifying the primary checkout.

Previewing an existing remote test branch

When the test branch already exists remotely:

git fetch origin
git worktree add --detach ..\VCFInsider-preview origin/<test-branch>
cd ..\VCFInsider-preview

To refresh an existing preview worktree:

git fetch origin
git switch --detach origin/<test-branch>

A detached preview worktree is for building and testing.

Do not make production commits from it.


5. Local dependencies

The project uses Bundler and the github-pages dependency set.

Install dependencies when setting up a new checkout or after dependency changes:

bundle install

Normal Jekyll commands should be run through Bundler:

bundle exec jekyll build
bundle exec jekyll serve

This helps keep the local Jekyll environment aligned with the versions defined by the repository.


6. Build before preview

Run:

bundle exec jekyll build

The build must complete successfully before a change is considered ready.

Warnings are not automatically failures. Review the final build result and distinguish non-blocking dependency/platform warnings from actual Jekyll errors.

The generated _site directory is build output, not source content.


7. Local preview

Run:

bundle exec jekyll serve

Open:

http://127.0.0.1:4000/

Keep the Jekyll process running while testing.

After each final CSS, layout, or template adjustment, rebuild or refresh the served branch and verify the actual rendered result rather than relying only on the source diff.


8. Required visual validation

For CSS, layout, navigation, card, or template changes, validate at minimum:

  • Desktop around 1440px wide
  • Mobile around 390px wide
  • Mobile around 430px wide

Check for:

  • horizontal overflow
  • clipped headings
  • unexpected text wrapping
  • broken navigation
  • malformed category pills
  • inconsistent card heights
  • inconsistent button placement
  • stretched or cropped images
  • unreadable text
  • bad contrast
  • changes outside the intended section

When shared classes are modified, inspect other pages that use those classes.

Whenever possible, scope page-specific styling to a page-specific parent such as:

.home-page ...
body.blog-index ...

This reduces the risk of changing unrelated pages.


9. Validate the exact branch before merge

Fetch the latest remote refs:

git fetch origin

Check whitespace:

git diff --check origin/main...origin/<test-branch>

Review changed files and size:

git diff --stat origin/main...origin/<test-branch>

Review the actual patch:

git diff origin/main...origin/<test-branch>

Review the commits that would enter production:

git log --oneline origin/main..origin/<test-branch>

Confirm:

  • only expected files changed
  • no temporary files were added
  • no backup files were added
  • no credentials or secrets are present
  • no unrelated cleanup is included
  • all requested fixes are present
  • previously approved behavior remains intact

If main changed while the test branch was being developed, stop and review the new relationship before merging.

Do not assume the old comparison is still valid.


10. Production merge workflow

Use a pull request from the reviewed test branch into main.

Before merging, verify:

  • PR base is main
  • PR head is the expected test branch
  • PR head SHA matches the version that was reviewed
  • changed-file list matches the approved scope
  • the branch is mergeable
  • desktop/mobile validation is complete

Merge only after Chris explicitly approves the production merge.

Afterward:

git fetch origin
git log -1 --oneline origin/main

Record the new production commit SHA.


11. DreamHost staging and production deployment

Hosting details:

SSH host:          vps69933.dreamhostps.com
SSH user:          vcfinsider_web
Staging site:      /home/vcfinsider_web/staging.vcfinsider.com
Staging data:      /home/vcfinsider_web/deployments/vcfinsider-staging
Production site:   /home/vcfinsider_web/vcfinsider.com
Production data:   /home/vcfinsider_web/deployments/vcfinsider

The deployment is deliberately separate from the GitHub merge. Merging a pull request into main does not change the DreamHost site.

The local deployment entry point is:

.\scripts\Deploy-VCFInsider.ps1

The script has three modes:

# Validation only; no DreamHost file changes
.\scripts\Deploy-VCFInsider.ps1

# Deploy an approved, clean remote-tracked branch to staging
.\scripts\Deploy-VCFInsider.ps1 -Staging

# Deploy a clean main that exactly matches origin/main to production
.\scripts\Deploy-VCFInsider.ps1 -Production

With no parameters, validation mode:

  • verifies the repository and current origin/main
  • verifies non-interactive SSH key authentication
  • performs read-only preflights of both DreamHost web roots
  • builds the site with JEKYLL_ENV=production
  • confirms _site/index.html exists
  • makes no DreamHost file changes

Before running it, load the dedicated key into the Windows SSH agent:

Start-Service ssh-agent
ssh-add "$env:USERPROFILE\.ssh\vcfinsider_dreamhost_ed25519"

Staging mode

Staging mode is for testing a focused branch before it enters main. It stops unless all of the following are true:

  • the current branch is named and is not main
  • the working tree is clean
  • the branch exists on origin
  • local HEAD exactly matches the freshly fetched remote branch
  • the origin points to krieg121/VCFInsider
  • the dedicated SSH key works non-interactively
  • the Jekyll build succeeds
  • the typed STAGE <short-SHA> confirmation matches

The staging build uses https://staging.vcfinsider.com as the Jekyll URL, includes future-dated posts for review, and replaces the generated robots.txt with a site-wide crawl disallow. This reduces accidental search indexing but is not an access-control mechanism. Password protection should be configured separately before placing sensitive unpublished content on staging.

Staging checks both / and /blog/ after promotion. Its backups, releases, and current-release metadata remain separate from production under:

/home/vcfinsider_web/deployments/vcfinsider-staging/

Production mode

Production mode stops unless all of the following are true:

  • the current branch is main
  • the working tree is clean
  • local main exactly matches the freshly fetched origin/main
  • the origin points to krieg121/VCFInsider
  • the dedicated SSH key works non-interactively
  • the Jekyll build succeeds
  • the typed commit confirmation matches

The script packages _site, uploads it to a private incoming directory, backs up the current target, and promotes the release. Production checks both / and /blog/ after promotion.

For both targets, DreamHost’s /.dh-diag symlink is preserved during synchronization. The script also preserves /.well-known/ and /.htaccess if either is created by DreamHost or maintained outside Jekyll.

Backups and staged releases are retained under:

/home/vcfinsider_web/deployments/vcfinsider/backups/
/home/vcfinsider_web/deployments/vcfinsider/releases/

The deployed release ID and Git SHA are recorded in:

/home/vcfinsider_web/deployments/vcfinsider/current-release

No automatic backup deletion is performed. Review storage usage and implement a separately approved retention policy before removing old backups.

After the deployment, remove the key from the Windows SSH agent when it is no longer needed:

ssh-add -d "$env:USERPROFILE\.ssh\vcfinsider_dreamhost_ed25519"

12. Post-deployment validation

After the DreamHost deployment completes, open:

https://www.vcfinsider.com/

Check the pages directly affected by the change.

Also check at least one page that should not have changed.

For homepage changes, verify:

  • hero
  • Latest from the Field
  • article cards
  • category section
  • navigation
  • community links
  • desktop layout
  • mobile layout

For Blog index changes, verify:

  • /blog/
  • card layout
  • category labels
  • article links
  • mobile stacking

For article-template changes, open at least one real article.

A successful Git merge does not by itself prove that the live site renders correctly.


13. Publishing new articles

Posts live in:

_posts/

The current post format commonly includes front matter such as:

layout: post
title:
description:
excerpt:
date:
author:
categories:
tags:
image:
thumbnail:
og_image:
hero_image_path:

Not every field is required for every template, but new articles should follow the established metadata pattern used by recent production posts.

In particular, keep:

  • a valid publication date
  • an authored category label
  • a useful excerpt
  • a card/hero image
  • social image metadata where applicable

Do not invent new category spelling or capitalization casually. Category labels and category URLs are handled separately by the site.


14. Homepage article behavior

Latest from the Field is generated automatically from the four newest posts.

The homepage template loops over:


{% for post in site.posts limit:4 %}

A new article therefore appears automatically when it becomes one of the four newest posts.

Homepage cards automatically inherit the shared homepage presentation, including:

  • article image
  • category pill
  • title
  • excerpt
  • publication date
  • Read More button
  • NEW badge for recently published posts

The homepage currently looks for:

post.featured_image

and falls back to:

post.image

Current production posts commonly use image.

No hand-built homepage card is required for each article.


15. Category handling

Preserve authored category labels such as:

Cloud Foundation
AI & Automation
NSX-T
VCF 9.1
VMware Cloud Foundation

Do not change category URLs merely to alter the visible label.

If a category label renders incorrectly, trace the Liquid/template rendering path before attempting to fix it with CSS.

After category-related changes, validate:

  • homepage cards
  • Blog index
  • category pages
  • category URLs

16. Custom-domain configuration

The production domain is:

https://www.vcfinsider.com

The repository currently contains:

url: "https://www.vcfinsider.com"
baseurl: ""

and the CNAME file contains:

www.vcfinsider.com

Do not change _config.yml, CNAME, DNS, or GitHub Pages domain settings as part of unrelated development work.

A domain change should be handled as its own reviewed task.


17. Scope discipline

Keep each branch focused.

A homepage change should not silently modify:

  • Blog index layout
  • article templates
  • navigation
  • analytics
  • community behavior

A Blog index change should not silently modify:

  • homepage cards
  • article pages
  • navigation
  • analytics

A documentation change should not include application code changes.

If testing reveals a second unrelated issue, record it and handle it in a separate task unless it is directly caused by the current patch.


18. Rollback

If a production change causes a significant problem:

  1. Stop further deployment attempts.
  2. Record the failed release ID, Git SHA, and observed symptoms.
  3. Identify the timestamped DreamHost backup for that release.
  4. Determine whether restoring the backup or deploying a reviewed corrective commit is safer.
  5. Obtain explicit approval for the exact rollback action.
  6. Restore or redeploy using the approved procedure.
  7. Verify the live site again.

The remote helper attempts to restore the just-created backup automatically if the file-promotion operation itself fails. A rollback caused by bad rendered content or a failed live smoke test is a separate production write and requires explicit approval.

Do not force-reset main, rewrite production history, or manually overwrite the web root as a routine rollback method.


19. Secrets and sensitive files

Never commit:

  • API keys
  • passwords
  • access tokens
  • database credentials
  • private backups
  • private configuration exports

Do not place secrets in:

  • Markdown documentation
  • screenshots
  • commit messages
  • issue descriptions
  • terminal transcripts

The VCF Insider Community API has its own runbook:

XENFORO_API_RUNBOOK.md

Forum writes and VCF Insider repository writes are separate operations and require separate approval.


20. Important source locations

_config.yml        Jekyll/site configuration
CNAME              Production custom domain
_layouts/          Page and post layouts
_includes/         Shared Liquid components
_pages/            Static pages
_posts/            Published articles
assets/css/        Site CSS
assets/js/         Site JavaScript
assets/images/     Site and article images
index.html         Homepage

Current site dependencies include:

  • Jekyll via GitHub Pages
  • Minima
  • jekyll-feed
  • jekyll-sitemap
  • jekyll-seo-tag
  • custom VCF Insider CSS and JavaScript

21. Definition of done

Before a site change is considered complete:

  • Current origin/main verified
  • Test branch based on intended production commit
  • Exact scope identified
  • Proposed patch reviewed before implementation
  • Only approved files changed
  • git diff --check passes
  • Jekyll build succeeds
  • Desktop preview validated
  • 390px mobile preview validated
  • 430px mobile preview validated
  • No horizontal overflow
  • No unintended shared-style regressions
  • Final branch-to-main diff reviewed
  • Production merge explicitly approved
  • PR head SHA re-verified before merge
  • New main SHA recorded
  • Validation-only DreamHost deployment run succeeds
  • Staging deployment separately approved
  • Staging release validated at desktop and mobile widths
  • Production deployment separately approved
  • Deployed DreamHost release ID and Git SHA recorded
  • Live site smoke-tested

Last materially updated: September 2026.