Production Deployment
Chuks compiles to a single static binary with no runtime dependencies. This makes deployment straightforward: build once, copy to your server, and run.
Build for Production
Section titled “Build for Production”Every chuks build produces a production-ready binary, stripped, optimized, and fully static by default.
chuks buildWhen run inside a project directory (with chuks.json), this reads your entry point and project name automatically:
✓ Successfully compiled src/main.chuks → build/my-app (1.3s)Build Flags
Section titled “Build Flags”| Flag | Short | Description |
|---|---|---|
--output <path> | -o | Custom output binary path |
--os <os> | Target OS: linux, darwin, windows | |
--arch <arch> | Target architecture: amd64, arm64 | |
--version <ver> | Embed a version string in the binary |
Custom Output Path
Section titled “Custom Output Path”chuks build -o myappVersion Embedding
Section titled “Version Embedding”The version from chuks.json is automatically embedded into the binary. Override it with --version:
chuks build --version 2.1.0This is useful in CI pipelines where the version comes from a Git tag:
chuks build --version $(git describe --tags)Cross-Compilation
Section titled “Cross-Compilation”Build for a different platform without any extra tooling:
# Build for Linux server from your Macchuks build --os linux --arch amd64
# Build for Windowschuks build --os windows --arch amd64Output files are automatically named with the platform suffix:
build/my-app-linux-amd64build/my-app-windows-amd64.exeMulti-Target Build
Section titled “Multi-Target Build”Build for multiple platforms in a single command:
chuks build --os linux --os darwin --os windows --arch amd64✓ Successfully compiled src/main.chuks → build/my-app-linux-amd64 (1.4s)✓ Successfully compiled src/main.chuks → build/my-app-darwin-amd64 (1.2s)✓ Successfully compiled src/main.chuks → build/my-app-windows-amd64.exe (1.5s)Supported Targets
Section titled “Supported Targets”| OS | Architectures |
|---|---|
linux | amd64, arm64 |
darwin (macOS) | amd64, arm64 |
windows | amd64, arm64 |
Output Naming
Section titled “Output Naming”The binary name is determined by this priority:
-oflag — use exactly what’s specifiedchuks.jsonname —build/<name>(e.g.build/userservice)- Source filename —
build/<filename>without the.chuksextension
Cross-compiled binaries get a -<os>-<arch> suffix. Windows binaries always end in .exe.
Deploying to a Server
Section titled “Deploying to a Server”Direct Copy
Section titled “Direct Copy”The simplest deployment: build for Linux and copy the binary to your server.
# Build locallychuks build --os linux --arch amd64
# Copy to serverscp build/my-app-linux-amd64 user@server:/opt/my-app/my-app
# SSH in and runssh user@serverchmod +x /opt/my-app/my-app./opt/my-app/my-appThe binary has zero dependencies — no runtime, no shared libraries, no package manager installs needed on the server.
Using systemd (Linux)
Section titled “Using systemd (Linux)”For production Linux servers, systemd keeps your app running across reboots and restarts it if it crashes.
Create a service file at /etc/systemd/system/my-app.service:
[Unit]Description=My Chuks ApplicationAfter=network.target
[Service]Type=simpleUser=appuserWorkingDirectory=/opt/my-appExecStart=/opt/my-app/my-appRestart=on-failureRestartSec=5StandardOutput=journalStandardError=journal
# Environment variablesEnvironment=PORT=3000Environment=DB_HOST=localhost
# Graceful shutdown (Chuks handles SIGTERM)KillSignal=SIGTERMTimeoutStopSec=10
[Install]WantedBy=multi-user.targetManage the service:
# Startsudo systemctl start my-app
# Enable auto-start on bootsudo systemctl enable my-app
# View logsjournalctl -u my-app -f
# Restart after re-deployingsudo systemctl restart my-appChuks applications handle SIGTERM gracefully — in-flight HTTP requests drain, database connections close, and spawned tasks complete before shutdown.
Using PM2
Section titled “Using PM2”PM2 is a popular process manager, commonly associated with Node.js, but it works with any binary.
# Install PM2 (if not already installed)npm install -g pm2
# Start your Chuks apppm2 start ./build/my-app --name my-app
# View logspm2 logs my-app
# Monitorpm2 monit
# Restartpm2 restart my-app
# Auto-start on bootpm2 startuppm2 saveWith an ecosystem file (ecosystem.config.js):
module.exports = { apps: [ { name: "my-app", script: "./build/my-app", instances: 1, env: { PORT: 3000, DB_HOST: "localhost", }, env_production: { PORT: 8080, DB_HOST: "db.production.internal", }, }, ],};pm2 start ecosystem.config.js --env productionUsing Supervisor
Section titled “Using Supervisor”Supervisor is another process manager, common on older Linux servers.
Create /etc/supervisor/conf.d/my-app.conf:
[program:my-app]command=/opt/my-app/my-appdirectory=/opt/my-appuser=appuserautostart=trueautorestart=truestderr_logfile=/var/log/my-app/error.logstdout_logfile=/var/log/my-app/output.logenvironment=PORT="3000",DB_HOST="localhost"stopsignal=TERMstopwaitsecs=10sudo supervisorctl rereadsudo supervisorctl updatesudo supervisorctl start my-appDocker
Section titled “Docker”Since Chuks compiles to a static binary, Docker images can be extremely small.
Create a Dockerfile
Section titled “Create a Dockerfile”# Build stageFROM ubuntu:22.04 AS builderRUN apt-get update && apt-get install -y curlRUN curl -fsSL https://raw.githubusercontent.com/chuks-programming-language/releases/main/install.sh | bashWORKDIR /appCOPY . .RUN chuks build --os linux --arch amd64
# Runtime stage — minimal imageFROM gcr.io/distroless/static:nonrootCOPY --from=builder /app/build/ /EXPOSE 3000ENTRYPOINT ["/my-app-linux-amd64"]The resulting image is typically 5–15 MB — just the binary and nothing else. No OS, no shell, no package manager.
Alternative: Build Locally, Copy Binary
Section titled “Alternative: Build Locally, Copy Binary”If you prefer building on your machine:
FROM gcr.io/distroless/static:nonrootCOPY build/my-app-linux-amd64 /appEXPOSE 3000ENTRYPOINT ["/app"]# Build for Linux firstchuks build --os linux --arch amd64
# Build Docker imagedocker build -t my-app .
# Rundocker run -p 3000:3000 my-appDocker Compose
Section titled “Docker Compose”services: app: build: . ports: - "3000:3000" environment: - PORT=3000 - DB_HOST=db depends_on: - db restart: unless-stopped
db: image: postgres:16 environment: POSTGRES_DB: myapp POSTGRES_USER: myuser POSTGRES_PASSWORD: mypassword volumes: - pgdata:/var/lib/postgresql/data
volumes: pgdata:GitHub Actions
Section titled “GitHub Actions”name: Build & Deploy
on: push: branches: [main]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Install Chuks run: curl -fsSL https://raw.githubusercontent.com/chuks-programming-language/releases/main/install.sh | bash
- name: Build run: chuks build --os linux --arch amd64 --version ${{ github.sha }}
- name: Upload artifact uses: actions/upload-artifact@v4 with: name: my-app path: build/GitLab CI
Section titled “GitLab CI”build: stage: build image: ubuntu:22.04 script: - curl -fsSL https://raw.githubusercontent.com/chuks-programming-language/releases/main/install.sh | bash - chuks build --os linux --arch amd64 --version $CI_COMMIT_TAG artifacts: paths: - build/CPU Core Limiting
Section titled “CPU Core Limiting”By default, Chuks uses all available CPU cores. On shared servers where Chuks runs alongside other services, you can limit how many cores Chuks uses.
VM Mode (chuks run)
Section titled “VM Mode (chuks run)”Use the --cpus flag:
chuks run --cpus 4 src/main.chukschuks run --cpus=2 src/main.chuksAOT-Compiled Binaries
Section titled “AOT-Compiled Binaries”Use the CHUKS_CPUS environment variable:
CHUKS_CPUS=4 ./build/my-appThis works with all deployment methods:
systemd:
[Service]Environment=CHUKS_CPUS=4PM2 ecosystem:
env: { CHUKS_CPUS: 4,}Docker:
environment: - CHUKS_CPUS=4Priority: --cpus flag > CHUKS_CPUS env var > default (all cores).
Environment Configuration
Section titled “Environment Configuration”Use the dotenv standard library to load environment variables from .env files in development, and real environment variables in production:
import { dotenv } from "std/dotenv"import { createServer } from "std/http"
function main() { dotenv.load() var port = dotenv.get("PORT","3000") var dbHost = dotenv.get("DB_HOST","localhost")
var server = createServer() server.listen(int(port))}In production, set environment variables through your deployment method:
| Method | How to set |
|---|---|
| systemd | Environment=KEY=value in service file |
| PM2 | env block in ecosystem file |
| Docker | -e KEY=value or environment: in compose |
| Cloud | Platform environment variable settings |
Health Checks
Section titled “Health Checks”Production deployments should expose a health endpoint for load balancers and orchestrators:
import { createServer, Request, Response } from "std/http"
function main() { var server = createServer()
server.get("/health", function(req: Request, res: Response) { res.json('{"status": "ok"}') })
// ... your other routes
server.listen(3000)}Use this endpoint in your deployment configuration:
Docker Compose:
services: app: healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"] interval: 30s timeout: 5s retries: 3PM2:
pm2 start ./build/my-app --name my-app --health-check-url http://localhost:3000/healthGraceful Shutdown
Section titled “Graceful Shutdown”Chuks applications handle shutdown signals (SIGTERM, SIGINT) automatically:
- HTTP server stops accepting new connections
- In-flight requests are drained (up to 5 seconds)
- Spawned tasks run to completion
- Database connections are closed
- Shutdown hooks are executed in reverse order
This means zero-downtime deployments work out of the box with rolling restarts in Docker, Kubernetes, systemd, or PM2.
Summary
Section titled “Summary”| What | Command |
|---|---|
| Build for current platform | chuks build |
| Build for Linux server | chuks build --os linux --arch amd64 |
| Build for multiple platforms | chuks build --os linux --os darwin --os windows |
| Custom output name | chuks build -o myapp |
| Embed version | chuks build --version 1.0.0 |
| Run with systemd | Create service file, systemctl start |
| Run with PM2 | pm2 start ./build/my-app |
| Run with Docker | Multi-stage Dockerfile, 5–15 MB image |
| Limit CPU cores (VM) | chuks run --cpus 4 src/main.chuks |
| Limit CPU cores (AOT) | CHUKS_CPUS=4 ./build/my-app |