Skip to main content

Deploy Zig Apps

Zig installation is powered by webi. To install latest version with deployment script:

features:
- zig

Without this, zig won't be available since no globally installed Zig compiler available.

Install other version using zig latest, zig 0.13.0, etc. To uninstall use zig off. Check the current version using zig version from SSH.

Example

The deployment script below installs the latest zig compiler, compiles main.zig and runs the main binary serving HTTP from PORT envar.

https://github.com/domcloud/recipes/blob/master/zig.yml
source: clear
features:
- zig
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT ./main
commands:
- 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 = std.net.Address.parseIp;

const body =
\\<!DOCTYPE html>
\\<html>
\\<head>
\\ <title>Zig App</title>
\\ <link rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css">
\\</head>
\\<body class="p-5 text-center">
\\ <p><img src="//images.unsplash.com/photo-1465153690352-10c1b29577f8?fit=crop&w=200&h=200"
\\ 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>
\\</body>
\\</html>
;

pub fn getVersion(allocator: std.mem.Allocator) []const u8 {
const zV = std.ChildProcess.exec(.{
.allocator = allocator,
.argv = &[_][]const u8{ "zig", "version" },
}) catch unreachable;
defer allocator.free(zV.stderr);
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("127.0.0.1", port));
debug.print("Listening to 127.0.0.1:{d}\n", .{port});
const version = getVersion(allocator);
const respBody = try allocPrintZ(allocator, body, .{version});

defer allocator.free(respBody);
defer allocator.free(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.do();
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.

https://github.com/domcloud/recipes/blob/master/zig-binary.yml
features:
- zig latest
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT ./zig-out/bin/app
commands:
- 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.

https://github.com/domcloud/recipes/blob/master/zig-gls.yml
features:
- zig latest
nginx:
root: public_html/public
passenger:
enabled: "on"
app_start_command: env PORT=$PORT zig build run
commands:
- zig build

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.

You might want to 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.