Skip to content

Fly.io

Fly.io deploys containerized applications to edge servers worldwide. For static sites, use a multi-stage Dockerfile that builds your site, runs pageflare, and serves the optimized output with a lightweight web server.

Add pageflare to the build stage of your Dockerfile. The optimized files are then copied to a minimal serving image (nginx or Caddy).

Dockerfile
# Build stage
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build && npx @pageflare/cli dist/ --in-place --no-progress
# Serve stage
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
fly.toml
app = "my-site"
primary_region = "iad"
[build]
[http_service]
internal_port = 8080
force_https = true

Pass your license key as a build argument:

Dockerfile
FROM node:22-slim AS build
ARG PAGEFLARE_LICENSE
ENV PAGEFLARE_LICENSE=$PAGEFLARE_LICENSE
# ... rest of build

Set the secret in Fly.io:

Terminal window
fly secrets set PAGEFLARE_LICENSE=your-license-key

And pass it during deploy:

Terminal window
fly deploy --build-arg PAGEFLARE_LICENSE=your-license-key

Check the deploy logs for the pageflare summary:

Done 145.2 KB saved (38.1%) 1.2s
Files 42 total, 38 optimized, 4 unchanged, 0 errors
FrameworkOutput directory
Astrodist/
Next.js static exportout/
Hugopublic/
Vitedist/
Eleventy_site/

Update the COPY --from=build path and the pageflare input directory to match your framework.

Build fails with “command not found” Make sure @pageflare/cli is in your devDependencies, or install it globally in the Dockerfile with RUN npm install -g @pageflare/cli.

Large Docker image The multi-stage build ensures only the optimized static files end up in the final image. Make sure you’re copying from the build stage, not including node_modules in the final image.