webhook setup

This commit is contained in:
cpu
2025-05-12 02:18:30 +02:00
parent ea0b369ab5
commit c9273e65c6
8 changed files with 249 additions and 36 deletions

View File

@@ -1,5 +1,11 @@
# Nexus Timer 🕰️✨ # Nexus Timer 🕰️✨
# Table of Contents
1. [Core Concept](#core-concept)
2. [Target Audience](#target-audience)
3. [Hardware Recommendations (Optional Enhancement)](#hardware-recommendations-optional-enhancement)
4. [Key Features](#key-features)
Nexus Timer is a dynamic multi-player timer designed for games, workshops, or any activity where turns pass sequentially in a circular fashion. It provides a clear visual focus on the current participant and their immediate successor, ensuring everyone stays engaged and aware of who is next. This document serves as a detailed specification for a Progressive Web App (PWA) prototype aimed at game enthusiasts. Nexus Timer is a dynamic multi-player timer designed for games, workshops, or any activity where turns pass sequentially in a circular fashion. It provides a clear visual focus on the current participant and their immediate successor, ensuring everyone stays engaged and aware of who is next. This document serves as a detailed specification for a Progressive Web App (PWA) prototype aimed at game enthusiasts.
## Core Concept ## Core Concept

View File

@@ -1,3 +1,9 @@
# Table of Contents
1. [UI/UX Considerations](#uiux-considerations)
2. [Tech Stack](#tech-stack)
3. [Data Model (For AI Generation)](#data-model-for-ai-generation)
4. [Build-time Information & Service Worker Versioning](#build-time-information--service-worker-versioning)
## UI/UX Considerations ## UI/UX Considerations
* **Minimalist Design:** Focus on clarity and ease of use. Avoid clutter. * **Minimalist Design:** Focus on clarity and ease of use. Avoid clutter.
* **Large, Clear Timers:** Timers should be easily readable at a glance. * **Large, Clear Timers:** Timers should be easily readable at a glance.

View File

@@ -1,76 +1,169 @@
## Deployment Setup # Deployment Guide: Nexus Timer
This guide outlines the steps to deploy and manage the Nexus Timer application on a server using Docker, Traefik (as a reverse proxy), and systemd, with an optional automated deployment via Gitea webhooks.
## Table of Contents
1. [Initial Server Setup](#initial-server-setup)
2. [Exposing the App Behind Traefik](#exposing-the-app-behind-traefik-reverse-proxy)
3. [Automating Updates with Webhooks (Gitea)](#automating-updates-with-webhooks-gitea)
4. [Manual Updates (Fallback)](#manual-updates-fallback)
5. [Troubleshooting & Logs](#troubleshooting--logs)
## Initial Server Setup
### On the Server ### On the Server
Navigate to the service directory on the server Navigate to your preferred service directory on the server (e.g., `/virt`).
```bash ```bash
cd /virt cd /virt
``` ```
Clone the repository Clone the repository (only the latest commit for faster cloning).
```bash ```bash
git clone --depth 1 https://gitea.virtonline.eu/2HoursProject/nexus-timer.git git clone --depth 1 https://gitea.virtonline.eu/2HoursProject/nexus-timer.git
cd nexus-timer cd nexus-timer
``` ```
If you will run the container on the docker network `traefik` find its IP subnet If you will run the container on the Docker network `traefik` (or any other pre-existing network), find its IP subnet to allow Nginx inside the container to correctly identify the real client IP.
```bash ```bash
docker network inspect traefik --format '{{(index .IPAM.Config 0).Subnet}}' docker network inspect traefik --format '{{(index .IPAM.Config 0).Subnet}}'
``` ```
Set the subnet in the `nginx.conf`. For example: You'll get an output like `172.22.0.0/16`.
Set this subnet in the `nginx.conf` file within your cloned repository before building the image. For example:
```bash ```bash
set_real_ip_from 172.22.0.0/16 set_real_ip_from 172.22.0.0/16;
``` ```
Build the docker image Build the Docker image for the application.
```bash ```bash
docker build -t virt-nexus-timer . docker build -t virt-nexus-timer .
``` ```
## Exposing the App Behind Traefik (Reverse Proxy) ## Exposing the App Behind Traefik (Reverse Proxy)
This setup assumes you have Traefik running and configured to watch for Docker labels.
### Review the provided docker labels and systemd service file ### Review the provided docker labels and systemd service file
Copy the example label file to its destination The `docker/traefik.labels` file contains Docker labels that Traefik uses for routing and HTTPS. Review and adjust them if necessary.
Copy the example label file to its destination (one level up, to be read by systemd).
```bash ```bash
cp docker/traefik.labels labels cp docker/traefik.labels labels
``` ```
View the example service definition: View the example systemd service definition to understand how the Docker container will be managed.
```bash ```bash
cat systemd/virt-nexus-timer.service cat systemd/virt-nexus-timer.service
``` ```
### Create the systemd service ### Create the systemd service
The editor opens to create or overwrite the service: Use `systemctl edit` to create or overwrite the service file. This is the recommended way to manage custom systemd units.
```bash ```bash
sudo systemctl edit --force --full virt-nexus-timer.service sudo systemctl edit --force --full virt-nexus-timer.service
``` ```
Paste the content from `systemd/virt-nexus-timer.service`, then save and exit. The editor will open. Paste the content from your `systemd/virt-nexus-timer.service` file into the editor, then save and exit (e.g., Ctrl+X, then Y, then Enter in nano).
Enable on system boot and start the service Enable the service to start on system boot and start it immediately.
```bash ```bash
sudo systemctl enable --now virt-nexus-timer.service sudo systemctl enable --now virt-nexus-timer.service
``` ```
Check the service status Check the service status to ensure it's running correctly.
```bash ```bash
systemctl status virt-nexus-timer.service systemctl status virt-nexus-timer.service
``` ```
View real-time logs Look for "active (running)".
```bash
journalctl -fu virt-nexus-timer.service
```
### Test the web application ### Test the web application
Verify that the application is accessible via HTTPS: Verify that the application is accessible via HTTPS through Traefik:
```bash ```bash
curl https://nexus-timer.virtonline.eu curl https://nexus-timer.virtonline.eu
``` ```
Or open it in your browser: Or open it in your browser:
[https://nexus-timer.virtonline.eu](https://nexus-timer.virtonline.eu) [https://nexus-timer.virtonline.eu](https://nexus-timer.virtonline.eu)
## Release the update ## Automating Updates with Webhooks (Gitea)
### On the Server Instead of manually pulling, building, and restarting on the server, you can automate this process using a webhook. Gitea will notify a webhook service running on your server, which will then execute a deployment script.
Navigate to the app directory on your server
Install the `webhook` service
```bash
sudo install webhook
```
Allow your Gitea instance to reach the webhook service on your server (e.g., `10.0.0.1:9000`). Ensure Gitea's `ALLOWED_HOST_LIST` in its `app.ini` includes this IP.
### The Redeployment Script
The `webhook` service will execute the script `hooks/redeploy.sh`. If webhook runs as a non-root user (recommended), that user will need passwordless sudo permission to restart the `virt-nexus-timer.service`.
You can grant this by editing the sudoers file:
```bash
sudo visudo
```
and adding a line like:
```bash
webhooksvc ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart virt-nexus-timer.service
```
Replace `webhooksvc` with the actual user webhook runs as. If webhook runs as root, this is not necessary but less secure overall.
### Configure the `webhook` Service
Create or edit the main webhook configuration file, typically at `/etc/webhook.conf`. Add the JSON object from `hooks/webhook.conf` to the array in the file (or create the file if it's new).
**Note:** Replace `YOUR_VERY_STRONG_SECRET_TOKEN_HERE_REPLACE_ME` with a strong, unique secret.
### Set Up webhook as a Systemd Service
Use `systemctl edit` to create or overwrite the service file. This is the recommended way to manage custom systemd units.
```bash
sudo systemctl edit --force --full webhook.service
```
The editor will open. Paste the content from your `systemd/webhook.service` file into the editor, then save and exit (e.g., Ctrl+X, then Y, then Enter in nano).
Enable, and start the webhook service:
```bash
sudo systemctl enable --now webhook.service
sudo systemctl status webhook.service
```
### Configure Webhook in Gitea
1. Navigate to your Gitea repository: `https://gitea.virtonline.eu/2HoursProject/nexus-timer`
2. Go to `Settings -> Webhooks`.
3. Click Add Webhook and choose `Gitea`.
4. **Target URL**: `http://10.0.0.1:9000/hooks/redeploy-nexus-timer`
*(The redeploy-nexus-timer part must match the id in your /etc/webhook.conf)*
5. **HTTP Method**: POST
6. **POST Content Type**: application/json
7. **Secret**: Enter the exact same strong secret token you used in `/etc/webhook.conf` (e.g., `YOUR_VERY_STRONG_SECRET_TOKEN_HERE_REPLACE_ME`).
8. **Trigger On**:
Select `Push Events`.
You can further refine this to specific branches if your `webhook.conf` doesn't already filter by branch (though redundant filtering is fine).
9. Ensure `Enable this webhook` is checked.
10. Click `Add Webhook`.
### Test the Webhook
* In Gitea, on the Webhooks settings page for the webhook you just created, click `Test Delivery`.
* Check the Gitea UI for the response. It should show a `200 OK` and include the output from your `redeploy.sh` script.
* Push a small change to your `main` (or configured) branch to trigger a real deployment.
### Firewall Considerations
If your server has a firewall (e.g., `ufw`), ensure that port `9000` (or whichever port you configured for `webhook`) is allowed for incoming connections from your Gitea server's IP address or network.
Example for `ufw` allowing any connection to `10.0.0.1:9000` (restrict source IP if possible):
```bash
sudo ufw allow to 10.0.0.1 port 9000 proto tcp comment 'Gitea Webhook'
```
If Gitea is external, use its specific source IP instead of 'any' for better security.
```bash
sudo ufw allow from <GITEA_SERVER_IP> to 10.0.0.1 port 9000 proto tcp comment 'Gitea Webhook'
```
Reload `ufw` if changes are made:
```bash
sudo ufw reload
```
## Manual Updates (Fallback)
Navigate to the application directory on your server.
```bash ```bash
cd /virt/nexus-timer cd /virt/nexus-timer
``` ```
Pull the changes, build the docker image and restart the service Pull the latest changes from the repository, rebuild the Docker image, and restart the systemd service.
```bash ```bash
git pull && docker build -t virt-nexus-timer . && systemctl restart virt-nexus-timer.service git pull && docker build -t virt-nexus-timer . && sudo systemctl restart virt-nexus-timer.service
``` ```
View real-time logs The previously installed Progressive Web App (PWA) should update automatically upon next launch or offer an upgrade prompt.
## Troubleshooting & Logs
View real-time logs for the application service:
```bash ```bash
journalctl -fu virt-nexus-timer.service journalctl -fu virt-nexus-timer.service
``` ```
The previously installed PWA should update automatically or offer an upgrade View real-time logs for the `webhook` service:
```bash
journalctl -fu webhook.service
```
Check the custom log file for the redeployment script (if configured):
```bash
tail -f /var/log/webhook-redeploy-nexus-timer.log
```
Check Gitea's webhook delivery logs for request/response details and errors.

View File

@@ -1,3 +1,9 @@
# Table of Contents
1. [Developer Setup](#developer-setup)
2. [Modify the app](#modify-the-app)
3. [Test the PWA locally](#test-the-pwa-locally)
4. [Commit & Push](#commit--push)
## Developer Setup ## Developer Setup
Clone the repository Clone the repository
```bash ```bash

View File

@@ -1,15 +1,44 @@
#!/bin/bash #!/bin/bash
set -e set -eo pipefail # Exit on error, treat unset variables as an error, and propagate pipeline errors
echo "[webhook] Pulling new code..."
cd /virt/nexus-timer || exit 1 APP_DIR="/virt/nexus-timer"
git pull origin main IMAGE_NAME="virt-nexus-timer"
SERVICE_NAME="virt-nexus-timer.service"
LOG_FILE="/var/log/webhook-redeploy-nexus-timer.log" # Optional: for script-specific logging
echo "[webhook] Building image..." # Redirect stdout and stderr to a log file and also to the console (for webhook response)
docker build -t virt-nexus-timer . exec > >(tee -a "$LOG_FILE") 2>&1
echo "[webhook] Restarting systemd service..." echo "----------------------------------------------------"
systemctl restart virt-nexus-timer.service echo "Webhook redeploy-nexus-timer triggered at $(date)"
echo "Branch/Ref: $1"
echo "Repository: $2"
echo "----------------------------------------------------"
echo "[webhook] Done." # Ensure script is run from the app directory
cd "$APP_DIR" || { echo "ERROR: Failed to cd to $APP_DIR. Exiting."; exit 1; }
# Optional: Check if the trigger is for the correct branch (e.g., main or master)
# TARGET_BRANCH="refs/heads/main" # Adjust to your primary branch name
# if [ "$1" != "$TARGET_BRANCH" ]; then
# echo "Webhook triggered for branch $1, but only deploying $TARGET_BRANCH. Exiting."
# exit 0 # Exit successfully to not show an error in Gitea for non-target branches
# fi
echo "Pulling latest changes from Git (main branch)..."
# Ensure you are on the correct branch first or specify it in the pull
# git checkout main # Uncomment if your repo might be on other branches
git pull origin main || { echo "ERROR: git pull failed. Exiting."; exit 1; } # Adjust 'main' if needed
echo "Building Docker image $IMAGE_NAME..."
docker build -t "$IMAGE_NAME" . || { echo "ERROR: docker build failed. Exiting."; exit 1; }
echo "Restarting systemd service $SERVICE_NAME..."
# This command might require sudo privileges. See note below.
sudo systemctl restart "$SERVICE_NAME" || { echo "ERROR: systemctl restart failed. Exiting."; exit 1; }
echo "Deployment finished successfully at $(date)."
echo "----------------------------------------------------"
exit 0

38
hooks/webhook.conf Normal file
View File

@@ -0,0 +1,38 @@
[
{
"id": "redeploy-nexus-timer",
"execute-command": "/virt/nexus-timer/hooks/redeploy.sh",
"command-working-directory": "/virt/nexus-timer",
"pass-arguments-to-command": [
{ "source": "payload", "name": "ref" },
{ "source": "payload", "name": "repository.full_name" }
],
"trigger-rule": {
"and": [
{
"match": {
"type": "payload-hmac-sha256",
"secret": "YOUR_VERY_STRONG_SECRET_TOKEN_HERE_REPLACE_ME",
"parameter": {
"source": "header",
"name": "X-Gitea-Signature"
}
}
},
{
"match": {
"type": "value",
"value": "refs/heads/main",
"parameter": {
"source": "payload",
"name": "ref"
}
}
}
]
},
"include-command-output-in-response": true,
"include-command-output-in-response-on-error": true,
"response-message": "Webhook processed."
}
]

View File

@@ -7,7 +7,7 @@ DefaultDependencies=no
[Service] [Service]
Type=simple Type=simple
Environment="HOME=/root" Environment="HOME=/root"
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-nexus-timer 2>/dev/null || true' ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker stop -t 3 virt-nexus-timer 2>/dev/null || true'
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true' ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true'
ExecStart=/usr/bin/env docker run \ ExecStart=/usr/bin/env docker run \
@@ -17,7 +17,7 @@ ExecStart=/usr/bin/env docker run \
--label-file /virt/nexus-timer/labels \ --label-file /virt/nexus-timer/labels \
virt-nexus-timer virt-nexus-timer
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker kill virt-nexus-timer 2>/dev/null || true' ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker stop -t 3 virt-nexus-timer 2>/dev/null || true'
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true' ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker rm virt-nexus-timer 2>/dev/null || true'
Restart=always Restart=always

35
systemd/webhook.service Normal file
View File

@@ -0,0 +1,35 @@
[Unit]
Description=Small server for creating HTTP endpoints (hooks)
Documentation=https://github.com/adnanh/webhook/
After=network-online.target
Wants=network-online.target
ConditionPathExists=/etc/webhook.conf
[Service]
Type=simple
# Clear any existing ExecStart from a base unit file, if any
ExecStart=
# Path to webhook, IP, port, path to hooks config, verbose logging, hot-reloading config
ExecStart=/usr/bin/webhook -ip 10.0.0.1 -port 9000 -verbose -nopanic -hooks /etc/webhook.conf
# --- Security & User (Recommended) ---
# 1. Create a dedicated user:
# sudo useradd --system --no-create-home --shell /bin/false webhooksvc
# 2. Ensure this user can read /etc/webhook.conf and execute redeploy.sh
# sudo chown webhooksvc:webhooksvc /etc/webhook.conf && sudo chmod 640 /etc/webhook.conf
# Also grant sudo rights for systemctl restart as mentioned in Step 3.1.
# Uncomment and use if you created the 'webhooksvc' user:
# User=webhooksvc
# Group=webhooksvc
# If running as root (less secure), leave User/Group commented.
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target