From d0c2a4823828adbcc0f6bcd8defc554f36c508e7 Mon Sep 17 00:00:00 2001 From: luxick Date: Thu, 2 Oct 2025 09:32:07 +0200 Subject: [PATCH] Add systemd unit file --- .github/used-prompts/deploying.md | 107 ++++++++++++++++++++++++++++++ deploy/luxtools.service | 19 ++++++ 2 files changed, 126 insertions(+) create mode 100644 .github/used-prompts/deploying.md create mode 100644 deploy/luxtools.service diff --git a/.github/used-prompts/deploying.md b/.github/used-prompts/deploying.md new file mode 100644 index 0000000..e285796 --- /dev/null +++ b/.github/used-prompts/deploying.md @@ -0,0 +1,107 @@ +## Overview + +Deploy `luxtools` to the personal Fedora server manually—no CI/CD required. The application runs behind Nginx via a reverse proxy and is supervised by `systemd`. + +## Prerequisites + +- Fedora (server) with SSH access for a user that can `sudo` without a passwordless setup. +- Nim toolchain installed locally (for `nim`/`nimble`). +- Server already provisioned with Nim runtime dependencies. +- Existing Nginx site definition that proxies traffic to the `luxtools` service port (defaults to `127.0.0.1:9000`). + +## One-time server setup + +1. Create deployment directories on the server: + ```fish + ssh user@server 'sudo mkdir -p /opt/luxtools/bin /opt/luxtools/config && sudo chown ${USER}:${USER} /opt/luxtools -R' + ``` +2. Copy the `systemd` unit and enable it: + ```fish + printf '%s\n' "[Unit]" \ + "Description=luxtools web service" \ + "After=network.target" \ + "" \ + "[Service]" \ + "Type=simple" \ + "ExecStart=/opt/luxtools/bin/luxtools" \ + "Restart=on-failure" \ + "RestartSec=5" \ + "User=www-data" \ + "WorkingDirectory=/opt/luxtools" \ + "Environment=LOG_LEVEL=info" \ + "" \ + "[Install]" \ + "WantedBy=multi-user.target" \ + | ssh user@server 'sudo tee /etc/systemd/system/luxtools.service' + + ssh user@server 'sudo systemctl daemon-reload && sudo systemctl enable luxtools.service' + ``` +3. Ensure Nginx reverse proxy points to `127.0.0.1:9000` and reload it once configured: + ```fish + ssh user@server 'sudo systemctl restart nginx' + ``` + +## Deployment script + +Save the following as `scripts/deploy.fish` (or another preferred location) and make it executable with `chmod +x scripts/deploy.fish`. + +```fish +#!/usr/bin/env fish + +set -e + +set SERVER user@server +set TARGET_DIR /opt/luxtools +set BIN_NAME luxtools + +echo 'Building project locally (release)...' +nimble build -y + +echo 'Uploading binary...' +scp bin/$BIN_NAME $SERVER:$TARGET_DIR/bin/ + +echo 'Uploading static assets...' +scp -r src/static $SERVER:$TARGET_DIR/ + +echo 'Restarting services...' +ssh $SERVER 'sudo systemctl restart luxtools.service' +ssh $SERVER 'sudo systemctl restart nginx' + +echo 'Deployment finished.' +``` + +> The script prompts for the SSH password and any required `sudo` password on the server. + +## Manual deployment steps + +1. Build the project locally: + ```fish + nimble build -y + ``` +2. Copy the new build output and static assets: + ```fish + scp bin/luxtools user@server:/opt/luxtools/bin/ + scp -r src/static user@server:/opt/luxtools/ + ``` +3. Restart the service and, if needed, Nginx: + ```fish + ssh user@server 'sudo systemctl restart luxtools.service' + ssh user@server 'sudo systemctl restart nginx' + ``` + +## Verification + +- Check service status: + ```fish + ssh user@server 'systemctl status luxtools.service --no-pager' + ``` +- Review recent logs: + ```fish + ssh user@server 'journalctl -u luxtools.service -n 50 --no-pager' + ``` + +## Troubleshooting tips + +- If the service fails, run it manually on the server to capture stdout/stderr: `bin/luxtools`. +- Ensure SELinux contexts allow Nginx to proxy (`setsebool -P httpd_can_network_connect 1`). +- Validate reverse proxy config: `sudo nginx -t`. \ No newline at end of file diff --git a/deploy/luxtools.service b/deploy/luxtools.service new file mode 100644 index 0000000..a02d0c4 --- /dev/null +++ b/deploy/luxtools.service @@ -0,0 +1,19 @@ +[Unit] +Description=luxtools web service +After=network.target + +[Service] +Type=simple +ExecStart=/opt/luxtools/bin/luxtools +WorkingDirectory=/opt/luxtools +Restart=on-failure +RestartSec=5 +User=luxtools +Group=luxtools +Environment=LOG_LEVEL=info +Environment=PORT=9000 +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target