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.
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
.
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.
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.