SOP-2 Automating Via Cross-Platform Deployment

Status: PRODUCTION

Systems: Linux Fedora 43 (Nobara), Windows Server (Windows 10 LTSC), Samba (Inter-Op)

Objective: I wanted to automate how I write this Digital Garden portfolio while maintaining services on my Windows-based NGINX instance.

Because I'm exporting this garden to a local instance and not to the cloud I needed to streamline the process of saving my notes. I also reduced security concerns by not needing to open any SSH ports on the web server.

Note: I could've automated this further by having my bash script observe changes on my local drive, but I wanted this to act more as a "Save" button to avoid accidental deployments.


1. Overview

This pipeline eliminates manual file transfers by using a Bash-driven build process on my Fedora computer, an rsync mirroring to a Samba share, and an asynchronous "Power Shell Trigger" to bounce the NGINX service on the Windows Server.

All you have to do now on Obsidian is export to the local directory. Then run a single script to deploy the notes. I have a "Watchdog" PowerShell script running on a 5 second loop to monitor a trigger file the bash script adds with the touch command. Watchdog only triggers a NGINX restart when this file is present to complete deployment.

2. The Linux Build Script (deploy.sh)

This script executes the local build and synchronizes the distribution folder with the production environment.

Bash

#!/bin/bash
# Move to project directory
cd ~/path/to/digital-garden

# Execute static site build
npm run build

# Synchronize files to Samba share
# --delete: Removes orphaned files to ensure a clean production mirror
rsync -avz --delete ./dist/ /mnt/samba/web_root/

# Signal the Windows Watchdog to restart Nginx
touch /mnt/samba/web_root/reload.txt

echo "Deployment sync complete. Restart signal sent."

3. The Windows Watchdog Script (watchdog.ps1)

Since NGINX is running as a standalone executable on Windows, this PowerShell script monitors for a trigger file and refreshes the process.

PowerShell

# Trigger the NGINX after our trigger file is present
$triggerPath = "C:\nginx-1.27.3\html\reload.txt"

while($true) {
    if (Test-Path $triggerPath) {
        # Terminate existing Nginx process
        Stop-Process -Name "nginx" -Force -ErrorAction SilentlyContinue
        
        # Restart Nginx from the bin directory
        Start-Process -FilePath "C:\nginx-1.27.3\nginx.exe" `
                      -WorkingDirectory "C:\nginx-1.27.3\"
        
        # Finally delete the trigger file
        Remove-Item $triggerPath
        
        Write-Host "Nginx refreshed at $(Get-Date)" -ForegroundColor Green
    }
    Start-Sleep -Seconds 5
}

4. Engineering Decisions & Security


Troubleshooting