Static Sites
Deploy static websites and Single Page Applications (SPAs)
Static Sites
Deploy static websites, documentation sites, and Single Page Applications (SPAs) with Senate.
Quick Deploy with Nginx
Create service
Go to Services → New Service
Enter service name: my-website and click Create
Configure source
- Go to the Source tab
- Select Docker Image as source type
- Enter image:
nginx:alpine - Click Save
Add your site
Mount your static files:
| Host Path | Container Path |
|---|---|
/path/to/site | /usr/share/nginx/html:ro |
Add domain
Add your domain in the Domains tab.
Deploy
Click Create to deploy.
Pre-built Static Images
Build your own image
Create a Dockerfile:
FROM nginx:alpine
COPY ./dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.confBuild and push:
docker build -t myuser/mysite:latest .
docker push myuser/mysite:latestThen deploy with the image myuser/mysite:latest.
SPA Configuration
Single Page Applications need special routing:
Nginx config for SPAs
Create nginx.conf:
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}Dockerfile for SPAs
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80Framework Examples
React (Vite)
# Build stage
FROM node:20-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Serve stage
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.confVue
FROM node:20-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.confNext.js (Static Export)
For next export:
FROM node:20-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/out /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.confAstro
FROM node:20-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/htmlAlternative: Caddy
Caddy has simpler config and automatic HTTPS:
Caddyfile
:80 {
root * /srv
file_server
try_files {path} /index.html
}Dockerfile with Caddy
FROM caddy:alpine
COPY dist/ /srv/
COPY Caddyfile /etc/caddy/CaddyfileCompression
Enable gzip compression:
Nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;Caddy
Caddy enables compression by default with encode:
:80 {
root * /srv
encode gzip
file_server
}Security Headers
Add security headers in nginx:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;CI/CD Integration
GitHub Actions
name: Deploy Static Site
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install and build
run: |
npm ci
npm run build
- name: Build and push image
run: |
docker build -t myuser/mysite:${{ github.sha }} .
docker push myuser/mysite:${{ github.sha }}
- name: Deploy to Senate
run: curl "${{ secrets.SENATE_WEBHOOK }}Documentation Sites
VitePress
FROM node:20-alpine as build
WORKDIR /app
COPY . .
RUN npm ci && npm run docs:build
FROM nginx:alpine
COPY --from=build /app/docs/.vitepress/dist /usr/share/nginx/htmlDocusaurus
FROM node:20-alpine as build
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/htmlPerformance Tips
- Enable caching: Set long cache headers for static assets
- Use CDN: Put Cloudflare or similar in front
- Optimize images: Use WebP, proper sizing
- Minimize bundles: Code split, tree shake
- Preload critical assets: Use
<link rel="preload">
Related
- CI/CD Integration - Automate deployments
- Domains - Custom domains