Skip to content

Deploy to AWS

Amazon Web Services (AWS) is the world’s largest cloud platform. It offers hundreds of services, but for a static site like Astro Docus, you only need two:

  • Amazon S3 — Stores your built files (HTML, CSS, JS, images)
  • Amazon CloudFront — A global CDN that caches and delivers those files to users worldwide

This is the recommended architecture for static sites on AWS. It is serverless, highly available, and costs virtually nothing for low-to-medium traffic .

AWS is more complex to set up than Cloudflare Pages or Netlify. But it gives you full control, and the free tier includes 5 GB of S3 storage and 1 TB of CloudFront data transfer per month .


Before starting, you need:

  • An AWS account (free tier available)
  • Your Astro Docus project built locally (npm run build works)
  • The dist/ folder generated
  • Basic familiarity with the AWS Console (we will guide you)

User → CloudFront (CDN) → S3 Bucket (private)
  • S3 holds your files. It stays private — no public access.
  • CloudFront reads from S3 using Origin Access Control (OAC) and serves content globally .
  • HTTPS is provided by CloudFront automatically.
  • Custom domain (optional) is configured via AWS Certificate Manager and Route 53.

This is more secure than the old “public S3 bucket” approach. Users never access S3 directly .


  1. Log in to the AWS Management Console: https://console.aws.amazon.com/s3/
  2. Click Create bucket
  3. Enter a globally unique bucket name (e.g., astrodocus-site)
  4. Choose a region close to you (e.g., us-east-1)
  5. Leave “Block all public access” checked — we will use CloudFront, not public access
  6. Click Create bucket
  1. Open your new bucket
  2. Click Upload
  3. Drag the contents of your dist/ folder (not the folder itself) into the upload area
  4. Click Upload

Important: Upload the files inside dist/, not the dist folder itself. The index.html must be at the root of the bucket.


Step 2 — Create a CloudFront Distribution

Section titled “Step 2 — Create a CloudFront Distribution”
  1. Go to the CloudFront Console: https://console.aws.amazon.com/cloudfront/
  2. Click Create distribution
  3. For Origin domain, select your S3 bucket
  4. For Origin access, choose Origin access control settings (recommended)
  5. Click Create control setting — use the default name
  6. For Viewer protocol policy, choose Redirect HTTP to HTTPS
  7. For Default root object, enter index.html
  8. Leave other settings as default
  9. Click Create distribution

After creating the distribution, CloudFront shows a bucket policy you need to copy. Go back to S3:

  1. Open your bucket → Permissions tab
  2. Click Bucket policy → Edit
  3. Paste the policy CloudFront provided
  4. Save

This grants CloudFront permission to read your bucket securely .

In the CloudFront console, find your distribution’s Domain name (e.g., d111111abcdef8.cloudfront.net). Open this URL in your browser — your site should be live.


Step 3 — Automate with GitHub Actions (Optional)

Section titled “Step 3 — Automate with GitHub Actions (Optional)”

Once the infrastructure is set up, you can automate deployments. Every push to main builds and deploys automatically .

  1. Go to IAM Console → Users → Create user
  2. Name it github-deploy
  3. Attach a policy with these permissions:
    • s3:PutObject, s3:DeleteObject, s3:ListBucket
    • cloudfront:CreateInvalidation
  4. Create the user and save the Access Key ID and Secret Access Key
  1. Go to your GitHub repository → Settings → Secrets and variables → Actions
  2. Add these secrets :
Secret NameValue
AWS_ACCESS_KEY_IDYour IAM access key
AWS_SECRET_ACCESS_KEYYour IAM secret key
AWS_REGIONus-east-1
S3_BUCKETYour bucket name
CLOUDFRONT_DISTRIBUTION_IDYour distribution ID

Create .github/workflows/deploy.yml in your project :

name: Deploy to AWS S3 and CloudFront
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Astro site
run: npm run build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Sync files to S3
run: |
aws s3 sync dist/ s3://${{ secrets.S3_BUCKET }} --delete
- name: Invalidate CloudFront cache
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \
--paths "/*"

Push this file to GitHub. The workflow runs on every push to main .


A *.cloudfront.net URL works, but a custom domain looks more professional.

  1. Go to AWS Certificate Manager (ACM) — must be in us-east-1 region
  2. Click Request a certificate → Request a public certificate
  3. Enter your domain (e.g., docs.yourdomain.com)
  4. Choose DNS validation
  5. Add the CNAME records to your DNS provider
  6. Wait for validation
  1. Open your CloudFront distribution
  2. Click Edit
  3. Under Alternate domain name (CNAME), add your domain
  4. Under Custom SSL certificate, select your ACM certificate
  5. Save

At your domain registrar, create a CNAME record:

docs.yourdomain.com → d111111abcdef8.cloudfront.net

Or use Route 53 with an A record (alias) pointing to your CloudFront distribution .


ServiceFree TierAfter Free Tier
S35 GB storage, 20,000 GET requests~$0.023/GB
CloudFront1 TB data transfer out/month~$0.085/GB
ACMFreeFree
Route 53—~$0.50/month per hosted zone

For a documentation site with moderate traffic, you will likely stay within the free tier .


ProblemLikely CauseFix
403 ForbiddenBucket policy missingPaste the CloudFront policy into S3
404 on subpagesMissing index documentSet Default root object to index.html
Changes not showingCloudFront cacheCreate an invalidation (/*)
Custom domain not workingDNS not propagatedWait, or verify CNAME
SSL errorCertificate not in us-east-1Re-request in the correct region

1. Create S3 bucket (private, no public access)
2. Upload dist/ contents
3. Create CloudFront distribution with OAC
4. Copy bucket policy from CloudFront → paste into S3
5. Site is live at *.cloudfront.net
6. (Optional) Automate with GitHub Actions
7. (Optional) Add custom domain with ACM + Route 53

AWS gives you full control and enterprise-grade reliability. The S3 + CloudFront pattern is the standard architecture for static sites on AWS .

👉 Next: docs/deploy-hosting/vps.md — deploy to a VPS.