v0.3.0 - Complete deployment documentation and examples - Added comprehensive deployment guide, automated deployment scripts, nginx SSL proxy setup, backup automation, and monitoring tools. Includes VPS deployment, cloud platform guides, and practical examples for production deployment of event-based configuration system.

This commit is contained in:
Your Name
2025-09-06 20:19:12 -04:00
parent a02c1204ce
commit c1de1bb480
39 changed files with 6109 additions and 2452 deletions

View File

@@ -1,89 +1,101 @@
# C-Relay Systemd Service
# C Nostr Relay - SystemD Deployment
This directory contains files for running C-Relay as a Linux systemd service.
This directory contains files for deploying the C Nostr Relay as a systemd service with the new **Event-Based Configuration System**.
## Overview
The C Nostr Relay now uses a revolutionary **zero-configuration** approach where all configuration is stored as Nostr events (kind 33334) in the database. No configuration files or command line arguments are needed.
## Files
- **`c-relay.service`** - Systemd service unit file
- **`install-systemd.sh`** - Installation script (run as root)
- **`uninstall-systemd.sh`** - Uninstallation script (run as root)
- **`README.md`** - This documentation file
- **`c-relay.service`** - SystemD service unit file
- **`install-service.sh`** - Automated installation script
- **`uninstall-service.sh`** - Automated uninstall script
- **`README.md`** - This documentation
## Quick Start
## Quick Installation
1. **Build the project:**
```bash
make clean && make
```
2. **Install as systemd service:**
```bash
sudo systemd/install-service.sh
```
3. **Start the service:**
```bash
sudo systemctl start c-relay
```
4. **Check admin keys (IMPORTANT!):**
```bash
sudo journalctl -u c-relay --since="1 hour ago" | grep "Admin Private Key"
```
## Event-Based Configuration System
### How It Works
- **Zero Configuration:** No config files or command line arguments needed
- **First-Time Startup:** Automatically generates admin and relay keypairs
- **Database Naming:** Creates database as `<relay_pubkey>.nrdb`
- **Configuration Storage:** All settings stored as kind 33334 Nostr events
- **Real-Time Updates:** Configuration changes applied instantly via WebSocket
### First Startup
On first startup, the relay will:
1. Generate cryptographically secure admin and relay keypairs
2. Create database file named with relay pubkey: `<relay_pubkey>.nrdb`
3. Create initial configuration event (kind 33334) with default values
4. Display admin private key **once** in the logs
5. Start WebSocket server listening on port 8888
### Admin Keys
⚠️ **CRITICAL:** Save the admin private key displayed during first startup!
### 1. Build the relay
```bash
# From the project root directory
make
# View first startup logs to get admin private key
sudo journalctl -u c-relay --since="1 hour ago" | grep -A 5 "IMPORTANT: SAVE THIS ADMIN PRIVATE KEY"
```
### 2. Install as systemd service
The admin private key is needed to update relay configuration by sending signed kind 33334 events.
## Configuration Management
### Viewing Current Configuration
```bash
# Run the installation script as root
sudo ./systemd/install-systemd.sh
# Find the database file
ls /opt/c-relay/*.nrdb
# View configuration event
sqlite3 /opt/c-relay/<relay_pubkey>.nrdb "SELECT content, tags FROM events WHERE kind = 33334;"
```
### 3. Start the service
```bash
sudo systemctl start c-relay
```
### Updating Configuration
### 4. Check status
```bash
sudo systemctl status c-relay
```
Send a new kind 33334 event to the relay via WebSocket:
## Service Details
### Installation Location
- **Binary**: `/opt/c-relay/c_relay_x86`
- **Database**: `/opt/c-relay/db/`
- **Service File**: `/etc/systemd/system/c-relay.service`
### User Account
- **User**: `c-relay` (system user, no shell access)
- **Group**: `c-relay`
- **Home Directory**: `/opt/c-relay`
### Network Configuration
- **Default Port**: 8888
- **Default Host**: 127.0.0.1 (localhost only)
- **WebSocket Endpoint**: `ws://127.0.0.1:8888`
## Configuration
### Environment Variables
Edit `/etc/systemd/system/c-relay.service` to configure:
```ini
Environment=C_RELAY_CONFIG_PRIVKEY=your_private_key_here
Environment=C_RELAY_PORT=8888
Environment=C_RELAY_HOST=0.0.0.0
```
After editing, reload and restart:
```bash
sudo systemctl daemon-reload
sudo systemctl restart c-relay
```
### Security Settings
The service runs with enhanced security:
- Runs as unprivileged `c-relay` user
- No new privileges allowed
- Protected system directories
- Private temporary directory
- Limited file access (only `/opt/c-relay/db` writable)
- Network restrictions to IPv4/IPv6 only
1. Create new configuration event with updated values
2. Sign with admin private key
3. Send via WebSocket to relay
4. Relay automatically applies changes to running system
## Service Management
### Basic Commands
```bash
# Start service
sudo systemctl start c-relay
# Stop service
# Stop service
sudo systemctl stop c-relay
# Restart service
@@ -92,126 +104,143 @@ sudo systemctl restart c-relay
# Enable auto-start on boot
sudo systemctl enable c-relay
# Disable auto-start on boot
sudo systemctl disable c-relay
# Check service status
# Check status
sudo systemctl status c-relay
# View logs (live)
sudo journalctl -u c-relay -f
# View logs (last 100 lines)
sudo journalctl -u c-relay -n 100
# View recent logs
sudo journalctl -u c-relay --since="1 hour ago"
```
### Log Management
Logs are handled by systemd's journal:
### Log Analysis
```bash
# View all logs
sudo journalctl -u c-relay
# Check for successful startup
sudo journalctl -u c-relay | grep "First-time startup sequence completed"
# View logs from today
sudo journalctl -u c-relay --since today
# Find admin keys
sudo journalctl -u c-relay | grep "Admin Private Key"
# View logs with timestamps
sudo journalctl -u c-relay --since "1 hour ago" --no-pager
# Check configuration updates
sudo journalctl -u c-relay | grep "Configuration updated via kind 33334"
# Monitor real-time activity
sudo journalctl -u c-relay -f | grep -E "(INFO|SUCCESS|ERROR)"
```
## Database Management
## File Locations
The database is automatically created on first run. Location: `/opt/c-relay/db/c_nostr_relay.db`
After installation:
- **Binary:** `/opt/c-relay/c_relay_x86`
- **Database:** `/opt/c-relay/<relay_pubkey>.nrdb` (created automatically)
- **Service File:** `/etc/systemd/system/c-relay.service`
- **User:** `c-relay` (system user created automatically)
## Security Features
The systemd service includes security hardening:
- Runs as dedicated system user `c-relay`
- `NoNewPrivileges=true`
- `ProtectSystem=strict`
- `ProtectHome=true`
- `PrivateTmp=true`
- Limited address families (IPv4/IPv6 only)
- Resource limits (file descriptors, processes)
## Network Configuration
- **Default Port:** 8888 (WebSocket)
- **Protocol:** WebSocket with Nostr message format
- **Configuration:** Port configurable via kind 33334 events (no restart needed)
## Backup and Migration
### Backup
The database file contains everything:
### Backup Database
```bash
sudo cp /opt/c-relay/db/c_nostr_relay.db /opt/c-relay/db/backup-$(date +%Y%m%d).db
# Backup database file
sudo cp /opt/c-relay/*.nrdb /backup/location/
# The .nrdb file contains:
# - All Nostr events
# - Configuration events (kind 33334)
# - Relay keys and settings
```
### Reset Database
```bash
sudo systemctl stop c-relay
sudo rm /opt/c-relay/db/c_nostr_relay.db*
sudo systemctl start c-relay
```
### Migration
## Updating the Service
To migrate to new server:
### Update Binary
1. Build new version: `make`
2. Stop service: `sudo systemctl stop c-relay`
3. Replace binary: `sudo cp build/c_relay_x86 /opt/c-relay/`
4. Set permissions: `sudo chown c-relay:c-relay /opt/c-relay/c_relay_x86`
5. Start service: `sudo systemctl start c-relay`
### Update Service File
1. Stop service: `sudo systemctl stop c-relay`
2. Copy new service file: `sudo cp systemd/c-relay.service /etc/systemd/system/`
3. Reload systemd: `sudo systemctl daemon-reload`
4. Start service: `sudo systemctl start c-relay`
## Uninstallation
Run the uninstall script to completely remove the service:
```bash
sudo ./systemd/uninstall-systemd.sh
```
This will:
- Stop and disable the service
- Remove the systemd service file
- Optionally remove the installation directory
- Optionally remove the `c-relay` user account
1. Copy `.nrdb` file to new server's `/opt/c-relay/` directory
2. Install service with `install-service.sh`
3. Start service - it will automatically detect existing configuration
## Troubleshooting
### Service Won't Start
```bash
# Check detailed status
sudo systemctl status c-relay -l
# Check service status
sudo systemctl status c-relay
# Check logs for errors
sudo journalctl -u c-relay --no-pager -l
```
sudo journalctl -u c-relay --no-pager
### Permission Issues
```bash
# Fix ownership of installation directory
sudo chown -R c-relay:c-relay /opt/c-relay
# Check if binary exists and is executable
ls -la /opt/c-relay/c_relay_x86
# Ensure binary is executable
sudo chmod +x /opt/c-relay/c_relay_x86
```
### Port Already in Use
```bash
# Check what's using port 8888
sudo netstat -tulpn | grep :8888
# Or with ss command
sudo ss -tulpn | grep :8888
# Check permissions
sudo -u c-relay ls -la /opt/c-relay/
```
### Database Issues
```bash
# Check database file permissions
ls -la /opt/c-relay/db/
# Check if database file exists
ls -la /opt/c-relay/*.nrdb*
# Check database integrity
sudo -u c-relay sqlite3 /opt/c-relay/db/c_nostr_relay.db "PRAGMA integrity_check;"
sqlite3 /opt/c-relay/*.nrdb "PRAGMA integrity_check;"
# View database schema
sqlite3 /opt/c-relay/*.nrdb ".schema"
```
## Custom Configuration
### Configuration Issues
For advanced configurations, you can:
1. Modify the service file for different ports or settings
2. Use environment files: `/etc/systemd/system/c-relay.service.d/override.conf`
3. Configure log rotation with journald settings
4. Set up reverse proxy (nginx/apache) for HTTPS support
```bash
# Check if configuration event exists
sqlite3 /opt/c-relay/*.nrdb "SELECT COUNT(*) FROM events WHERE kind = 33334;"
## Security Considerations
# View configuration event
sqlite3 /opt/c-relay/*.nrdb "SELECT id, created_at, LENGTH(tags) FROM events WHERE kind = 33334;"
```
- The service runs as a non-root user with minimal privileges
- Database directory is only writable by the c-relay user
- Consider firewall rules for the relay port
- For internet-facing relays, use reverse proxy with SSL/TLS
- Monitor logs for suspicious activity
## Uninstallation
```bash
sudo systemd/uninstall-service.sh
```
The uninstall script will:
- Stop and disable the service
- Remove service file
- Optionally remove installation directory and data
- Optionally remove service user
## Support
For issues with the event-based configuration system:
1. Check service logs: `sudo journalctl -u c-relay -f`
2. Verify database integrity
3. Ensure admin private key is saved securely
4. Check WebSocket connectivity on port 8888
The relay is designed to be zero-maintenance once deployed. All configuration is managed through Nostr events, enabling dynamic updates without server access.

