Created Tutorial: Creating a (micro) service (asciidoc)
This commit is contained in:
parent
cd1b25a659
commit
2b10336e6c
|
@ -0,0 +1,169 @@
|
|||
How to create a simple HTTP service and run it under systemd.
|
||||
|
||||
Replace myservicename and myservicedir.
|
||||
|
||||
Install the build requirements:
|
||||
[source,bash]
|
||||
----
|
||||
nimble install jester
|
||||
----
|
||||
|
||||
=== Basic HTTP service
|
||||
|
||||
Create myservice.nim :
|
||||
[source,nim]
|
||||
----
|
||||
import jester, posix, json
|
||||
const config_file_name = "conf.json"
|
||||
|
||||
# the "debug" and "info" macros from the logging module are not flushing the buffer
|
||||
|
||||
proc log_debug(args: varargs[string, `$`]) =
|
||||
debug args
|
||||
fl.file.flushFile()
|
||||
|
||||
proc log_info(args: varargs[string, `$`]) =
|
||||
info args
|
||||
fl.file.flushFile()
|
||||
|
||||
onSignal(SIGABRT):
|
||||
## Handle SIGABRT from systemd
|
||||
# Lines printed to stdout will be received by systemd and logged
|
||||
# Start with "<severity>" from 0 to 7
|
||||
echo "<2>Received SIGABRT"
|
||||
quit(1)
|
||||
|
||||
# Add handlers for SIGSTOP, SIGQUIT as needed
|
||||
|
||||
let conf = parseFile(config_file_name)
|
||||
let fl = newFileLogger(conf["log_fname"].str, fmtStr = "$datetime $levelname ")
|
||||
fl.addHandler
|
||||
|
||||
include "templates/base.tmpl"
|
||||
include "templates/home.tmpl"
|
||||
|
||||
routes:
|
||||
get "/":
|
||||
resp base_page(generate_home_page())
|
||||
|
||||
when isMainModule:
|
||||
log_info "starting"
|
||||
runForever()
|
||||
|
||||
----
|
||||
|
||||
=== Example templates
|
||||
|
||||
Create /var/lib/myservicename/temaplates/base.tmpl
|
||||
[source,nim]
|
||||
----
|
||||
#? stdtmpl | standard
|
||||
#proc base_page(content: string): string =
|
||||
# result = ""
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>myservicename</title>
|
||||
<link rel="shortcut icon" href=""/>
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
${content}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
----
|
||||
|
||||
Create /var/lib/myservicename/temaplates/home.tmpl
|
||||
[source,nim]
|
||||
----
|
||||
#? stdtmpl | standard
|
||||
#proc generate_home_page(): string =
|
||||
# result = ""
|
||||
<h5>Welcome to myservicename</h5>
|
||||
----
|
||||
|
||||
|
||||
=== Configure the running environment
|
||||
|
||||
Create /lib/systemd/system/myservicename.service file. Configure CapabilityBoundingSet as needed.
|
||||
|
||||
[source,ini]
|
||||
----
|
||||
[Unit]
|
||||
Description=myservicename
|
||||
Documentation=man:myservicename
|
||||
Documentation=https://github.com/REPLACEME/myservicename
|
||||
After=network.target httpd.service squid.service nfs-server.service mysqld.service named.service postfix.service
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/var/lib/myservicedir/
|
||||
ExecStart=/usr/bin/stdbuf -oL /var/lib/myservicedir/myservicename
|
||||
TimeoutStopSec=10
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
|
||||
User=myservicename
|
||||
#Group=myservicename
|
||||
# Restart the daemon if crashes or is killed
|
||||
Restart=always
|
||||
RestartSec=2s
|
||||
LimitNOFILE=65536
|
||||
|
||||
# Hardening
|
||||
NoNewPrivileges=yes
|
||||
CapabilityBoundingSet=CAP_DAC_READ_SEARCH
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
ProtectHome=yes
|
||||
ProtectSystem=full
|
||||
StandardOutput=syslog+console
|
||||
StandardError=syslog+console
|
||||
ReadWriteDirectories=/proc/self
|
||||
ReadWriteDirectories=-/var/run
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
----
|
||||
|
||||
Create /var/lib/myservicedir/conf.json
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"log_fname": "/var/log/myservicename.log",
|
||||
}
|
||||
----
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
sudo adduser myservicename --system --home /var/lib/myservicedir
|
||||
sudo touch /var/log/myservicename.log
|
||||
sudo chown myservicename:myservicename /var/log/myservicename.log
|
||||
sudo systemctl enable myservicename
|
||||
sudo systemctl start myservicename
|
||||
----
|
||||
|
||||
|
||||
=== Systemd watchdog
|
||||
|
||||
To enable a watchdog, add "WatchdogSec=10s" to the service file.
|
||||
|
||||
Install https://github.com/FedericoCeratto/nim-sdnotify
|
||||
|
||||
[source,nim]
|
||||
----
|
||||
import sdnotify
|
||||
let sd = newSDNotify()
|
||||
sd.notify_ready()
|
||||
# Every 5 seconds in a dedicated thread:
|
||||
sd.ping_watchdog()
|
||||
----
|
||||
|
Loading…
Reference in New Issue