The Mako Server is a ready-to-run Lua application server built on the Barracuda App Server C Library. It packages BAS, Lua, Lua Server Pages, SQLite support, TLS, WebSockets, and server-side APIs into a single executable for high-level operating systems such as Linux, Windows, macOS, QNX, and VxWorks.
This page explains how to use and configure the Mako Server runtime. For downloads, getting-started material, tutorials, and the broader product overview, see makoserver.net. For source-level build instructions, see Building the Mako Server with BAS. See Xedge if you need an RTOS-based Lua application environment.
If you are working with Embedded Linux, check out the Embedded Linux Web Interface Design Tutorial. It covers practical examples for controlling GPIOs and provides useful insights to streamline web interface development in embedded systems.
| Goal | Section |
|---|---|
| Use a precompiled server | Precompiled Mako Server Versions |
Understand mako.zip | Mako Server's resource file mako.zip |
Embed applications in mako.zip | Embedding applications in mako.zip |
| Use AI agents to build and debug Mako apps | AI-Assisted Development with LSP-Claw |
| Start the server and load applications | Command-Line Options |
| Configure the server | Configuration File (mako.conf) |
| Use the browser-based IDE | The Mako Server's Integrated Development Environment |
| Use Mako runtime APIs | Functions, IO interfaces, and Modules |
Most users should start with a precompiled Mako Server from makoserver.net. The site also provides tutorials, getting-started material, and ready-to-use examples. Build from BAS only when you need to customize the executable, add C modules, change compile-time options, or port Mako to a specific platform.
The precompiled versions include the following additional modules:
Optional embedded SharkTrust test identity.
A Mako executable can include generated tokengen proof code and its associated zone identity. See the Let's Encrypt configuration options and the shared ACME DNS module for more information.
🚫 Warning - Do Not Use the Included Identity in Production
The generated proof identity is intended only for testing SharkTrust features with the local.makoserver.net domain. A product deployment must run its own SharkTrust portal with a separately generated and protected zone identity.
The Mako Server's core runtime logic is implemented in Lua and stored in mako.zip. A normal deployment consists of two files: the Mako executable and mako.zip. If the executable cannot find the external mako.zip, it falls back to the embedded ZIP compiled into the executable. The embedded ZIP contains simplified fallback logic and should not be treated as a replacement for the full external resource file.
The mako.zip Developer Edition is the recommended Mako Server package for application development. It provides a ready-to-run development setup around the Mako executable and the mako.zip resource file, so you can start the server, load applications, and experiment without first building BAS or assembling the runtime files yourself.
The Mako Server can load applications from command-line arguments or from instructions in mako.conf. When distributing a finished product, however, it is often more convenient to package the applications directly inside mako.zip so the deployment remains self-contained.
To embed applications in mako.zip, create the following directory:
mako.zip/apps/
Each application must be placed in its own subdirectory. For example, an application named myapp should be installed as follows:
mako.zip/apps/myapp/
The embedded application loader discovers directories under apps/. Do not place myapp.zip directly in that directory. If an application is distributed as a ZIP file, unpack it so its contents are stored under apps/myapp/.
By default, the application's base URL path is derived from the directory name. In this example, the application is available under the URL path /myapp/.
You can override the default base path by creating a configuration file named .config in the application's root directory. This Lua-parsed configuration file supports the following settings:
return {
name = "basepath", -- Set to "" to install as a root application.
prio = 0, -- Application resource-reader priority.
startprio = 100 -- Startup order; lower values start first.
}
The name defaults to the application directory name, prio controls resource lookup when application directories compete for the same URL, and startprio controls application startup order.
The Mako Server Developer Edition demonstrates this packaging model. It embeds FuguHub, Xedge, and LSP-Claw as application directories under mako.zip/apps/, allowing them to start automatically with Mako Server.
All embedded applications are installed as LSP applications. If an application should be loaded for internal use only and should not be accessible through a URL, create a .preload script in the application's root directory that executes the following statement:
dir:unlink()
This removes the application's URL mapping while still allowing the application to be loaded and used internally.
To modify the Lua logic in mako.zip, run the Mako Server in developer mode. The following example sets the environment variable MAKO_ZIP to a directory containing a copy of the mako.zip content:
$ mkdir makozip $ cd makozip/ $ unzip ../mako.zip $ cd .. $ export MAKO_ZIP=makozip $ mako Mako Server. Version 3.0 BAS lib 4396. Build date: Jun 18 2019 Copyright (c) Real Time Logic. Mounting makozip Server listening on IPv6 port 9357 Server listening on IPv4 port 9357 Loading certificate MakoServer SharkSSL server listening on IPv6 port 9443 SharkSSL server listening on IPv4 port 9443
The output shows that the server mounts the directory makozip instead of mako.zip.
If you use AI agents for Mako Server development, consider using LSP-Claw. LSP-Claw is an MCP server that runs inside Mako Server or Xedge and gives the AI agent a controlled lab application where it can inspect files, create Lua and LSP applications, start or restart the lab, and read trace output instead of editing arbitrary local files.
The mako.zip Developer Edition is the fastest way to get started with LSP-Claw because it provides a ready-to-run Mako development environment for running and testing LSP-Claw. See the LSP-Claw GitHub repository for setup instructions, AI agent configuration examples, and starter prompts.
The Mako Server is easy to deploy because only two files are normally required: the mako executable and the mako.zip resource file. The server does not need to be installed and can run directly in a console window.
For a complete beginner's tutorial, see Getting Started with the Mako Server.
On Windows, the server can optionally be installed as a Windows service. On all other platforms, the server can optionally be installed as a daemon (background) process. See the following tutorials for details:
The Mako Server starts as a foreground process if no arguments are provided. You can request the server to list all commands and then exit as follows:
mako -?
You may specify the location of an optional configuration file.
Example:mako -c mytestdir/mako.conf
See the Configuration File documentation for more information on how to use the configuration file.
-d - Run in daemon mode by detaching from the console -s - Run in daemon mode without detaching from the console -u username - Username to run as
sudo mako -l::myapp.zip -u `whoami`
Note: The server will open alternate ports above 1024 if it is unable to open the default ports.
Instead of using this command, you can add the CAP_NET_BIND_SERVICE capability, which allows an executable to bind to ports below 1024 even when run as a non-root Linux user.
sudo setcap cap_net_bind_service=+ep /path/2/mako
-install - Installs the service -installauto - Installs the service for autostart -remove - Removes the service -start - Starts the service -stop - Stops the service -restart - Stops and starts the service -autostart - Changes the service to automatic start -manual - Changes the service to manual start -minimize - Minimize the console window -elevate - Request elevated privileges
The first eight commands are for installing and managing the server as a Windows service. For example, the following command installs the server as a service, enables auto-start, and starts the service:
mako -l::myapp.zip -installauto
On Windows, administrative privileges are required to install a service. The Mako Server will request elevated permissions if the process or command window from which the service is installed is not already elevated.
The two command line options -elevate and -minimize are designed for creating web-based dashboard-like applications for Windows when not running as a service. When using both options, use the command line sequence -elevate -minimize to leave the current command line window (if any) "as is" and to only minimize the new command window that opens when running in elevated mode.
This section provides a quick introduction to running the Mako Server as a Windows service. For a more detailed explanation, see the tutorial Installing the Mako Server as a Windows Service.
Use a Mako Server Configuration File when starting the Mako Server as a Windows service. The following example uses the directory c:\wwwapps as the base directory and the subdirectory mywww for storing the web application (HTML, LSP, etc.).
The configuration file "mymako.conf" must use absolute paths:
apps={
{ name="", path="/c/wwwapps/mywww"}
}
homeio="/c/wwwapps"
Initially, test the configuration file without installing the server as a service:
mako -c c:\wwwapps\mymako.conf
Make sure you can navigate to your 'mywww' app. When it works, install the server as a service as follows:
mako -c c:\wwwapps\mymako.conf -installauto
In the Barracuda App Server, an application is comparable to the 'www' directory used by other servers. Multiple web applications can be loaded simultaneously, and each application can be assigned a base URL. This URL serves as a unique identifier, helping to distinguish it from other loaded applications and prevent URL conflicts.
If two applications use the same name, the server uses each application's priority setting to determine which application takes precedence.
Applications are created by the Lua code in the Mako Server's .config script, using LSP-enabled Resource Reader instances. For more detailed information on this process, refer to the introduction to the virtual file system.
Applications are loaded with command-line options, the configuration file, or both.
Loading apps via the command line:
-l[name]:[priority]:path - Load one or multiple applications
The following example loads three applications:
mako -lmyapp:1:path/2/myapp -lmyapp:0:myapp.zip -l::/path/2/my-root-app
The two myapp applications have the same base URI, but the non-deployed application has a higher priority than the deployed application myapp.zip. Resources are first searched for in the non-deployed application and then in the deployed application if not found. The last application loaded is a non-deployed root application.
script - Execute the specified script and exit.
Description:
This option allows you to run the Mako Server in a special mode that closely resembles the behavior of the standard Lua interpreter. When you provide a script name as the only argument and without a preceding hyphen, the server will execute the specified script immediately upon starting.
During the execution of the script, the server operates as usual: it opens any configured ports and runs any necessary services. However, once the script completes its execution, the server shuts down completely, closing all ports and stopping all services.
Use Case:
This mode is useful for running initialization scripts, one-time setup tasks, or quick automated processes that require the extended Lua APIs provided by the Mako Server but do not need the server to continue running afterward.
Example Usage:
mako myscript.lua
In this example, the server loads and executes myscript.lua. After the script finishes, the server terminates automatically.
See also Using The Mako Server Instead of Bash For Scripting and XLua.
The configuration file lets you customize the server's initialization of the Barracuda App Server and perform other initialization tasks. You can also use the configuration file for loading applications and setting your own configuration parameters.
If you do not specify a configuration file with the "-c" command line option, the Mako Server looks for a file named mako.conf in the following directories:
The configuration file uses Lua syntax. The Mako Server loads the configuration file as a Lua table; thus all configuration options must be provided as key/value pairs. The following key/value pairs are the available configuration options:
When the Mako Server creates a SharkSSL object using ba.create.sharkssl() for its secure server connection object, the associated certificate store is set to nil unless 'certstore' is set. In most typical web server operations, a certificate store is not required. However, if there is a requirement to authenticate HTTP clients, including web browsers, through client-side certificates, then it becomes necessary to establish a certificate store. To request a client certificate from server-side code, use the request:clientcert() method. The client's certificate can be verified using request:certificate(). For this verification to succeed and return true, the certificate store must contain the certificate of the authority that signed the client's certificate. To facilitate the creation of a certificate store for the SharkSSL object, you can specify the necessary configuration in mako.conf. This configuration can be a single string (for one certificate) or a table (for multiple certificates).
certstore = string | table
Examples:
certstore="my-CA-cert.pem"
certstore={"my-CA-cert1.pem", "my-CA-cert2.pem"}
Set your own parameters in the configuration file and then access the configuration parameters from the loaded LSP applications. The configuration parameters are made available as a Lua module.
Example: Configuration File:myparam="This is my custom parameter"In your Lua code, load the configuration table as follows:
local conf=require"loadconf" print(conf.myparam) -- prints "This is my custom parameter"
Enable function mako.log(), which sends log and status information by email. Log data is accumulated internally in the log module, and an email is sent when the accumulated data is larger than 'maxsize' or data has been accumulated for longer than 'sdelay' seconds. Emails may also be sent immediately if the flush option is set when calling mako.log().
Table log:Download: ready-to-run example code from GitHub.
log = {
smtp = {
from = "john.doe@gmail.com",
to = "john.doe@gmail.com",
subject="My Server's Log",
server = "smtp.googlemail.com",
port = 465,
useauth = true,
consec = "tls",
user = "john.doe@gmail.com",
password = "qwerty"
},
logerr = true, -- Send Lua exceptions by email
signature = "Sent from my Mako Server"
}
The Mako Server creates several Barracuda IO instances, and one of them is the home IO, the IO object returned when calling ba.openio("home"). Many applications and modules rely on a working home directory. The home directory is by default set to the execution directory. This works when the server runs in console mode and when the server runs in daemon mode on Linux since a startup script can change to a suitable home directory prior to starting the server in daemon mode. However, this does not work when run as a service on Windows.
The Mako Server provides a platform-neutral way of setting the home directory by using the "homeio" option.
The following mako.conf example sets the home directory to c:\mako-home on a Windows computer:homeio="/c/mako-home" -- Must use POSIX path
If you are compiling the server's C code for an operating system that lacks the "executable directory" concept, such as VxWorks, you may want to provide a hard-coded default value in the C code. The hard-coded value is used if "homeio" is not set. See the C macro MAKO_HOME_DIR for details.
Mako Server uses the shared ACME certificate-management modules to obtain, install, and renew TLS certificates. Add an acme table to mako.conf to start the service automatically. The table must contain acceptTerms=true. No certificate installation callback is needed because Mako automatically updates its standard HTTPS listeners.
Mako stores the current ACME state below the acme directory in the configured home directory. Keep this directory private and move it with the home directory. It contains ACME account information, software-generated certificate private keys or TPM key descriptors, and, when SharkTrust is used, a secret device credential.
challenge. Use this when the certificate authority can reach this Mako Server by its public domain name.challenge.type="dns-01" and use a SharkTrust portal. The portal publishes the temporary DNS TXT record, so the Mako Server can remain on a private network.challenge.type="dns-01" and challenge.mode="manual". An operator must publish the TXT record and continue the paused operation.The field names in the following tables are the complete Mako configuration interface. They are case-sensitive. Legacy aliases such as acceptterms, rsa, tpm, servername, key, and revcon are not accepted.
acme Table| Field and type | Required | Meaning |
|---|---|---|
acceptTerms boolean | Yes | Must be true. Confirms acceptance of the selected ACME provider's terms. |
email string | Yes | Non-empty ACME account contact email address. |
domains table | Yes | Non-empty array of DNS-name strings. HTTP-01 and manual DNS-01 manage one certificate record per name. For automatic SharkTrust DNS-01, the first value is the requested device label or full name. The portal assigns the fully qualified name that Mako manages. |
production boolean | No | Set to false for the staging service. Mako selects production when the field is omitted. |
productionUrl, stagingUrl strings | No | HTTPS directory URLs for another RFC 8555 provider. Built-in Let's Encrypt URLs are used when omitted. |
cleanup boolean | No | Mako removes obsolete managed certificate entries unless this field is false. |
namePolicy string | No | SharkTrust naming policy: increment or exact. Mako defaults to increment. |
info string | No | Device description of at most 256 bytes, sent during SharkTrust enrollment. |
keyType string | No | Certificate key type: ecc or rsa. ECC is the default and automatically uses the Mako TPM integration when available. |
bits number | No | RSA key size when keyType="rsa". The default is 2048 bits. |
challenge table | No | DNS-01 configuration described below. Omit the table for HTTP-01. |
challenge Table| Field and type | Used for | Meaning |
|---|---|---|
type string | All DNS-01 configurations | Must be dns-01. Omit the complete challenge table for HTTP-01. |
mode string | Manual DNS-01 | Set to manual when an operator will publish the TXT record. Omit it, or set it to automatic, for SharkTrust automation. |
portalUrl string | Automatic DNS-01 with explicit credentials | HTTPS root URL for the SharkTrust portal, or its exact /sharktrust.lsp endpoint. Supply portalUrl, zoneKey, and secret together. Omit all three to use Mako's included embedded tokengen identity. |
zoneKey string | Automatic DNS-01 with explicit credentials | SharkTrust zone key as exactly 64 hexadecimal characters. |
secret string | Automatic DNS-01 with explicit credentials | SharkTrust zone secret as exactly 64 hexadecimal characters. |
dns string | Automatic DNS-01 | Address publication policy: local, wan, or both. The default is local. It does not select the ACME challenge type. |
reverse boolean | Automatic DNS-01 | True enables the SharkTrust reverse connection. The default is false. |
propagationDelay number | Automatic DNS-01 | Seconds to wait after publishing the DNS TXT record. The default is 30 seconds. |
acme = {
acceptTerms = true,
email = "operator@example.com",
domains = {"device.example.com"},
production = false
}
The domain must resolve to this server, and the ACME service must be able to reach its HTTP challenge endpoint.
tokengen Identity
acme = {
acceptTerms = true,
email = "operator@example.com",
domains = {"controller"},
production = false,
namePolicy = "increment",
challenge = {
type = "dns-01",
dns = "local",
reverse = false
},
info = "Mako"
}
The supplied Mako source includes a generated tokengen identity for the local.makoserver.net test zone. The build exposes it internally as etokengen. Mako loads it automatically and obtains the portal URL, zone key, and proof function, so these values do not appear in mako.conf. In this example, the portal assigns controller.local.makoserver.net, or a numbered variant when that name is already registered.
acme = {
acceptTerms = true,
email = "operator@example.com",
domains = {"controller.example-zone.com"},
production = false,
namePolicy = "increment",
challenge = {
type = "dns-01",
portalUrl = "https://portal.example.com/",
zoneKey = "<64-hexadecimal-character-zone-key>",
secret = "<64-hexadecimal-character-zone-secret>",
dns = "local",
reverse = false
},
info = "Mako"
}
Use explicit credentials when Mako must connect to a different SharkTrust portal instead of the included identity. Supply portalUrl, zoneKey, and secret together.
acme = {
acceptTerms = true,
email = "operator@example.com",
domains = {"device.example.com"},
production = false,
challenge = {type="dns-01", mode="manual"}
}
Mako exposes the selected manual adapter as mako.acme.challenge. Read mako.acme.challenge:status() to obtain the TXT record. After the record is publicly visible, call mako.acme.challenge:continue(callback). See the generic manual DNS example and manual adapter API.
mako.acme:setIpAddress(ipAddress, callback), where ipAddress is the new dotted-decimal IPv4 string.mako.acme is the shared runtime object. Mako starts it during server startup and closes it during shutdown.The Mako Server can load multiple applications. An application can be a directory, ZIP file, or network path. Applications can be loaded with the command line option -l, by creating an 'apps' table in the configuration file, or both.
Table 'apps' is a list of one or several of the following:The following example loads three applications: the first application is provided as a string, and the other two applications are provided as a Lua table. Providing a Lua table allows for more configuration options. The last application is loaded as a root application since we set the name to an empty string. The first application's name is set to the name of the directory 'app1'.
apps={
"/path/2/app1", -- path to 'www' directory. Base URL is: http://server/app1
{
name="myapp", -- Base URL is: http://server/myapp
prio=1, -- Higher priority (for directory/resource name conflict resolution).
path="/path/2/app2" -- path to 'www' directory
dav=true, -- WebDAV at /myapp/dav/
},
{
name="", -- Root app. -- Base URL is: http://server/
path="/path/2/app3"
dav="fs", -- WebDAV at /fs/
auth=true, -- Enable WebDAV authentication
}
}
host="localhost". Default binds to all interfaces.host="192.168.1.100". Default binds to all interfaces.The proxy configuration options are required if the server runs in an environment that requires a proxy for connecting to the Internet.
Table proxy:If you cannot use our recommended Let's Encrypt option, you can still load your own SSL certificates. For instance, you could create your own public key infrastructure using our free Certificate Management Tool. Note that the SSL Certificate option cannot be used in combination with the Let's Encrypt option.
Mako Server can load multiple certificates for various domains, but Mako Server also lets you load multiple certificates for the same domain name. SharkSSL then selects the certificate with the strongest cipher selection accepted by the client. Elliptic Curve Cryptography (ECC) certificates typically have a higher ranking than RSA certificates. The favorRSA option enables you to still favor RSA for clients that support both EC and RSA certificates. This option makes it possible to have a self signed ECC Certificate Authority (CA) and ECC chain for devices and serve RSA certificates for browsers. See the Certificate Management for IoT tutorial for details.
Enable the TraceLogger by setting one of the following two options:
When the TraceLogger is enabled, navigate to http://your-server/rtl/tracelogger/. The second option requires a user database. The second option also calls the TraceLogger's dir:configure() method with the provided table, enabling additional TraceLogger configuration.
Example:
tracelogger={
auth=true,
priority= 1 -- Filter out lower priority messages
}
users={
root="qwerty",
}
You can setup a static user database that can be used by the WebDAV server(s), the TraceLogger, and custom authenticators. The user database is a key-value pair, where the key is the username and the value is the password. The password can be cleartext or HA1.
Example:
users={
joe="querty", -- Joe's password is 'querty'
alice={'ef8fef1da0258aea0d0d234ab05debaf'} -- Alice's password is a HA1 hash
}
Function mako.udb() returns the static user database as an Authenticator User Database Object.
Realm name and HA1The realm is used by the Mako Server authenticators and the default realm name is "Barracuda Server". You may change the realm name as follows:
realm="My realm name"
Create a system wide Web File Server (WFS) at startup.
Table fileserver:Note: Unless noauth is set, the "fileserver" requires a user database and the fileserver parameter is ignored if no user database is configured.
MS Windows Example:
fileserver={
fsname="fs",
ioname="disk",
path="/C",
lockdir="temp/.LOCK"
}
The Barracuda App Server powering the Mako Server is designed for deep embedded systems where one may have requirements on resource allocation. The server is therefore designed such that one must pre-allocate the number of resources required. The following allows you to modify these options. See the C reference manual for detailed information.
You may hide the creation and modification of mako.conf from the end user; however, any changes require the Mako Server to be restarted before they take effect. As mentioned earlier, mako.conf uses Lua syntax and is loaded as a Lua table by module loadconf.
Converting the loaded Lua table back to a configuration file can be done by using a library such as inspect.lua.
The Mako Server includes all Barracuda App Server APIs and features. The Mako Server also includes the following extended features:
The Mako Server has the concept of an application environment. The environment for an application is a location where you can keep commonly used Lua code, i.e., library functions. This environment is available to LSP pages in the application, but not to LSP pages in other applications. The application environment is referred to as the application table in our documentation. The Mako Server provides a number of environments that can be used by LSP programmers.
The Mako Server creates an application table/environment per loaded application. This table is known as the "app" table and is explained in section Command (Request/Response) Environment. See the Mako Server tutorial Lua Environments and the .preload Script for a more in-depth explanation on how to use the .preload script.
The Mako Server looks for the .preload file in the application's root directory when starting an application. This file is loaded and executed as a Lua script, if found.
The preload script runs in the 'app' table environment (_ENV) and comes with the following pre-set values:
io object shadows Lua's standard io object. You may access Lua's io by prefixing it with _G, e.g., _G.io.
trace("Starting my application")
trace("Path = "..io:realpath(""))
trace("Base URL = "..dir:baseuri())
function onunload()
trace("Stopping my application")
end
The optional function 'onunload' is run when the application stops either when the server terminates or if the application is stopped by calling mako.stopapp or mako.reloadapp.
Functions and data in the .preload script are added to the application table. You can access this table from an LSP page as "app". For example, a function such as myfunc() can be accessed from an LSP page as app.myfunc().
For more information, see the tutorial Lua Environments and the .preload Script.
The Mako Server's integrated development environment is Xedge running as a Mako Server application. Xedge provides a browser-based file manager, Lua/LSP editor, and application manager for creating, starting, stopping, and testing Mako applications from the running server.
The simplest way to use this IDE is the mako.zip Developer Edition, which includes Xedge in mako.zip. Start the Mako Server with the Developer Edition package and open the server URL in a browser to use the integrated Xedge IDE.
If you are using a regular mako.zip package, you can load Xedge separately as a Mako application:
mako -l::Xedge.zip
Download a pre-assembled Xedge.zip, or build it from the BAS Resources repository by running XedgeMako.cmd on Windows or . XedgeMako.sh on macOS/Linux from the repository's build directory.
For detailed information about using the IDE and its additional APIs, see Using Xedge.
A function on the Windows version that translates a Windows path to a path that can be used by the IO interface.
For application-private Lua modules, prefer appreq. It loads modules from the application's .lua directory with application-local module state and avoids changing the global require() loader or module cache.
mako.createloader(io) is retained for applications that intentionally load application modules with the standard require() function. It extends require()'s search path so it can find Lua files in the current application's .lua directory. If an existing application needs this compatibility behavior, add the following line to the beginning of the application's .preload script.
mako.createloader(io) -- io is the application's pre-defined IO interface
The loader works for both deployed and non-deployed Lua applications. In other words, it works with deployed ZIP applications and with applications loaded from a directory. New applications should normally use appreq for modules private to the current application.
Mako Server and BAS do not include a package manager. When several applications need the same Lua modules, manually assemble those modules into a separate application and load that application before the applications that depend on it. The shared module application can call mako.createloader(io) from its .preload script so dependent applications can use standard require() for the shared modules.
The example application require-test (GitHub) shows the require()-based pattern.
Loads a private Lua module in the context of the current Mako or Xedge application. This is the preferred way to load modules stored in the application's .lua directory. Unlike the standard require() function, appreq uses application-local module state and does not use the global module environment or module cache. Xedge uses the same application-module contract and links to this section as the canonical description.
Note: This function is installed only if the application has a .preload script.
local mymodule = appreq"mymodule" assert(mymodule == appreq"mymodule") -- Cached by this application
The module name may use dot notation for subdirectories. Modules loaded by appreq have access to the application's app table and to appreq, allowing them to load other application-private modules.
local child = appreq"sub.mymodule"
return { child = child, app = app }
appreq is available in an application's .preload script and in modules loaded by appreq. In these environments, app == _ENV; consequently, app.appreq and appreq refer to the same function. LSP pages do not inherit the preload environment, but they can load an application-private module directly through the application table without an assignment in .preload:
-- LSP page local handler = app.appreq"http_handler"
appreq searches only the current application's private module space. Continue using standard require() for built-in Mako/BAS modules, such as loadconf and wfs, and for shared Lua modules that are deliberately provided by another loaded application. The appreq function is not available when Mako runs a standalone Lua script using mako script.lua.
Immediately terminates the Mako Server process with an optional exit code.
This function is only available when the server is running in the foreground. Internally, it calls the standard C exit() function and does not perform a graceful shutdown - open socket connections and other resources are not explicitly closed. Use this function for development or controlled shutdown scenarios where cleanup is not required.
Parameters:The function re-loads the certificates specified in mako.conf if no arguments are provided. The function enables an application to install new SSL certificates and then load the new certificates without having to restart the server. The Mako function loadcerts() is internally using the BAS function ba.create.servcon in the mode that enables it to recycle an existing server listening connection.
You may also dynamically load new certificates by providing the two arguments. The keys and certs arguments must be arrays of identical size, with the keys and certificates in the same order. Each array element is a string containing the pathname.
Note: Do not use this function if the Let's Encrypt plugin is enabled since use of this function would conflict with the Let's Encrypt plugin's use of this function.
Sends the message by email if data logging has been enabled in the configuration file. The function returns true if data logging is enabled and false otherwise.
Log data is accumulated internally in the log module, and an email is sent when the accumulated data is larger than 'maxsize' or data has been accumulated for longer than 'sdelay' seconds. Emails may also be sent immediately if the flush option is set.
Parameters:You may optionally set or override the following configuration options when 'flush' is set to true: 'from', 'to', and 'subject'. You may also add 'cc' and 'bcc'. See the SMTP library for details.
Deprecated. Use function ba.sharkclient().
Change the trace file name or location. This function enables you to dynamically change the trace file in a running system. The argument "name" is the full trace file name, including the path, which can be relative or absolute. The function returns true on success. The trace file is used by function trace(), Lua exceptions, and any traces enabled by the TraceLogger.
This function is created by mako.zip:/.config if a static user database has been set up in mako.conf.
The function returns the static user database as an Authenticator User Database Object.
Example usage:local auth = ba.create.authenticator(mako.udb())
You may control the applications loaded through command line parameters and the applications loaded through the configuration file. You may also dynamically create new applications.
Dynamically create and load a new application.
Parameters:Returns true on success and nil, err if the .preload script fails.
Returns a table with all apps loaded by the Mako Server. The following example restarts all applications:
for ix,path in ipairs(mako.getapps()) do
print("Reloading:",path)
mako.reloadapp(ix)
end
Reloads the .preload script for an app. Parameter x is either the application's environment or an index position returned by function mako.getapps(). The following code snippet can be used by an LSP page to reload the .preload script for the app:
mako.reloadapp(app) -- reload 'self'
Stops a registered application. Parameter x is either the application's environment (_ENV: app tab) or an index position returned by function mako.getapps().
Returns true on success and false, err if the .preload script has an unload function that failed. The function throws an error if parameter x is invalid.
Starts a registered application. Parameter x is either the application's environment or an index position returned by function mako.getapps().
Removes an app from the internal app database stored in mako.zip:/.config. Note: this function does not change static options such as mako.conf. Parameter x is either the application's environment or an index position returned by function mako.getapps().
The Barracuda App Server provides an IO interface in addition to the standard Lua input/output operations. These IO interfaces must be created by C code, and the Mako Server's C startup code creates the following IO interfaces:
The following example shows how to list all available IO interfaces:
for name,io in pairs(ba.io()) do print(name, ":", io:realpath"", " : ", io:resourcetype()) end
This example produces the following output when run on Linux:
disk : / : disk POSIX home : ./ : disk POSIX net : nil : net vm : nil : zip zip
See io:realpath() and io:resourcetype() for details on the printouts.
The server makes the following global variables accessible to the loaded applications:
Mako Server includes all Barracuda App Server modules and protocols in addition to the following Mako Server specific modules:
The ACME implementation is now shared by BAS, Mako Server, and Xedge. See the ACME module guide and API reference. The former acme/bot API is not part of the new implementation.
Returns all options in mako.conf, including custom options, as a Lua table.
Example:
for key,val in pairs(require"loadconf") do
print("Key=",key, ", val=", val)
end
Module log is automatically loaded by mako.zip/.config if mako.conf includes the data logging option. Module log activates function mako.log(). The module returns a table with functions, where the following function may be used by your programs:
Send an email using the log module's pre-configured SMTP object.
Argument op is a Lua table. You may optionally set or override the following log configuration options: ('body' or htmlbody'), 'from', 'to', and 'subject'. You may also add 'cc' and 'bcc'. See the SMTP library for details.
Note that the sendmail function may also route outgoing SMTP requests via a proxy if the proxy options are set in mako.conf.
The precompiled Mako Server includes LPeg (Lua Parsing Expression Grammars). LPeg brings PEG to Lua. See the following for details:
Example:
-- Using the LPeg module
local lpeg=require"lpeg"
print(lpeg.match(lpeg.P'a','aaa')) -- prints: 2
-- Using the re module
local re = require"re"
-- find the position of the first numeral in a string
print(re.find("the number 423 is odd", "[0-9]+")) -- prints: 12 14
The sqlutil library streamlines common read-oriented tasks when working with the LuaSQL SQLite module. It standardizes where Mako Server stores SQLite database files, opens connections by logical database name, and provides helpers for common SELECT queries.
To understand how this module is intended to be used, first read the Lua SQLite Tutorial. For LSP applications with concurrent write paths, also read LuaSQL SQLite and LSP Considerations.
For a real-world reference, you can also examine the SharkTrustX database module, which uses sqlutil for all database read operations.
The library is loaded as follows:
local su=require"sqlutil"
Database names and location:
sqlutil opens databases by logical name. The name "users" maps to the file users.sqlite.db in the current sqlutil database directory. During module initialization, sqlutil selects or creates a data subdirectory using the first available base location in this order:
dbdir from mako.conf, via require"loadconf".dbdirmako.cfgdirmako.execpathFor example, if the selected base directory is /var/mako, the database directory becomes /var/mako/data/ and su.open("users") opens /var/mako/data/users.sqlite.db. On Windows, sqlutil normalizes drive-letter and backslash syntax to the path form used by BAS IO APIs.
The sqlutil functions:
Opens or creates an SQLite database connection. The logical database name is resolved to su.dir() .. name .. ".sqlite.db" and opened with LuaSQL's SQLite driver.
If the first argument is a LuaSQL environment userdata, sqlutil reuses that environment. Otherwise, sqlutil creates an environment internally by calling luasql.sqlite(). The optional options argument is passed as-is to env:connect(filename, options); for SQLite this can be used for options such as "READONLY" or "NOCREATE".
Returns env, conn. Raises a Lua error if the database cannot be opened, using the form Cannot open <resolved path>: <driver error>. If opening the connection fails, the environment object in use is closed before the error is raised.
local su = require"sqlutil"
local env, conn = su.open("users")
-- ...
su.close(env, conn)
local env2, conn2 = su.open("users", "READONLY")
-- ...
su.close(env2, conn2)
Returns the current database directory when called without an argument. When path is supplied, the path must already exist and must be a directory. sqlutil then uses this directory directly for database files. Unlike the startup auto-discovery step, su.dir(path) does not append data and does not create the directory.
local su = require"sqlutil"
trace("Current DB directory:", su.dir())
su.dir("/var/mako/custom-data")
Returns true if su.dir() .. name .. ".sqlite.db" exists, otherwise returns false.
Closes the connection and environment by calling conn:close() and then env:close(). The function expects both arguments to be valid objects.
Executes a SELECT query and returns the first row. The query argument is the part after SELECT; sqlutil prepends SELECT automatically.
The first argument may be a connection object or a function that returns env, conn. When a function is used, sqlutil closes the connection and environment after the query completes.
su.find returns the first row as multiple values. su.findt returns the first row as a table keyed by column name; if a table is supplied, that table is reused.
local su = require"sqlutil"
local env, conn = su.open("users")
local id, name = su.find(conn, "id, name FROM users WHERE email='a@example.com' LIMIT 1")
local user = su.findt(conn, "id, name FROM users WHERE email='a@example.com' LIMIT 1")
su.close(env, conn)
Returns an iterator for a SELECT query. The query argument is the part after SELECT; sqlutil prepends SELECT automatically.
When asTable is true, each row is returned as a table keyed by column name. Otherwise, each row is returned as multiple values. The first argument may be a connection object or a function that returns env, conn. When a function is used, sqlutil closes the connection and environment when iteration reaches the end.
local su = require"sqlutil"
local function openUsers()
return su.open("users")
end
for user, email in su.iter(openUsers, "name, email FROM users ORDER BY name") do
trace(user, email)
end
for row in su.iter(openUsers, "name, email FROM users ORDER BY name", true) do
trace(row.name, row.email)
end
Executes a SELECT query and passes the resulting cursor to func(cur). The return values from func are returned by su.select. The cursor is closed before su.select returns.
The first argument may be a connection object or a function that returns env, conn. When a function is used, sqlutil closes the connection and environment after func returns. If the query initially returns BUSY, sqlutil retries the query up to three times.
local su = require"sqlutil"
local count = su.select(function() return su.open("users") end,
"count(*) FROM users",
function(cur)
return cur:fetch()
end)