View File

@@ -1,5 +1,5 @@
[Unit]
Description=C Nostr Relay Server
Description=C Nostr Relay Server (Event-Based Configuration)
Documentation=https://github.com/your-repo/c-relay
After=network.target
Wants=network-online.target
@@ -20,7 +20,7 @@ SyslogIdentifier=c-relay
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/c-relay/db
ReadWritePaths=/opt/c-relay
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
@@ -34,10 +34,10 @@ RestrictAddressFamilies=AF_INET AF_INET6
LimitNOFILE=65536
LimitNPROC=4096
# Environment variables (optional)
Environment=C_RELAY_CONFIG_PRIVKEY=
Environment=C_RELAY_PORT=8888
Environment=C_RELAY_HOST=127.0.0.1
# Event-based configuration system
# No environment variables needed - all configuration is stored as Nostr events
# Database files (<relay_pubkey>.nrdb) are created automatically in WorkingDirectory
# Admin keys are generated and displayed only during first startup
[Install]
WantedBy=multi-user.target

105
systemd/install-service.sh Executable file
View File

@@ -0,0 +1,105 @@
#!/bin/bash
# C Nostr Relay Event-Based Configuration System - Installation Script
# This script installs the C Nostr Relay as a systemd service
set -e
# Configuration
SERVICE_NAME="c-relay"
SERVICE_USER="c-relay"
INSTALL_DIR="/opt/c-relay"
BINARY_NAME="c_relay_x86"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root"
exit 1
fi
print_info "Installing C Nostr Relay with Event-Based Configuration System"
echo
# Check if binary exists
if [ ! -f "build/${BINARY_NAME}" ]; then
print_error "Binary build/${BINARY_NAME} not found. Please build the project first."
exit 1
fi
# Create service user
if ! id "${SERVICE_USER}" &>/dev/null; then
print_info "Creating service user: ${SERVICE_USER}"
useradd --system --home-dir "${INSTALL_DIR}" --shell /bin/false "${SERVICE_USER}"
print_success "Service user created"
else
print_info "Service user ${SERVICE_USER} already exists"
fi
# Create installation directory
print_info "Creating installation directory: ${INSTALL_DIR}"
mkdir -p "${INSTALL_DIR}"
chown "${SERVICE_USER}:${SERVICE_USER}" "${INSTALL_DIR}"
# Copy binary
print_info "Installing binary to ${INSTALL_DIR}/${BINARY_NAME}"
cp "build/${BINARY_NAME}" "${INSTALL_DIR}/"
chown "${SERVICE_USER}:${SERVICE_USER}" "${INSTALL_DIR}/${BINARY_NAME}"
chmod +x "${INSTALL_DIR}/${BINARY_NAME}"
# Install systemd service file
print_info "Installing systemd service file"
cp "systemd/${SERVICE_NAME}.service" "/etc/systemd/system/"
# Reload systemd
print_info "Reloading systemd daemon"
systemctl daemon-reload
print_success "Installation complete!"
echo
print_info "Event-Based Configuration System Information:"
echo " • No configuration files needed - all config stored as Nostr events"
echo " • Database files are created automatically as <relay_pubkey>.nrdb"
echo " • Admin keys are generated and displayed during first startup"
echo " • Configuration is updated via WebSocket with kind 33334 events"
echo
print_info "To start the service:"
echo " sudo systemctl start ${SERVICE_NAME}"
echo
print_info "To enable automatic startup:"
echo " sudo systemctl enable ${SERVICE_NAME}"
echo
print_info "To view service status:"
echo " sudo systemctl status ${SERVICE_NAME}"
echo
print_info "To view logs:"
echo " sudo journalctl -u ${SERVICE_NAME} -f"
echo
print_warning "IMPORTANT: On first startup, save the admin private key displayed in the logs!"
print_warning "Use: sudo journalctl -u ${SERVICE_NAME} --since=\"1 hour ago\" | grep \"Admin Private Key\""
echo
print_info "Database files will be created in: ${INSTALL_DIR}/<relay_pubkey>.nrdb"
print_info "The relay will listen on port 8888 by default (configured via Nostr events)"

