NimbusNexus

Deploy a static site

S3-compatible object storage doubles as a static-site host. You upload your built files to a bucket, mark them public-read, point your domain at the bucket's URL, and you have a CDN-backed static site at a few cents per month.

This guide takes you from a built dist/ directory (the output of any modern static-site generator — Next.js export, Astro, Hugo, plain HTML) to a live site at your domain.

Prereqs

  • A NimbusNexus account with an API key.
  • A built site in a local dist/ directory.
  • A domain you control (or use a NimbusNexus-issued subdomain to skip the domain step).
  • awscli configured to talk to NimbusNexus object storage (or any S3-compatible client — rclone, mc, s3cmd).
export NIMBUS_KEY="nn_live_xxxxxxxxxxxxxxxx"
export BUCKET="my-site"
export REGION="us-east-1"

1 · Create the bucket

curl -X POST https://api.nimbusnexus.net/v1/buckets \
  -H "Authorization: Bearer $NIMBUS_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"$BUCKET\",
    \"region\": \"$REGION\",
    \"storage_class\": \"standard\",
    \"public_read\": true,
    \"website\": {
      \"enabled\": true,
      \"index_document\": \"index.html\",
      \"error_document\": \"404.html\"
    }
  }"

What each option does:

  • public_read: true — anyone on the internet can GET any object in the bucket. Required for static hosting; the bucket name appears in URLs.
  • website.enabled: true — enables static-site mode. The bucket starts serving HTML with the right Content-Type, follows index_document for directory requests, and renders error_document on 4xx.

The response includes the bucket's URL:

{
  "id": "bkt_01HG7Y3...",
  "url": "https://my-site.s3.us-east-1.nimbusnexus.net",
  "website_endpoint": "https://my-site.s3.us-east-1.nimbusnexus.net"
}

2 · Configure S3 CLI

aws configure set aws_access_key_id $NIMBUS_KEY
aws configure set aws_secret_access_key $NIMBUS_SECRET
aws configure set region $REGION
aws configure set s3.endpoint_url https://s3.us-east-1.nimbusnexus.net

$NIMBUS_SECRET is the secret half of an S3-compatible access key, generated in the dashboard at Settings → Object Storage Keys → New key. Don't confuse it with the regular API key — they're different.

3 · Upload your site

aws s3 sync ./dist s3://$BUCKET \
  --delete \
  --cache-control "public, max-age=3600" \
  --endpoint-url https://s3.us-east-1.nimbusnexus.net

--delete removes files in the bucket that aren't in ./dist anymore. --cache-control sets a 1-hour cache header on every object — long enough that browsers don't re-fetch on every page load, short enough that you don't have to bust caches manually on a typo fix.

For files that should NEVER cache (your index.html):

aws s3 cp ./dist/index.html s3://$BUCKET/index.html \
  --cache-control "no-cache, max-age=0" \
  --endpoint-url https://s3.us-east-1.nimbusnexus.net

Pattern: long cache on hashed assets (/_app/[hash].js), no-cache on the entry HTML that references them. Same pattern Vercel + Netlify + Cloudflare Pages use under the hood.

4 · Verify it works

Visit https://my-site.s3.us-east-1.nimbusnexus.net in a browser. You should see your site.

If you see XML instead, the website endpoint isn't routing correctly — most often because public_read wasn't set or website.enabled wasn't set. Re-check the bucket config:

curl https://api.nimbusnexus.net/v1/buckets/$BUCKET \
  -H "Authorization: Bearer $NIMBUS_KEY"

5 · Custom domain (optional)

Add a DNS record at your registrar pointing your domain at the bucket:

www.example.com   CNAME   my-site.s3.us-east-1.nimbusnexus.net

For an apex domain (example.com without www.), CNAMEs don't work — apex CNAME records are illegal per RFC. Two options:

  1. Use www.example.com as the canonical and redirect apex → www
  2. Add an A record on the apex pointing at a floating IP attached to a tiny VM running a redirect (300 lines of nginx config, ~$5/mo)

Once the DNS record propagates (1 minute to 24 hours depending on your registrar's TTL):

curl -X PATCH https://api.nimbusnexus.net/v1/buckets/$BUCKET \
  -H "Authorization: Bearer $NIMBUS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "custom_domains": ["www.example.com"]
  }'

This tells the bucket to accept requests with Host: www.example.com and to issue a TLS cert for that hostname (Let's Encrypt-backed, auto-renewed).

6 · Wire up a deploy pipeline

The above is the one-shot deploy. For CI/CD, the pattern is the same aws s3 sync from a GitHub Action (or any CI runner):

# .github/workflows/deploy.yml (abbreviated)
- name: Deploy
  run: |
    aws s3 sync ./dist s3://$BUCKET --delete --endpoint-url $ENDPOINT
  env:
    AWS_ACCESS_KEY_ID:     ${{ secrets.NIMBUS_S3_KEY }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.NIMBUS_S3_SECRET }}
    BUCKET:                my-site
    ENDPOINT:              https://s3.us-east-1.nimbusnexus.net

Most CI systems already have S3-compatible deploy actions; you point them at our endpoint and they work unchanged.

Cost

Storage: $0.013/GB-month standard. A 50 MB site costs about a penny a month.

Egress: free for the first 100 GB/month, $0.01/GB after that. A site serving 100k page views at 200 KB per page is 20 GB — still free tier.

Compared to the same workload on AWS CloudFront + S3: typically 4–6× cheaper at the egress line, similar at the storage line.

Next steps

  • Object storage reference — the full bucket API.
  • DNS zones — host your DNS on NimbusNexus directly instead of at your registrar.
  • Cold storage — for the parts of your storage you almost never read (build artifacts, old releases).