🟢 Static Container Builder
Ship a static site as an HTTPS container. A Dockerfile, nginx config, and entrypoint that bake any static site into a self-contained image that serves itself over HTTPS.
Install & availability
Available now. Install from the Companion Hub App Store. The published image is public, so you can also pull it without a Hub.
| Hub App Store | Search Static Container Builder → Install |
| Ports | 80 (HTTP → HTTPS redirect) and 443 (HTTPS). The Hub listing routes only port 80. |
| Minimum Hub version | 0.2.27 |
| Architecture | linux/amd64 and linux/arm64 (multi-arch) |
Overview
The Static Container Builder is a small, practical build artifact: a Dockerfile + nginx config + entrypoint (with an alternate Spin/WASM variant) that packages a directory of static files into a container which serves them over HTTPS. You point it at your built static site and get back an image you can run anywhere — including as a Hub app.
It is not a CLI tool or an app framework. There is no scaffolding command, no manifest format, and no agent/memory integration — it is a container recipe for static hosting done well.
Current capabilities
What the Static Container Builder is today:
- A Dockerfile + nginx config + entrypoint that bakes static files into an image
- Serves on port 80 (redirects to HTTPS) and port 443 (HTTPS with HTTP/2)
- Uses a self-signed certificate by default, overridable via
SSL_DOMAIN,SSL_CERTandSSL_KEY, or by mounting your own certificate files - Exposes a
/healthendpoint on the HTTPS port - A Spin / WASM image variant alongside the nginx one. It serves plain HTTP on port
3000and needs a TLS proxy in front for HTTPS - Multi-arch images (amd64 + arm64)
- The nginx image is hermetic / offline-safe at runtime — it needs no network to serve
Usage
You use the builder in one of two ways: base your own image on the public image, or build directly with a build arg. Either way you get one image that serves itself over HTTPS wherever you run it. Only the first way works without access to the source repository, which is private.
flowchart TD
SITE["Your built static site<br/>e.g. dist/"] -->|"docker build<br/>--build-arg STATIC_FILES_PATH=./dist"| IMG
SITE -->|"FROM ci-static-containter-builder<br/>COPY ./dist"| IMG["Your image<br/>nginx variant, or Spin / WASM"]
IMG -->|"docker run"| C["Container start<br/>entrypoint picks TLS material:<br/>SSL_CERT + SSL_KEY, files in /etc/nginx/ssl,<br/>or a self-signed cert for SSL_DOMAIN"]
C --> S80["Port 80<br/>redirects to HTTPS"]
C --> S443["Port 443 HTTPS<br/>plus /health"]
IMG -.->|"the same image"| HUB["Run anywhere<br/>including as a Hub app"]Base your image on it
Put these two lines in a Dockerfile next to your built site, then build and run it:
FROM ghcr.io/companionintelligence/ci-static-containter-builder:latest
COPY ./dist /usr/share/nginx/htmldocker build -t my-static-site .
docker run -p 80:80 -p 443:443 my-static-siteBrowse to https://localhost and accept the self-signed certificate warning. Publish ports 80 and 443 as shown. The redirect on port 80 sends browsers to https://<host>/ on the standard HTTPS port, so if you publish 443 on another port, such as -p 8443:443, open https://localhost:8443 directly.
Build with a build arg
If you have the source repository, build its Dockerfile directly:
docker build \
--build-arg STATIC_FILES_PATH=./dist \
-t my-static-site .TLS configuration
By default the container generates and serves a self-signed certificate valid for 365 days. At startup the entrypoint picks the certificate in this order:
SSL_CERTandSSL_KEY, when both are set- Files already at
/etc/nginx/ssl/server.crtand/etc/nginx/ssl/server.key, for example from a mounted volume - A self-signed certificate for
SSL_DOMAIN
| Variable | Default | Purpose |
|---|---|---|
SSL_DOMAIN | localhost | Hostname for the self-signed certificate |
SSL_CERT | none | PEM-encoded certificate text. Set it together with SSL_KEY. |
SSL_KEY | none | PEM-encoded private key text. Set it together with SSL_CERT. |
If only one of SSL_CERT and SSL_KEY is set, the entrypoint logs a warning and falls back to a self-signed certificate.
The container’s filesystem is not read-only/immutable: the entrypoint writes certificate material at startup. The nginx image is offline-safe at runtime, but it does mutate its own filesystem to set up TLS.
Health checks
GET /health on the HTTPS port returns healthy for liveness and readiness probes. The image’s own Compose file checks https://localhost/health.
Use Cases
- Package a built static site (docs, dashboard, landing page) into an HTTPS-serving container
- Run a static admin/dashboard UI as a Hub app on its own port
- Distribute a static site as a single OCI image with TLS already configured
Setup
Install from Hub
Search for Static Container Builder in the Hub app store and install to run the reference image. The install form has an App Seed that Hub generates (don’t change it after install) and a Share crash reports switch that is on by default.
The Hub listing routes only the container’s port 80, and port 80 always
answers with a redirect to HTTPS on port 443. If the app card’s link doesn’t
load the reference page, run the image yourself with both ports published, as
shown in Usage.
Build your own site image
Write a Dockerfile that does FROM ghcr.io/companionintelligence/ci-static-containter-builder:latest and COPYs your files into the web root. If you have access to the source repository, you can instead build with --build-arg STATIC_FILES_PATH=… pointing at your static output directory.
Configure TLS (optional)
Set SSL_DOMAIN for the self-signed certificate’s hostname, or set SSL_CERT and SSL_KEY (or mount server.crt and server.key at /etc/nginx/ssl) to use your own certificate.
Troubleshooting
Browser warns about the certificate
The default certificate is self-signed. Provide your own via SSL_DOMAIN / SSL_CERT / SSL_KEY, or trust the self-signed cert for testing.
docker build can’t find my files
Make sure your static output (e.g. dist/) is built first and sits in the build context. If you build with STATIC_FILES_PATH, it must point at a directory that exists in the build context.