Skip to content

Deploy the Documentation Site

This guide covers how the MkDocs documentation site is deployed to AWS and how to work with the auto-deploy pipeline.

Overview

The docs site is a MkDocs Material static site served by Nginx on the same EC2 instance as the main app, at http://docs.2sigma.io. It has its own GitHub Actions pipeline that triggers automatically when doc changes are pushed to the staging branch.

The main app deploy workflow ignores docs/** changes entirely. Docs and app deployments are fully independent.

Architecture

The pipeline works like this:

  1. MkDocs source lives in docs/ and mkdocs.yml in the backend repo
  2. The GitHub Actions workflow at .github/workflows/deploy-docs.yml triggers on pushes to staging when files under docs/** or mkdocs.yml change
  3. The workflow runs: checkout → install MkDocs dependencies → mkdocs build --strict → tar the output → SCP to EC2 → extract to ~/docs-site/ → reload Nginx
  4. Docker Compose bind-mounts ~/docs-site/ on the EC2 host into the Nginx container at /usr/share/nginx/docs:ro
  5. Nginx has a dedicated server block for docs.2sigma.io that serves static files from /usr/share/nginx/docs

The result: pushing a doc change to staging gets it live within about a minute, with no manual steps.

DNS Setup

You need an A record pointing the docs subdomain at the EC2 Elastic IP:

Record Type Value
docs.2sigma.io A 3.151.25.120

To verify DNS is resolving before it fully propagates, you can test the Nginx routing directly:

curl -H "Host: docs.2sigma.io" http://3.151.25.120/

If Nginx is configured correctly, this returns the docs site HTML even before DNS propagates.

Deploying Docs Changes

The normal workflow for updating docs:

  1. Edit files in docs/ or update mkdocs.yml
  2. Commit and push to main
  3. Merge main into staging to trigger the deploy:
git checkout staging && git merge main && git push && git checkout main
  1. GitHub Actions builds and deploys automatically
  2. Verify at http://docs.2sigma.io

Paths filter

The workflow only triggers when docs/** or mkdocs.yml files change. If you push to staging with only backend code changes, the docs pipeline won't run. This is intentional.

Building Docs Locally

Before pushing, preview your changes locally to catch broken links or formatting issues.

Install the required packages:

pip install mkdocs mkdocs-material mkdocs-autorefs "mkdocstrings[python]" pymdown-extensions

Start the live-reload dev server:

mkdocs serve

Open http://localhost:8000 in your browser. The server reloads automatically as you edit files.

To test the production build (same flags as CI):

mkdocs build --strict

Fix --strict failures before pushing

The CI pipeline runs mkdocs build --strict, which treats warnings as errors. Broken internal links and pages referenced in the nav but missing from docs/ will fail the build. Run this locally first to catch those issues.

The built site goes into site/. You can open site/index.html directly in a browser to inspect the output.

Manual Deployment

Use this if GitHub Actions is unavailable or for first-time setup.

Step 1: Build locally

mkdocs build --strict

Step 2: Package the output

tar -czf /tmp/docs-site.tar.gz -C site .

Step 3: Transfer to EC2

scp -i ai-tutor-backend/terraform/ai-tutor-staging.pem \
  /tmp/docs-site.tar.gz \
  ec2-user@3.151.25.120:/tmp/docs-site.tar.gz

Step 4: Extract on EC2

SSH into the instance:

ssh -i ai-tutor-backend/terraform/ai-tutor-staging.pem ec2-user@3.151.25.120

Then extract the archive:

mkdir -p ~/docs-site && rm -rf ~/docs-site/* && \
  tar -xzf /tmp/docs-site.tar.gz -C ~/docs-site/ && \
  rm /tmp/docs-site.tar.gz

Step 5: Reload Nginx

cd ~/ai-tutor-backend/deploy && \
  docker compose --env-file .env.production exec -T nginx nginx -s reload

Exit the SSH session and verify at http://docs.2sigma.io.

Infrastructure Files

File Purpose
deploy/nginx/nginx.conf server block for docs.2sigma.io, serves static files from /usr/share/nginx/docs
deploy/docker-compose.yml Bind-mount from ~/docs-site/ on the host to /usr/share/nginx/docs:ro in the Nginx container
.github/workflows/deploy-docs.yml CI/CD pipeline: build, transfer, extract, reload
mkdocs.yml MkDocs configuration, nav structure, theme settings
docs/ Documentation source files (Markdown)

Troubleshooting

Docs not updating after push

Check that the GitHub Actions workflow actually ran. The paths filter means the workflow only triggers when docs/** or mkdocs.yml files are in the push. If you only changed backend code, the docs pipeline won't fire.

If the workflow ran but the deploy failed, check the Actions log for SSH connectivity errors. The EC2 instance must be reachable and the SSH key secret must be configured in the repo settings.

404 on docs.2sigma.io

The DNS A record may not be set or hasn't propagated yet. Test Nginx routing directly:

curl -H "Host: docs.2sigma.io" http://3.151.25.120/

If this returns the docs HTML, Nginx is working and the issue is DNS only. If it returns a 404 or the main app, check the Nginx config for the docs.2sigma.io server block.

Nginx not serving docs

Verify the volume mount is in place and the files are there:

docker exec deploy-nginx-1 ls /usr/share/nginx/docs/

If the directory is empty or the command fails, the bind-mount may not be configured or ~/docs-site/ on the host is empty. Run the manual deployment steps above to populate it.

Build fails with --strict

The most common causes:

  • A page is listed in the mkdocs.yml nav but the corresponding .md file doesn't exist
  • An internal link points to a page or anchor that doesn't exist
  • A mkdocstrings reference points to a Python object that can't be found

Run mkdocs build --strict locally and read the error output. It will tell you exactly which file and line caused the failure.