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.

Updated 3 Aug 20262 min read

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.conf

Astro and other multi-page outputs that already emit an HTML file per route do not need this fallback.

Deploy from the Console

  1. Create a new HTTP container in your project.
  2. Set the image to your built reference and select a registry if it is private.
  3. Set the port to 80. A static nginx site serves / reliably, so / is a fine health check path.
  4. 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-1

Static 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