Systemd and Swift applications
This article is for those who write server-side Swift applications
All applications on the server must be run under the control of some kind of daemon. You may already be using supervisord
or systemd
.
This article will show you how to simplify your life with systemd
by integrating it directly into your application via an SPM plugin.
First, let's look at how we usually work with systemd
and what needs to be done to make it work with our application.
Pure systemd
Settings
You need to find examples of a valid config on the Internet, play with it and save it in the right place /etc/systemd/system
.
Most developers give up somewhere around here..
State management
After successful configuration, we need to remember to start the service.
To do this, you need to remember a few simple commands:
systemctl start myapp.service
restart myapp.service
stop myapp.service
Everything is easy here, but you need to remember the name of the configuration file
Removing a service
systemctl stop myapp.service
systemctl start clean --all
Not too hard to remember, but still…
Viewing logs
This is where most developers get lost because the logs are stored somewhere in the depths /var/logs
or anywhere else. This is where it comes to the rescue journalctl
.
Real time logs
journalctl -u myapp -f
Last few lines
journalctl -u myapp -n 100 --no-pager
I find it a little difficult to remember all of this, and I often just click “up” on the history in the console in search of the desired command
Plugin
A plugin can make your life a lot easier SwiftSystemd.
It provides an easy way to manage all the above-mentioned processes without any headaches.
You only need to do two steps: add it to the project and run the configuration command.
Adding to a project
Open the file Package.swift
your application and add just one line:
.package(url: "https://github.com/MihaelIsaev/SwiftSystemd.git", from:"1.0.0")
Setup command
Go to your Swift application folder and run:
swift run systemd install
At this point, the configuration file will be created and the application will be launched.
It is possible to avoid dialogs in the console by passing the parameters in advance:
swift run systemd install -c release -t App -u mike
-c,–config | build configuration: |
-t,–target | name of executable target from |
-u,–user | the user under whom the service will run |
Listing of the generated configuration file:
[Unit]
Description="AppName"
After=network.target
[Service]
User={user}
EnvironmentFile=/path/to/AppName/.env
WorkingDirectory=/path/to/AppName
TimeoutStopSec=2
Restart=always
ExecStart=/path/to/AppName/.build/{config}/{target}
[Install]
WantedBy=multi-user.target
That's it! You configured your application correctly, and you didn’t have to google or remember anything. Just two simple steps and it's already working.
Logs
One of the most important tasks is viewing logs.
swift run systemd logs
This way you will get real-time logs of your application from journalctl
.
swift run systemd logs --limit 100
This is how you can display the latest 100
lines from application logs.
Easy to remember!
State management
Check service activity:
swift run systemd status
You can manage the state of the service using the following commands:
swift run systemd start # запускает приложение
stop # останавливает приложение
restart # перезапускает приложение
disable # временно отключает приложение
enable # включает приложение
You can also send kill
signal to application:
swift run systemd kill
Removing a service
If you no longer need the service, you can easily remove it completely:
swift run systemd uninstall
Conclusion
Now you can throw away all your notes by systemctl
And journalctl
.
I will be glad to see your commits to the project.