# How to host a static site on object storage

Source: https://docs.quake.ai/docs/object/how-to/host-static-site
Markdown: https://docs.quake.ai/docs/object/how-to/host-static-site.md

---

# How to host a static site on object storage

Serve HTML, CSS, JavaScript, and image files from a Quake AI object storage bucket. For a custom domain or HTTPS at the edge, put a [CDN in front of the bucket](/docs/network/how-to/front-with-cdn) and [point your domain](/docs/network/how-to/point-domain-to-quake-ai) at the CDN.



A public-read bucket alone exposes objects at the S3-compatible endpoint URL. Visitors expect `https://www.example.com/`. Terminate TLS and map the hostname at a CDN provider, then restrict direct bucket access if you need cache and WAF controls at the edge.



<PrerequisiteBlock methods={["console", "cli", "api"]}>

- An object storage [bucket](/docs/object/how-to/create-container)
- [S3 credentials](/docs/object/how-to/create-s3-credentials) configured in your CLI environment
- Static site files built locally (`index.html`, assets)

</PrerequisiteBlock>

## Upload site files

<MethodTabs>
<Method label="Console">

1. Open **Storage** > **Object Storage** and select your bucket.
2. Use **Upload** to add `index.html` and asset files. Preserve folder prefixes if your site uses subpaths (`css/app.css` uploads as key `css/app.css`).

</Method>
<Method label="CLI">




Sync a local build directory to the bucket:

```bash
aws s3 sync ./dist s3://MY_BUCKET/ \
  --endpoint-url "$S3_ENDPOINT" \
  --acl public-read
```

Set the correct `Content-Type` metadata for HTML and assets when browsers mis-detect types:

```bash
aws s3 cp ./dist/index.html s3://MY_BUCKET/index.html \
  --endpoint-url "$S3_ENDPOINT" \
  --acl public-read \
  --content-type text/html
```




```bash
openstack object create MY_CONTAINER index.html --file ./dist/index.html
```

For many files, use `swift upload` or the S3-compatible client above.




</Method>
<Method label="API">

Use `PUT` against the S3-compatible endpoint with the tenant-prefixed object path in [Anonymous URL shape](/reference/object-storage/bucket-policies#anonymous-url-shape).

</Method>
</MethodTabs>

## Make objects readable

Apply a [public read bucket policy](/reference/object-storage/bucket-policies#public-read) so anonymous `GET` requests succeed. Test with the tenant-prefixed URL shape:

```text
https://object.<region>.rumble.cloud/<tenant>:<bucket>/index.html
```

Replace `<region>`, `<tenant>`, and `<bucket>` with your project values.

## Add a custom domain (recommended)

1. Point a CDN pull zone or reverse-proxy origin at the bucket endpoint, or at a small reverse-proxy instance that fetches from the bucket.
2. Follow [How to put a CDN in front of a Quake AI workload](/docs/network/how-to/front-with-cdn).
3. Publish DNS records with [How to point a domain at a Quake AI resource](/docs/network/how-to/point-domain-to-quake-ai) (or the CDN provider's CNAME instructions).
4. Issue TLS at the CDN edge or on the origin with [Let's Encrypt](/docs/network/how-to/lets-encrypt-certificate).

## Verify

```bash
curl -I "https://object.<region>.rumble.cloud/<tenant>:<bucket>/index.html"
```

Expect `HTTP/1.1 200` and a `Content-Type` appropriate for HTML. After CDN setup, repeat the check against your public hostname.

## See also

- [How to create an object storage bucket](/docs/object/how-to/create-container)
- [How to upload a file to object storage](/docs/object/how-to/upload-file)
- [Public read policy](/reference/object-storage/bucket-policies#public-read)
- [Host a static website tutorial](/docs/quickstart/host-static-website) (VM-based alternative)
- [CloudFront in front of object storage](/docs/object/how-to/use-cloudfront-with-buckets)