103
systemd/uninstall-service.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/bin/bash
# C Nostr Relay Event-Based Configuration System - Uninstall Script
# This script removes the C Nostr Relay systemd service
set -e
# Configuration
SERVICE_NAME="c-relay"
SERVICE_USER="c-relay"
INSTALL_DIR="/opt/c-relay"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root"
exit 1
fi
print_info "Uninstalling C Nostr Relay Event-Based Configuration System"
echo
# Stop and disable service
if systemctl is-active --quiet "${SERVICE_NAME}"; then
print_info "Stopping ${SERVICE_NAME} service"
systemctl stop "${SERVICE_NAME}"
fi
if systemctl is-enabled --quiet "${SERVICE_NAME}"; then
print_info "Disabling ${SERVICE_NAME} service"
systemctl disable "${SERVICE_NAME}"
fi
# Remove systemd service file
if [ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]; then
print_info "Removing systemd service file"
rm "/etc/systemd/system/${SERVICE_NAME}.service"
fi
# Reload systemd
print_info "Reloading systemd daemon"
systemctl daemon-reload
systemctl reset-failed
# Ask about removing installation directory and databases
echo
print_warning "The installation directory ${INSTALL_DIR} contains:"
echo " • The relay binary"
echo " • Database files with all events and configuration (.nrdb files)"
echo " • Any logs or temporary files"
echo
read -p "Do you want to remove ${INSTALL_DIR} and all data? [y/N]: " -r
if [[ $REPLY =~ ^[Yy]$ ]]; then
print_info "Removing installation directory: ${INSTALL_DIR}"
rm -rf "${INSTALL_DIR}"
print_success "Installation directory removed"
else
print_info "Installation directory preserved: ${INSTALL_DIR}"
print_warning "Database files (.nrdb) are preserved and contain all relay data"
fi
# Ask about removing service user
echo
read -p "Do you want to remove the service user '${SERVICE_USER}'? [y/N]: " -r
if [[ $REPLY =~ ^[Yy]$ ]]; then
if id "${SERVICE_USER}" &>/dev/null; then
print_info "Removing service user: ${SERVICE_USER}"
userdel "${SERVICE_USER}" 2>/dev/null || print_warning "Could not remove user ${SERVICE_USER}"
print_success "Service user removed"
else
print_info "Service user ${SERVICE_USER} does not exist"
fi
else
print_info "Service user '${SERVICE_USER}' preserved"
fi
print_success "Uninstallation complete!"
echo
print_info "If you preserved the database files, you can reinstall and the relay will"
print_info "automatically detect the existing configuration and continue with the same keys."