This document provides comprehensive instructions for deploying MD-Book to various hosting platforms including Cloudflare Pages, Workers, and Netlify.
MD-Book supports multiple hosting platforms:
- Cloudflare Pages - Unlimited bandwidth, Workers integration, advanced caching
- Netlify - Simple deployment, forms, branch previews, generous free tier
- Vercel - Zero-config deployments, edge functions, serverless integration
- GitHub Pages - Free hosting for public repos, Jekyll-free static sites
- AWS Amplify - AWS integration, serverless backend, custom domains
- Render - Free SSL, auto-deploy from Git, DDoS protection
- Railway - Simple deployments, automatic HTTPS, preview environments
- Fly.io - Edge deployment, global distribution, Dockerfile support
- DigitalOcean App Platform - Simple pricing, managed infrastructure
# Run the setup script to configure everything
./scripts/setup-cloudflare.sh# Set up 1Password integration (secure, team-friendly)
./scripts/setup-1password.sh
# Deploy with 1Password
op run --env-file=.env.1password -- ./scripts/deploy.sh production# Copy environment template
cp .env.example .env
# Set your Cloudflare credentials (get these from Cloudflare Dashboard)
export CLOUDFLARE_API_TOKEN="your-api-token-here" # From API Tokens page
export CLOUDFLARE_ACCOUNT_ID="your-account-id-here" # From Dashboard sidebar.env file to git - it's already in .gitignore
🔐 1Password Benefits: Secure secret storage, team collaboration, audit trails, and automated rotation.
# Deploy to production with 1Password
op run --env-file=.env.1password -- ./scripts/deploy.sh production
# Deploy to staging with 1Password
op run --env-file=.env.1password -- ./scripts/deploy.sh staging
# Auto-detect 1Password (fallback to env vars if not available)
./scripts/deploy.sh production
# Force disable 1Password
USE_1PASSWORD=false ./scripts/deploy.sh production# Deploy to production
./scripts/deploy.sh production
# Deploy to staging
./scripts/deploy.sh staging┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ GitHub Repo │───▶│ GitHub Actions │───▶│ Cloudflare Edge │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌─────────────────────┐
│ Build Process │ │ Cloudflare Pages │
│ │ │ (Static Hosting) │
│ • Rust Compile │ └─────────────────────┘
│ • Static Site │ │
│ • Asset Optimize │ ▼
│ • Search Index │ ┌─────────────────────┐
└──────────────────┘ │ Cloudflare Workers │
│ (API & Functions) │
└─────────────────────┘
- Purpose: Static site hosting with global CDN
- Features: Automatic HTTPS, instant deployments, preview deployments
- Configuration:
wrangler.toml
- Purpose: API endpoints, redirects, and edge functions
- Features: Sub-millisecond response times, serverless scaling
- Configuration:
worker/wrangler.toml
- Purpose: Automated CI/CD pipeline
- Features: Testing, building, deploying, monitoring
- Configuration:
.github/workflows/
- Trigger: Push to
mainbranch - URL:
https://md-book.pages.dev - Features: Full feature set, production optimizations
- Workflow:
.github/workflows/deploy.yml
- Trigger: Manual deployment
- URL:
https://md-book-staging.pages.dev - Features: Same as production, used for testing
- Command:
./scripts/deploy.sh staging
- Trigger: Pull requests
- URL:
https://preview-{pr-number}.md-book.pages.dev - Features: Automatic preview for PR changes
- Duration: Temporary, removed when PR is closed
Initial setup for Cloudflare deployment
- Installs required tools
- Configures environment
- Tests local build
- Provides GitHub Actions setup instructions
1Password integration setup for secure secret management
- Installs and configures 1Password CLI
- Creates vault and items for Cloudflare secrets
- Tests secret retrieval
- Generates .env file from 1Password vault
Comprehensive secret validation
- Validates 1Password setup and access
- Checks environment variables
- Tests GitHub secrets (optional)
- Validates Cloudflare API connection (optional)
GitHub secrets synchronization from 1Password
- Retrieves secrets from 1Password vault
- Syncs to GitHub repository secrets
- Supports dry-run mode for testing
Comprehensive deployment script
- Runs tests and builds
- Deploys to Cloudflare Pages
- Optionally deploys Worker
- Provides deployment summary
Examples:
# Traditional deployment
./scripts/deploy.sh production
./scripts/deploy.sh staging docs dist
SKIP_TESTS=true ./scripts/deploy.sh production
DEPLOY_WORKER=false ./scripts/deploy.sh production
# 1Password integration
op run --env-file=.env.1password -- ./scripts/deploy.sh production
USE_1PASSWORD=false ./scripts/deploy.sh production # Force disable 1PasswordWorker-specific deployment
- Validates Worker code
- Deploys to specified environment
- Shows deployment history
Deployment monitoring and health checks
- Tests site availability
- Checks API endpoints
- Measures performance
- Validates SSL certificates
Examples:
./scripts/monitor.sh # Full check of all environments
./scripts/monitor.sh production # Check production only
./scripts/monitor.sh production quick # Quick health checkCLOUDFLARE_API_TOKEN=your_cloudflare_api_token # See "GitHub Secrets" section for details
CLOUDFLARE_ACCOUNT_ID=your_cloudflare_account_id # See "GitHub Secrets" section for detailsHow to Get These Values:
CLOUDFLARE_API_TOKEN: Create at Cloudflare API TokensCLOUDFLARE_ACCOUNT_ID: Found in Cloudflare Dashboard sidebar
INPUT_DIR=test_input # Source markdown directory
OUTPUT_DIR=dist # Build output directory
SKIP_TESTS=false # Skip tests during deployment
DEPLOY_WORKER=true # Deploy worker with pages- Project configuration
- Security headers
- Caching rules
- Custom domains
- Redirects
- Worker configuration
- Route patterns
- Environment variables
- Resource limits
Add these secrets to your GitHub repository (Settings → Secrets and variables → Actions):
CLOUDFLARE_API_TOKEN
- Purpose: Authenticates with Cloudflare API for deployments
- Permissions Required:
Cloudflare Pages:Edit,Zone:Read,Account:Read - How to Get:
- Go to Cloudflare Dashboard → My Profile → API Tokens
- Click "Create Token"
- Use "Custom Token" template
- Set permissions:
Cloudflare Pages:Edit,Zone:Read,Account:Read - Optionally restrict to specific account/zones
- Copy the generated token (save it securely - you won't see it again)
CLOUDFLARE_ACCOUNT_ID
- Purpose: Identifies your Cloudflare account for resource management
- How to Get:
- Go to Cloudflare Dashboard
- Select any domain or go to the main dashboard
- In the right sidebar, copy the "Account ID" value
- It looks like:
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
- Never commit these values to your repository
- Use minimal permissions - only grant what's needed
- Rotate tokens regularly (every 90 days recommended)
- Monitor token usage in Cloudflare Dashboard → API Tokens
MD-Book includes comprehensive 1Password CLI integration for secure secret management:
- 🔐 Secure Storage: No secrets in plain text files or environment variables
- 👥 Team Collaboration: Shared vaults for team deployments
- 📊 Audit Trail: Complete history of secret access
- 🔄 Easy Rotation: Automatic propagation to all environments
- 🎯 Principle of Least Privilege: Service accounts with minimal permissions
# 1. Set up 1Password integration
./scripts/setup-1password.sh
# 2. Deploy with 1Password
op run --env-file=.env.1password -- ./scripts/deploy.sh production
# 3. Sync secrets to GitHub for Actions
./scripts/sync-secrets-to-github.sh- Local Development: Use
op runorop injectfor seamless secret loading - GitHub Actions: Automatic integration with 1Password service accounts
- Team Deployment: Shared vaults with role-based access
- Secret Rotation: Automated token rotation and propagation
.env.1password- 1Password secret references templatescripts/setup-1password.sh- Initial setup and vault creationscripts/validate-secrets.sh- Comprehensive secret validationscripts/sync-secrets-to-github.sh- GitHub secrets syncdocs/1PASSWORD_SETUP.md- Complete setup documentation
See 1Password Setup Guide for detailed instructions.
- Static Asset Caching: 1-year cache for CSS/JS/images
- HTML Revalidation: Immediate content updates
- Search Index Caching: 1-hour cache for Pagefind
- Edge Computing: Worker functions run at 200+ locations
- HTTPS Everywhere: Automatic SSL/TLS certificates
- Security Headers: CSP, HSTS, XSS protection
- Content Validation: Input sanitization and validation
- DDoS Protection: Built-in Cloudflare protection
- Live Previews: Automatic PR deployments
- Fast Deployments: Typically complete in under 2 minutes
- Rollback Support: Easy deployment rollbacks
- Comprehensive Monitoring: Health checks and performance metrics
GET /api/healthReturns deployment status and version information.
GET /api/search/suggestions?q=queryReturns search suggestions based on the indexed content.
POST /api/analytics/event
Content-Type: application/json
{
"event": "page_view",
"page": "/getting-started",
"timestamp": "2024-09-06T12:00:00Z"
}POST /api/feedback
Content-Type: application/json
{
"message": "Great documentation!",
"page": "/introduction",
"rating": 5
}# Check Rust installation
cargo --version
rustc --version
# Clean and rebuild
cargo clean
cargo build --release# Verify environment variables
echo $CLOUDFLARE_API_TOKEN
echo $CLOUDFLARE_ACCOUNT_ID
# Check Wrangler authentication
wrangler whoami
# Manual deployment for debugging
wrangler pages deploy dist --project-name=md-book# Check deployment status
wrangler pages deployment list --project-name=md-book
# Test API endpoints
curl -s https://md-book.pages.dev/api/health
# Run monitoring script
./scripts/monitor.sh production# Test local build
cargo run -- -i test_input -o dist
# Validate worker locally
cd worker && wrangler dev
# Check DNS resolution
nslookup md-book.pages.dev
# Test SSL certificate
openssl s_client -servername md-book.pages.dev -connect md-book.pages.dev:443Expected performance metrics:
- Page Load Time: < 1.5s (globally)
- First Contentful Paint: < 0.8s
- API Response Time: < 100ms (from edge)
- Build Time: < 2 minutes (full deployment)
- GitHub Actions deployment status
- Cloudflare analytics dashboard
- Worker execution metrics
- Pages performance insights
- Health check endpoints
- Performance monitoring script
- Error rate tracking
- User feedback collection
Add to wrangler.toml:
[pages.custom_domains]
production = "docs.yourdomain.com"
staging = "staging-docs.yourdomain.com"Create new workers for specialized functionality:
mkdir additional-worker
cd additional-worker
wrangler initUse environment variables in wrangler.toml:
[env.production.vars]
API_URL = "https://api.yourdomain.com"
[env.staging.vars]
API_URL = "https://staging-api.yourdomain.com"MD-Book can also be deployed to Netlify, which offers a simple drag-and-drop deployment option and Git-based continuous deployment.
-
Build your site locally:
# Build with default input/output cargo run -- -i docs -o dist # Or use custom directories cargo run -- -i your-content -o build
-
Deploy to Netlify:
- Go to Netlify Drop
- Drag your
dist(orbuild) folder to the deploy area - Your site will be live instantly with a random URL
- Optionally set a custom subdomain
-
Connect your repository:
- Go to Netlify
- Click "Add new site" → "Import an existing project"
- Connect your Git provider and select your repository
-
Configure build settings:
# Build command cargo run -- -i docs -o dist # Publish directory dist # Environment variables (optional) RUST_VERSION=1.70.0
# Install Netlify CLI
npm install -g netlify-cli
# Login to Netlify
netlify login
# Build your site
cargo run -- -i docs -o dist
# Deploy to draft URL
netlify deploy --dir=dist
# Deploy to production
netlify deploy --prod --dir=distCreate netlify.toml in your project root:
[build]
command = "cargo run -- -i docs -o dist"
publish = "dist"
[build.environment]
RUST_VERSION = "1.70.0"
# Redirect rules for SPA-like behavior
[[redirects]]
from = "/*"
to = "/404.html"
status = 404
# Headers for better caching
[[headers]]
for = "/css/*"
[headers.values]
Cache-Control = "public, max-age=31536000"
[[headers]]
for = "/js/*"
[headers.values]
Cache-Control = "public, max-age=31536000"
[[headers]]
for = "*.html"
[headers.values]
Cache-Control = "public, max-age=0, must-revalidate"
# Enable Netlify Functions (optional)
[functions]
directory = "netlify/functions"Create .github/workflows/netlify-deploy.yml:
name: Deploy to Netlify
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.70.0
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build site
run: |
cargo run -- -i docs -o dist
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v3.0
with:
publish-dir: './dist'
production-branch: main
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: "Deploy from GitHub Actions"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}Add contact forms to your documentation:
<!-- In your markdown or template -->
<form name="feedback" method="POST" data-netlify="true">
<p>
<label>Name: <input type="text" name="name" required /></label>
</p>
<p>
<label>Email: <input type="email" name="email" required /></label>
</p>
<p>
<label>Message: <textarea name="message" required></textarea></label>
</p>
<p>
<button type="submit">Send Feedback</button>
</p>
</form>- Every pull request gets a preview URL
- Perfect for reviewing documentation changes
- Automatic cleanup when PR is merged/closed
# In netlify.toml
[build]
command = "cargo run -- -i docs -o dist"
publish = "dist"
# Custom domain configuration
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"| Feature | Netlify | Cloudflare Pages |
|---|---|---|
| Deployment | Git-based, CLI, Drag & Drop | Git-based, CLI, API |
| Build Time | 15min free tier | Unlimited |
| Bandwidth | 100GB/month free | Unlimited |
| Forms | Built-in form handling | Requires Workers |
| Functions | Netlify Functions | Cloudflare Workers |
| CDN | Global CDN | Global CDN (faster) |
| Custom Headers | Via netlify.toml | Via _headers file |
| Redirects | Built-in | Built-in |
| Branch Previews | ✅ | ✅ |
| Custom Domains | Free SSL | Free SSL |
| Analytics | Paid add-on | Built-in |
If you want to migrate from Cloudflare to Netlify:
-
Export your build:
# Build locally cargo run -- -i docs -o dist -
Create netlify.toml:
[build] command = "cargo run -- -i docs -o dist" publish = "dist"
-
Set up redirects:
# Convert Cloudflare _redirects to netlify.toml [[redirects]] from = "/old-path/*" to = "/new-path/:splat" status = 301
-
Deploy:
netlify init netlify deploy --prod
Vercel offers zero-configuration deployments with automatic HTTPS and global CDN.
# Install Vercel CLI
npm install -g vercel
# Build your site
cargo run -- -i docs -o dist
# Deploy to Vercel
vercel --prod
# Or deploy with custom configuration
vercel deploy --prod --name md-book-
Connect repository:
- Go to Vercel Dashboard
- Click "Add New" → "Project"
- Import your Git repository
-
Configure build:
- Framework Preset: Other
- Build Command:
cargo run -- -i docs -o dist - Output Directory:
dist - Install Command: Leave empty (Rust pre-installed)
-
Deploy:
- Click "Deploy"
- Your site will be live in minutes
# Build locally
cargo run -- -i docs -o dist
# Deploy with Vercel CLI
cd dist && vercel --prodCreate vercel.json in your project root:
{
"version": 2,
"name": "md-book",
"builds": [
{
"src": "package.json",
"use": "@vercel/static-build",
"config": {
"distDir": "dist"
}
}
],
"buildCommand": "cargo run -- -i docs -o dist",
"devCommand": "cargo run -- -i docs -o dist --serve",
"installCommand": "echo 'Rust is pre-installed'",
"outputDirectory": "dist",
"routes": [
{
"src": "/(.*)",
"dest": "/$1",
"status": 200
}
],
"headers": [
{
"source": "/css/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
},
{
"source": "/js/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
},
{
"source": "/(.*).html",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=0, must-revalidate"
}
]
},
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
]
}
],
"rewrites": [
{
"source": "/:path*",
"destination": "/:path*"
}
]
}Create .github/workflows/vercel-deploy.yml:
name: Deploy to Vercel
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.70.0
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build site
run: cargo run -- -i docs -o dist
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
working-directory: ./distAdd to GitHub repository secrets:
VERCEL_TOKEN- Get from Vercel Dashboard → Settings → TokensVERCEL_ORG_ID- Found in Vercel project settingsVERCEL_PROJECT_ID- Found in Vercel project settings
GitHub Pages offers free hosting for public repositories with custom domain support.
Create .github/workflows/github-pages.yml:
name: Deploy to GitHub Pages
on:
push:
branches: [main, master]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.70.0
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build site
run: cargo run -- -i docs -o _site
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: '_site'
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4# Build your site
cargo run -- -i docs -o dist
# Create gh-pages branch
git checkout --orphan gh-pages
git rm -rf .
cp -r dist/* .
git add .
git commit -m "Deploy to GitHub Pages"
git push origin gh-pages --force
# Switch back to main
git checkout main-
Enable GitHub Pages:
- Go to repository Settings → Pages
- Source: "GitHub Actions" (for workflow) or "Deploy from branch" (for manual)
- Branch:
gh-pagesif using manual method
-
Custom Domain (Optional):
- Add
CNAMEfile to output directory:
echo "docs.yourdomain.com" > dist/CNAME
- Add
-
Base URL Configuration:
- For project pages (username.github.io/repo-name), update links to use base path
- Modify templates to include base path in asset URLs
- Free SSL/TLS certificates for custom domains
- Jekyll-free deployment (disable Jekyll with
.nojekyllfile) - CDN distribution via GitHub's infrastructure
- Version control built-in
- Branch-based deployment strategies
AWS Amplify provides fully managed hosting with AWS service integration.
-
Connect repository:
- Go to AWS Amplify Console
- Click "New app" → "Host web app"
- Connect your Git provider
-
Configure build:
version: 1 frontend: phases: preBuild: commands: - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - source $HOME/.cargo/env build: commands: - cargo run -- -i docs -o dist artifacts: baseDirectory: dist files: - '**/*' cache: paths: - target/**/* - ~/.cargo/**/*
-
Deploy:
- Review settings
- Click "Save and deploy"
# Install Amplify CLI
npm install -g @aws-amplify/cli
# Configure Amplify
amplify configure
# Initialize project
amplify init
# Add hosting
amplify add hosting
# Build and deploy
cargo run -- -i docs -o dist
amplify publishCreate amplify.yml:
version: 1
frontend:
phases:
preBuild:
commands:
# Install Rust
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
- source $HOME/.cargo/env
- rustc --version
build:
commands:
- cargo build --release
- cargo run --release -- -i docs -o dist
artifacts:
baseDirectory: dist
files:
- '**/*'
cache:
paths:
- target/**/*
- ~/.cargo/**/*- Custom domains with free SSL certificates
- Branch deployments for staging/production
- Environment variables management
- Serverless backend integration (Lambda, DynamoDB)
- Authentication via Amazon Cognito
- CI/CD built-in
- Performance monitoring and analytics
Render offers simple deployments with free SSL and automatic scaling.
-
Create Web Service:
- Go to Render Dashboard
- Click "New +" → "Static Site"
- Connect your repository
-
Configure:
- Build Command:
cargo run -- -i docs -o dist - Publish Directory:
dist - Environment: Select "Rust"
- Build Command:
-
Deploy:
- Click "Create Static Site"
- Automatic deployments on push
Create render.yaml in repository root:
services:
- type: web
name: md-book
env: static
buildCommand: cargo run -- -i docs -o dist
staticPublishPath: dist
headers:
- path: /*
name: X-Frame-Options
value: DENY
- path: /*
name: X-Content-Type-Options
value: nosniff
- path: /css/*
name: Cache-Control
value: public, max-age=31536000, immutable
- path: /js/*
name: Cache-Control
value: public, max-age=31536000, immutable
routes:
- type: rewrite
source: /*
destination: /index.html- Free SSL certificates for custom domains
- DDoS protection built-in
- Auto-deploy from Git
- Preview environments for pull requests
- Custom headers and redirects
- Zero-downtime deploys
Railway provides simple deployments with automatic HTTPS and preview environments.
# Install Railway CLI
npm install -g @railway/cli
# Login
railway login
# Initialize project
railway init
# Link to project (or create new)
railway link
# Deploy
cargo run -- -i docs -o dist
railway up-
Create Project:
- Go to Railway Dashboard
- Click "New Project" → "Deploy from GitHub repo"
- Select your repository
-
Configure:
- Railway auto-detects Rust projects
- Set build command:
cargo build --release && cargo run --release -- -i docs -o dist - Set start command: Static site serving
-
Deploy:
- Automatic deployment begins
- Get deployment URL
Create railway.toml:
[build]
builder = "NIXPACKS"
buildCommand = "cargo build --release"
[deploy]
startCommand = "cargo run --release -- -i docs -o dist --serve --port $PORT"
healthcheckPath = "/"
healthcheckTimeout = 100
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10Or use Procfile:
web: cargo run --release -- -i docs -o dist --serve --port $PORT
- Automatic HTTPS for all deployments
- Preview environments for branches and PRs
- Environment variables management
- Database integration (PostgreSQL, MySQL, Redis)
- Metrics and logging
- Custom domains with SSL
Fly.io provides edge deployment with global distribution using containers.
# Install flyctl
curl -L https://fly.io/install.sh | sh
# Login
flyctl auth login
# Launch app (creates fly.toml)
flyctl launch
# Deploy
flyctl deployCreate fly.toml:
app = "md-book"
primary_region = "iad"
[build]
[build.args]
RUST_VERSION = "1.70.0"
[env]
PORT = "8080"
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
[[http_service.checks]]
grace_period = "10s"
interval = "30s"
method = "GET"
timeout = "5s"
path = "/"Create Dockerfile:
# Build stage
FROM rust:1.70 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
# Runtime stage
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /app/target/release/md-book /usr/local/bin/md-book
COPY --from=builder /app/docs ./docs
COPY --from=builder /app/src/templates ./templates
# Build the site
RUN md-book -i docs -o dist
# Serve static files
EXPOSE 8080
CMD ["md-book", "-i", "docs", "-o", "dist", "--serve", "--port", "8080"]- Global edge network - Deploy to multiple regions
- Auto-scaling based on demand
- Zero-downtime deploys
- Built-in SSL/TLS
- Private networking between services
- Volume storage for persistent data
- Custom domains with automatic certificates
DigitalOcean App Platform offers simple pricing and managed infrastructure.
-
Create App:
- Go to DigitalOcean App Platform
- Click "Create App"
- Connect your repository
-
Configure:
- Type: Static Site
- Build Command:
cargo run -- -i docs -o dist - Output Directory:
dist - Environment: Rust
-
Deploy:
- Review plan ($0 for static sites)
- Click "Launch Your App"
Create .do/app.yaml:
name: md-book
region: nyc
static_sites:
- name: web
github:
repo: yourusername/md-book
branch: main
deploy_on_push: true
build_command: cargo run -- -i docs -o dist
output_dir: dist
routes:
- path: /
environment_slug: rust
envs:
- key: RUST_VERSION
value: "1.70.0"
cors:
allow_origins:
- prefix: https://
allow_methods:
- GET
- OPTIONS
- POST
allow_headers:
- Content-Type- Free tier for static sites
- Automatic SSL certificates
- CDN included
- Auto-deploy from Git
- Preview deployments for PRs
- Simple pricing - No surprises
- Managed databases integration
- Easy monitoring and alerts
| Feature | Cloudflare | Netlify | Vercel | GitHub Pages | AWS Amplify | Render | Railway | Fly.io | DigitalOcean |
|---|---|---|---|---|---|---|---|---|---|
| Free Tier | Unlimited | 100GB | 100GB | Unlimited | Free (pay-as-go) | Free | $5 credit | Free tier | Free static |
| Build Minutes | Unlimited | 300/mo | 6000/mo | Unlimited | 1000/mo | 500/mo | Limited | N/A | 100/mo |
| Bandwidth | Unlimited | 100GB | 100GB | 100GB/mo | 15GB | 100GB | 100GB | Limited | 100GB |
| Custom Domain | ✅ Free SSL | ✅ Free SSL | ✅ Free SSL | ✅ Free SSL | ✅ Free SSL | ✅ Free SSL | ✅ Free SSL | ✅ Free SSL | ✅ Free SSL |
| Auto Deploy | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Preview Deploys | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Edge Functions | Workers | Functions | Functions | ❌ | Lambda | ❌ | Limited | ✅ | Functions |
| Global CDN | ✅ 200+ | ✅ | ✅ | ✅ | ✅ | ✅ | Limited | ✅ Multi-region | ✅ |
| Analytics | ✅ Built-in | Paid | Paid | Limited | ✅ | Basic | Basic | Basic | Basic |
| DDoS Protection | ✅ Enterprise | Basic | ✅ | ✅ | ✅ AWS Shield | ✅ | Limited | ✅ | ✅ |
| Build Cache | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Deployment Speed | Very Fast | Fast | Fast | Medium | Fast | Fast | Fast | Medium | Fast |
| Ease of Setup | Medium | Easy | Very Easy | Easy | Medium | Easy | Very Easy | Medium | Easy |
- Unlimited bandwidth and builds
- Advanced edge computing with Workers
- Best-in-class DDoS protection
- Global CDN with 200+ locations
- Simple drag-and-drop deployment
- Built-in form handling
- Generous free tier
- Easy custom domains
- Zero-config deployment
- Excellent Next.js integration (future)
- Edge functions
- Great developer experience
- Simple hosting for open source
- Free for public repositories
- Direct GitHub integration
- Jekyll support (if needed)
- AWS ecosystem integration
- Serverless backend (Lambda, DynamoDB)
- Enterprise features
- Advanced authentication
- Simple pricing
- Free SSL and DDoS protection
- PostgreSQL/Redis included in free tier
- Preview environments
- Simplest deployment experience
- Database integration
- Preview environments
- Hobby projects
- Global edge deployment
- Container-based deployment
- Multi-region by default
- Low-latency worldwide
- Simple pricing
- Managed infrastructure
- Free static site hosting
- Great documentation
This deployment system is designed for high-performance, scalable documentation hosting with minimal maintenance overhead.