πŸ“¦

It's a Binary.

Not a Next.js project. Not a collection of 50,000 node_modules. No complex runtime required.

Download. Run. Done.

Scroll down for the "boring" technical details

Guide / 18 β€” Production

Deployment & Docker

From your local kitchen to the cloud. Stew applications are compiled into a single Go binary with no dependencies, making them perfect for containerization.

Dependency: TinyGo

To compile the client-side (Wasm) parts of your application, you must have TinyGo installed on your build machine or in your CI/CD container.

wget https://github.com/tinygo-org/tinygo/releases/download/v0.40.1/tinygo_0.40.1_amd64.deb
sudo dpkg -i tinygo_0.40.1_amd64.deb

The Build Process

Before deploying, you must execute the sequential build command. This ensures the router is up-to-date and all Stew components are compiled before creating the final binary.

stew run build

This command sequentially runs: stew compile β†’ stew generate β†’ go build.

Multi-Stage Dockerfile

The most efficient way to deploy is a multi-stage Docker build. We use a "heavy" image for compilation and a lightweight image (alpine or scratch) for execution.

# Stage 1: Build
FROM golang:1.22-alpine AS builder

# Install Stew
RUN go install github.com/ZiplEix/stew@latest

WORKDIR /app
COPY . .

# Compile the project
RUN stew run build

# Stage 2: Run
FROM alpine:latest
WORKDIR /root/
# Copy the generated binary (adjust path if needed)
COPY --from=builder /app/bin/app .
# Copy static and Wasm assets
COPY --from=builder /app/static ./static

EXPOSE 8080
CMD ["./app"]

Environment Variables

In production, Stew ignores .env.local files and prefers system environment variables. Ensure your host (Fly.io, Railway, DigitalOcean) has the following variables set:

  • PORT: The listening port (defaults to 8080).
  • STEW_DEV: Must be set to false to disable Hot Morphing scripts.

πŸ“¦ Static Assets & Embed

To maintain your application as a single binary, we recommend using Go's embed package to include your static files (images, CSS, Wasm) directly in the executable.

// main.go
//go:embed static/*
var staticFS embed.FS

func main() {
    // ...
    fs := http.FileServer(http.FS(staticFS))
    mux.Handle("GET /static/", fs)
}