Skip to main content

Publish a static site

Available

Deployed and supported. The fields and commands described here are stable within version v1alpha1.

A static site serves the files of a folder (HTML, CSS, JS, images) behind a cache, under <name>.<tenant>.dev.stackngo.app. You create the site with sng cdn create, then you publish your build folder with sng cdn upload; no server to run.

Prerequisites​

  • The sng CLI authenticated, a session on your tenant (sng tenant use acme); sng config show displays the cluster and the tenant.
  • The rights cdn:write (create), cdn:upload and cdn:purge (publish and clear the cache): included in the managed policies readwrite and admin.
  • A folder to publish, for example the dist/ produced by npm run build.

1. Create the site​

sng cdn create docs
site docs créé : https://docs.acme.dev.stackngo.app (stockage default)
déposez le contenu : sng cdn upload docs ./dist
le site est servi dans quelques minutes.

The site name becomes the first label of the domain: lowercase letters, digits and -, 63 characters at most. The site is stored by the platform (default storage); you have neither a bucket nor a key to manage.

The same site as a manifest:

docs-site.yml
apiVersion: cdn.stackngo.io/v1alpha1
kind: CDNSite
metadata:
name: docs
spec:
domain: docs.acme.dev.stackngo.app
fallback: index.html # served for unknown routes (single-page application)
sng apply docs-site.yml

2. Publish the content​

npm run build
sng cdn upload docs ./dist
envoyé 42/42
site docs : 42 fichier(s) publié(s), 0 retiré(s)

Files are uploaded in parallel, then the platform checks that everything has arrived and clears the site's cache. Files that no longer exist in your folder stay online; to remove them:

sng cdn upload docs ./dist --prune
envoyé 40/40
site docs : 40 fichier(s) publié(s), 2 retiré(s)

3. Choose how routes behave​

RequestFile served
/index.html
/assets/app.3f9c.jsassets/app.3f9c.js, or 404
/docs/intro/ (ends with /)docs/intro/index.html if it exists, otherwise the fallback
/docs/intro (no extension)docs/intro if it exists, otherwise docs/intro/index.html, otherwise the fallback

Each folder therefore serves its index.html, with or without a trailing /: a site built by a static site generator (Docusaurus, Hugo, MkDocs…) works as is, without adjusting its links.

The fallback (index.html by default with sng cdn create) suits single-page applications (React Router, Vue Router): any route without an extension that matches no file or folder returns your index.html with a 200 code. A route with an extension (.png, .js) that is missing returns 404.

Without a fallback: sng cdn create docs --fallback "", or remove fallback from the manifest.

Verification​

sng cdn list
NAME URL STORAGE STATUS STATE
docs https://docs.acme.dev.stackngo.app default enabled Ready

sng cdn list shows what you declared, and the state of the site in the STATE column: Ready when it is served, Waiting or Pending while it waits for something (a message under the table explains what). sng kind get CDNSite docs shows its manifest, then its state as comments (Ready condition, reason and message). Also check it directly:

curl -sI https://docs.acme.dev.stackngo.app/

HTTP/2 200, content-type: text/html; charset=utf-8. As long as the site is not served yet, it responds 404 not found: wait a few minutes (for a brought domain, the time for its zone to be verified).

HTTPS

The site automatically receives a valid HTTPS certificate, with nothing to declare, usually within minutes of its creation. This wildcard certificate covers all your sites placed directly under your zone: the next one (blog.acme.dev.stackngo.app) is served over HTTPS as soon as it is created. If curl still reports an invalid certificate an hour after the site was created, contact support. To serve your own certificate, see tlsSecretRef in CDNSite.

Publish from a CI​

.gitlab-ci.yml
deploy-docs:
stage: deploy
image: node:22
script:
- npm ci && npm run build
- sng tenant use acme
- sng cdn upload docs ./dist --prune
rules:
- if: $CI_COMMIT_BRANCH == "main"

Authenticating sng in a job (machine account or OIDC federation) is described in CI/CD. Give the CI's identity a policy limited to this site: cdn:upload and cdn:purge on cdn/docs.

Going further​

  • Upload limits: 100 MiB per file, 20,000 files per site and per upload (sent in batches of 1,000). File names: letters, digits and ._~@+=,-; no spaces or accents. Symbolic links are ignored (warning on standard error), .git/ and .DS_Store are never sent.
  • Parallelism: --concurrency N (1 to 32, 8 by default).
  • Content type: inferred from the extension (.html, .css, .js, .mjs, .json, .svg, .woff2, .wasm…), application/octet-stream otherwise.
  • Cache: see Maintenance and cache.
  • Your own bucket: a site can serve an object storage bucket that belongs to you (spec.s3); sng cdn upload does not apply then, upload the files yourself. See CDNSite.
  • Domains: a site is named under <tenant>.dev.stackngo.app (docs.acme.dev.stackngo.app, v2.docs.acme.dev.stackngo.app), or under a brought domain (docs.exemple.fr, see Bring a domain). You can declare the site before its zone: it stays in Waiting and goes live as soon as the zone is verified, with no new command.
  • One scope: the sites are the tenant's; a site name and a domain can only be used once in the tenant.

See also​