Infrastructure · Updated Jun 29, 2026

Public Website Deployment

Public Website Deployment

Checklist for taking the SystemLink docs site public with S3 + CloudFront.


#Short Answer

Yes, CloudFront can use your own domain name.

CloudFront calls these alternate domain names or CNAMEs. To use one, the distribution needs:

  • The domain added as an alternate domain name, such as docs.example.com.
  • A valid TLS certificate that covers that domain.
  • DNS pointed at the CloudFront distribution.

AWS docs:

Important certificate detail: for viewer HTTPS on CloudFront, request or import the ACM certificate in us-east-1 (US East / N. Virginia).


Use:

  • Private S3 bucket for static files.
  • CloudFront distribution as the public HTTPS front door.
  • Origin Access Control (OAC) so only CloudFront can read the bucket.
  • ACM certificate for a custom domain.
  • Route 53 alias record if DNS is hosted in Route 53.

Avoid:

  • Making the S3 bucket public.
  • Publishing from the private Git server instance.
  • Uploading anything outside Docs/Site.
  • Uploading private infrastructure notes.

#Repo-Side Preconditions

  • [x] Public docs are generated into Docs/Site.
  • [x] Private infrastructure notes are outside Docs.
  • [x] Public safety scan exists:

powershell -ExecutionPolicy Bypass -File Tools\scan_public_docs.ps1

Before every deploy:


python Tools\build_docs_site.py

powershell -ExecutionPolicy Bypass -File Tools\scan_public_docs.ps1


#AWS Setup Checklist

#1. Choose Names

  • [ ] Pick public domain or subdomain.
    • Example: docs.systemlink.dev
  • [ ] Pick globally unique S3 bucket name.
    • Example: systemlink-docs-public
  • [ ] Decide AWS region for S3.
    • Example: us-east-2 or whichever region you normally use.
  • [ ] Remember: CloudFront certificate must be in us-east-1.

#2. Create S3 Bucket

  • [ ] Create the bucket.
  • [ ] Keep Block all public access enabled.
  • [ ] Do not enable public bucket policies.
  • [ ] Do not rely on the S3 static website endpoint for the final public URL.
  • [ ] Optional: enable bucket versioning.

#3. Create CloudFront Distribution

  • [ ] Origin points at the S3 bucket REST endpoint, not the S3 website endpoint.
  • [ ] Create/use Origin Access Control (OAC).
  • [ ] Set default root object to index.html.
  • [ ] Viewer protocol policy: redirect HTTP to HTTPS.
  • [ ] Allowed methods: GET, HEAD.
  • [ ] Enable compression.
  • [ ] Add custom error response:
    • 404 -> /index.html only if we later add client-side routing.
    • For the current static HTML site, normal 404 is fine.

#4. Lock S3 To CloudFront

  • [ ] Add the bucket policy generated/recommended by CloudFront OAC.
  • [ ] Confirm direct public S3 access is denied.
  • [ ] Confirm CloudFront can read index.html.

#5. Add Custom Domain

  • [ ] Request ACM cert in us-east-1.
  • [ ] Include the exact domain:
    • docs.example.com, or
    • wildcard like *.example.com if appropriate.
  • [ ] Validate the certificate through DNS.
  • [ ] Add the domain as a CloudFront alternate domain name.
  • [ ] Attach the ACM certificate to the distribution.
  • [ ] Point DNS to CloudFront:
    • Route 53: use an Alias A record, plus AAAA if IPv6 is enabled.
    • Other DNS provider: use CNAME for subdomains.

#6. Deploy Site

Initial manual deploy:


python Tools\build_docs_site.py

powershell -ExecutionPolicy Bypass -File Tools\scan_public_docs.ps1

aws s3 sync Docs\Site s3://YOUR_BUCKET_NAME --delete

aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"

Replace:

  • YOUR_BUCKET_NAME
  • YOUR_DISTRIBUTION_ID

#7. Verify

  • [ ] CloudFront domain loads.
  • [ ] Custom domain loads over HTTPS.
  • [ ] Homepage image loads.
  • [ ] Docs pages load.
  • [ ] Screenshot gallery loads.
  • [ ] Filter works on screenshots.
  • [ ] Old private infrastructure pages return 404.
  • [ ] Direct S3 object URL is not publicly readable unless intentionally allowed.

#Future Deploy Script

Once the AWS bucket and distribution exist, create:


Tools/deploy_docs_site.ps1

It should:

  1. Build the site.
  1. Run the public safety scan.
  1. Sync Docs/Site to S3.
  1. Invalidate CloudFront.

Draft shape:


param(

    [Parameter(Mandatory = $true)]

    [string]$BucketName,



    [Parameter(Mandatory = $true)]

    [string]$DistributionId

)



$ErrorActionPreference = "Stop"



python Tools\build_docs_site.py

powershell -ExecutionPolicy Bypass -File Tools\scan_public_docs.ps1

aws s3 sync Docs\Site "s3://$BucketName" --delete

aws cloudfront create-invalidation --distribution-id $DistributionId --paths "/*"


#Open Questions

  • [ ] What domain should be used?
  • [ ] Is DNS in Route 53 or another registrar/provider?
  • [ ] Should screenshots be public?
  • [ ] Should the public site include all docs or only a curated subset?
  • [ ] Should deployment happen from this machine, private Git CI, or an AWS pipeline later?