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).
awscliconfigured 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 canGETany 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 rightContent-Type, followsindex_documentfor directory requests, and renderserror_documenton 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:
- Use
www.example.comas the canonical and redirect apex → www - 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).