Эта статья для тех, кто пишет серверные Swift приложения
Все приложения на сервере необходимо запускать под управлением какого-либо демона. Возможно, вы уже используете supervisord
или systemd
.
Эта статья покажет, как упростить вашу жизнь при помощи systemd
, интегрировав его напрямую в ваше приложение через SPM-плагин.
Для начала давайте посмотрим, как мы обычно работаем с systemd
и что нужно проделать для его работы с нашим приложением.
Чистый systemd
Настройка
Необходимо найти на просторах интернета примеры валидного конфига, поиграться с ним и сохранить в правильное место /etc/systemd/system
.
Большинство разработчиков сдаются где-то здесь..
Управление состоянием
После успешного конфигурирования нам нужно не забыть запустить сервис.
Для этого нужно запомнить несколько простых команд:
systemctl start myapp.service
restart myapp.service
stop myapp.service
Тут всё легко, но нужно помнить название конфигурационного файла
Удаление сервиса
systemctl stop myapp.service
systemctl start clean --all
Не слишком сложно запомнить, но все же...
Просмотр логов
Здесь большинство разработчиков теряются потому что логи хранятся где-то в недрах /var/logs
или где-либо ещё. Тут на помощь приходит journalctl
.
Логи в реальном времени
journalctl -u myapp -f
Последние несколько строк
journalctl -u myapp -n 100 --no-pager
По-моему запомнить всё этого немного сложно, и я часто просто жму "вверх" по истории в консоли в поисках нужной команды
Плагин
Сильно упростить жизнь может плагин SwiftSystemd.
Он предоставляет простой способ управления всеми вышеупомянутыми процессами без головной боли.
Нужно сделать всего два действия: добавить в проект и запустить команду настройки.
Добавление в проект
Откройте файл Package.swift
вашего приложения и добавьте всего одну строку:
.package(url: "https://github.com/MihaelIsaev/SwiftSystemd.git", from:"1.0.0")
Команда настройки
Перейдите в папку с вашим Swift приложением и выполните:
swift run systemd install
На этом конфигурационный файл будет создан и приложение будет запущено.
Есть возможность обойтись без диалогов в консоле заранее передав параметры:
swift run systemd install -c release -t App -u mike
-c,--config |
конфигурация сборки: |
-t,--target |
имя исполняемого таргета из |
-u,--user |
пользователь, под которым будет работать сервис |
Листинг сгенерированного конфигурационного файла:
[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
Вот и всё! Вы настроили своё приложение правильно, и не пришлось ничего гуглить и вспоминать. Всего два простых шага, и оно уже работает.
Логи
Одна из самых важных задач — просмотр логов.
swift run systemd logs
Так вы получите логи вашего приложения в реальном времени из journalctl
.
swift run systemd logs --limit 100
Так можно вывести последние 100
строк из логов приложения.
Легко запомнить!
Управление состоянием
Проверить активность сервиса:
swift run systemd status
С помощью следующих команд можно управлять состоянием сервиса:
swift run systemd start # запускает приложение
stop # останавливает приложение
restart # перезапускает приложение
disable # временно отключает приложение
enable # включает приложение
Так же можно отправить kill
сигнал приложению:
swift run systemd kill
Удаление сервиса
Если вам больше не нужен сервис, вы можете легко его начисто удалить:
swift run systemd uninstall
Заключение
Теперь можно выбросить все свои заметки по systemctl
и journalctl
.
Буду рад вашим коммитам в проект.
AuToMaton
Очень порадовал ироничный стиль автора.
Хорошая practical joke.
Ещё одна.
Это не может быть - либо сколько ни жми команды не будет, либо всё давно запомнилось. Если бы вместо «запомнить» стояло «утомляет набирать», было бы правдоподобно но не смешно.
А, классика - вредные советы. Засорить все свои проекты плагином. А в глубине, как тать заметённый под ковёр, скрывается идея естественности написания приложения для сервера на самом сервере.
Правильно. Заметки по командам ежечасного использования, если они конечно есть, давно пора выбросить.
И да, заглянул в код и удивился - зачем при попытке снести сервис когда его нет предлагать его установить? Отсылка к классике про наполнение чайника математиком?
Но как же это было интересно, статья отличная
Я узнал и как выглядит код на Swift, и как хорош его менеджер пакетов, и как Swift может применяться на Андроид, и как на нём можно писать сайты, и как из него обращаться к системным функциям… и всё по ссылочкам, с интересом, быстро и конкретно (не забудьте глянуть профиль автора на GitHub). Финал-апофеоз случился когда я обнаружил swiftly (https://github.com/swiftlang/swiftly) для установки Swift помимо менеджера пакетов дистрибутива, как я люблю, не пробовал пока.
Шальные мысли
Если посмотреть чуть серьёзнее, то напрашивается приложение которое ставит любой выполняемый файл сервисом. А если подумать, то это должно быть в systemctl. Но понятно - туда такое не пустят за обрезанностью бритвой Оккама. На что мгновенно возникает ответ - переписать systemctl. И это очень в стиле Rust, уже очень удачно переписали, например, cat (bat) и Midnight Commander (nnn).
После инициированного статьёй, я вижу - а можно и на Swift переписать, публика только другая и не случится, но как говаривал президент Буш соревнуясь с премьером Черномырдиным
Что особенно приятно думать после не акцентированных но прозвучавших на WWDC слов о том, что Эппл будет работать над расширением области применения Swift.
Могу ли я придумать способ прорекламировать Swift лучше? Нет, не могу.