Deploy Wyn Apps with Docker
Wyn compiles to a single static binary. That means your Docker images can be tiny — 5MB or less using a scratch base image. No runtime, no interpreter, no dependency layer.
Why Wyn + Docker Works Well
| Metric | Wyn | Python | Node.js | Go |
|---|---|---|---|---|
| Docker image size | ~5MB | ~150MB | ~180MB | ~15MB |
| Startup time | <1ms | ~500ms | ~200ms | ~5ms |
| Runtime dependencies | None | Python + pip packages | Node + npm packages | None |
| Files in image | 1 binary | Hundreds | Thousands | 1 binary |
Wyn produces a statically-linked binary with no external dependencies. The entire container is your binary plus a scratch base layer.
Basic Dockerfile
# Build stage
FROM ubuntu:22.04 AS build
RUN apt-get update && apt-get install -y curl gcc
RUN curl -fsSL https://wynlang.com/install.sh | sh
WORKDIR /app
COPY . .
RUN wyn build main.wyn --release --target linux-x86_64 -o server
# Runtime stage — scratch means empty base image
FROM scratch
COPY --from=build /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]Build and run:
docker build -t myapp .
docker run -p 8080:8080 myappThe final image contains exactly one file: your compiled binary.
Multi-Stage Build with SQLite
If your app uses SQLite, you need the SQLite shared library. Use alpine instead of scratch:
FROM ubuntu:22.04 AS build
RUN apt-get update && apt-get install -y curl gcc libsqlite3-dev
RUN curl -fsSL https://wynlang.com/install.sh | sh
WORKDIR /app
COPY . .
RUN wyn build main.wyn --release --target linux-x86_64 -o server
FROM alpine:3.19
RUN apk add --no-cache sqlite-libs
COPY --from=build /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]This adds ~8MB for Alpine + SQLite, bringing the total to ~13MB.
Docker Compose Example
version: "3.8"
services:
api:
build: .
ports:
- "8080:8080"
environment:
- DB_PATH=/data/app.db
volumes:
- app-data:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/health"]
interval: 30s
timeout: 5s
retries: 3
volumes:
app-data:Production Checklist
- Use
--release— produces optimized binaries (49KB hello world vs 425KB debug) - Use
scratchoralpine— don't ship Ubuntu in production - Set a non-root user if using Alpine:dockerfile
RUN adduser -D appuser USER appuser - Add a health check endpoint in your Wyn app:wyn
if path == "/health" { Http.respond(req, 200, "ok") } - Pin your base image versions —
alpine:3.19, notalpine:latest
Image Size Comparison
Real-world web API (HTTP server + JSON + routing):
| Stack | Image Size |
|---|---|
| Wyn (scratch) | 4.8MB |
| Wyn (alpine + SQLite) | 13MB |
| Go (scratch) | 12MB |
| Rust (scratch) | 8MB |
| Node.js (alpine) | 180MB |
| Python (slim) | 150MB |
Cross-Compilation for Docker
Build a Linux binary from macOS without Docker:
wyn build main.wyn --release --target linux-x86_64 -o serverThen copy the binary into a minimal Dockerfile:
FROM scratch
COPY server /server
EXPOSE 8080
ENTRYPOINT ["/server"]This skips the build stage entirely — useful for CI pipelines where you build the binary separately.
Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: wyn-api
spec:
replicas: 3
selector:
matchLabels:
app: wyn-api
template:
metadata:
labels:
app: wyn-api
spec:
containers:
- name: api
image: registry.example.com/wyn-api:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "16Mi"
cpu: "50m"
limits:
memory: "64Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 1
periodSeconds: 10Wyn's low memory footprint (1-2MB RSS for a hello world server) means you can run many replicas on minimal resources.
See Also
- Deploying —
wyn deployfor direct server deployment - Cross-Compilation — build for Linux, Windows, and macOS
- Build a Web Server — HTTP server tutorial
- GitHub Actions CI/CD — automate Docker builds in CI