Deploy a static site on Bahriya
This quickstart deploys a static site — the build output from Vite, Create React App, Astro, or any similar tool — as an HTTP container served by nginx on port 80. You get a public hostname with automatic TLS, and you can cache assets at the edge for fast delivery.
This quickstart deploys a static site — the build output from Vite, Create React App, Astro, or any similar tool — as an HTTP container served by nginx on port 80. You get a public hostname with automatic TLS, and you can cache assets at the edge for fast delivery.
A static site is just files. The pattern is to build those files in one stage, then copy them into a small nginx image that serves them. The only differences between tools are the build command and the output directory: Vite and Astro emit dist, Create React App emits build.
Dockerfile
This example builds a Vite project and serves the dist directory. For Create React App, change dist to build in the final COPY:
# Build stage
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Serve stage
FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]nginx listens on port 80 by default, binds to all interfaces, and logs access and errors to standard output and error, so it works with Bahriya as-is.
Client-side routing
Single-page apps (React, Vue, and similar) need every unknown path to fall back to index.html so client-side routing works on a hard refresh. Add an nginx.conf and copy it into the image:
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}COPY nginx.conf /etc/nginx/conf.d/default.confAstro and other multi-page outputs that already emit an HTML file per route do not need this fallback.
Deploy from the Console
- Create a new HTTP container in your project.
- Set the image to your built reference and select a registry if it is private.
- Set the port to
80. A static nginx site serves/reliably, so/is a fine health check path. - Choose regions, set CPU and memory, and create the container.
Deploy with Reis
reis container:create \
--type http \
--name "Marketing Site" \
--handle site \
--image ghcr.io/myorg/site:1.0.0 \
--project my-project \
--port 80 \
--healthcheck / \
--cpu 350 \
--memory 150 \
--replicas 2 \
--regions falkenstein-1 \
--regions virginia-1Static sites are light on CPU and memory, so the defaults are usually enough.
Caching and custom domains
- Turn on proxy caching to serve your assets from the edge and take load off your container — ideal for a static site where responses rarely change.
- Point your own hostname at the site with Custom domain setup; TLS is provisioned automatically.
Next steps
- Proxy caching — cache static responses close to your users.
- HTTP containers — hostnames, TLS, and security knobs.
- Custom domain setup — serve on your own domain.
- Deploy an HTTP container with flags — the full Reis reference.