Skip to main content

Deploy Zig Apps

Zig is an new low-level programming language popularly used for speed similar to Zig and C++. Zig is served as an compile language, which means you need to compile your code before running it.

There is no default zig compiler at system level. You have to install it first through deployment scripts.


Serving Zig apps requires to be run via GLS, that's mean you have to listen from given PORT env/args.


The deployment script below installs the latest zig compiler and compiles main.zig and serves that main binary.
source: clear
- zig
root: public_html/public
enabled: "on"
app_start_command: env PORT=$PORT ./main
- filename: main.zig
content: |
const std = @import("std");
const debug = std.debug;
const getenv = std.os.getenv;
const Server = std.http.Server;
const parseInt = std.fmt.parseInt;
const allocPrintZ = std.fmt.allocPrintZ;
const parseIp =;

const body =
\\<!DOCTYPE html>
\\ <title>Zig App</title>
\\ <link rel="stylesheet" href="//">
\\<body class="p-5 text-center">
\\ <p><img src="//"
\\ class="img-fluid rounded-circle"></p>
\\ <h1 class="mb-3">Hello, world!</h1>
\\ <p>Serving from Zig version {s}</p>
\\ <p class="text-muted">DOM Cloud</p>

pub fn getVersion(allocator: std.mem.Allocator) []const u8 {
const zV = std.ChildProcess.exec(.{
.allocator = allocator,
.argv = &[_][]const u8{ "zig", "version" },
}) catch unreachable;
return zV.stdout;

pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
var server = Server.init(allocator, .{ .reuse_address = true });
const port = try parseInt(u16, getenv("PORT") orelse "3000", 10);
try server.listen(try parseIp("", port));
debug.print("Listening to{d}\n", .{port});
const version = getVersion(allocator);
const respBody = try allocPrintZ(allocator, body, .{version});

defer server.deinit();
defer debug.assert(gpa.deinit() == .ok);

while (true) {
var resp = try server.accept(.{ .allocator = allocator });
defer resp.deinit();
while (resp.reset() != .closing) {
try resp.wait();

resp.transfer_encoding = .{ .content_length = respBody.len };
try resp.headers.append("Content-Type", "text/http");
try resp.writeAll(respBody);
try resp.finish();
- zig build-exe main.zig

Existing Zig projects

For existing zig apps, use this deployment script. This project must have a build.zig initialized. You may need to change the start path if your app is not compiled to ./zig-out/bin/app.
- zig latest
root: public_html/public
enabled: "on"
app_start_command: env PORT=$PORT ./zig-out/bin/app
- zig build

It's possible to run the app via zig build run. This eliminates the need to compile the code into a binary, although startup time may be a little bit slower.
- zig latest
root: public_html/public
enabled: "on"
app_start_command: env PORT=$PORT zig build run
- zig build

Use other Zig versions

To switch zig version use feature syntax like zig latest, zig 0.11.0, etc. Check your current zig version using zig version in SSH.

- zig 0.11.0

Zig install scripts is powered by webi.

App Management

Your app do not restarted automatically after file changes. To restart, run restart via SSH.

Environment variables can be set either using NGINX's env_var_list or ~/.bashrc. Usually your language framework also reads .env files.

See NGINX and App Daemon for more information about NGINX and App managements including restarting, environment variables, and other global limitations.

App Logging

You can see app log from Check -> Check Process Logs tab. Only startup problems displayed in the browser.

Please use a proper logging mechanism such as the standard logging library then write it to a log file, or any other solution that suits you.

NGINX errors and traffic logs can be examined via Webmin or Check -> Check Process Logs tab.