diff options
19 files changed, 1107 insertions, 0 deletions
diff --git a/scripts/powershell/Get-GitDirty.ps1 b/scripts/powershell/Get-GitDirty.ps1 new file mode 100644 index 0000000..9216ef2 --- /dev/null +++ b/scripts/powershell/Get-GitDirty.ps1 @@ -0,0 +1,19 @@ +<# +.SYNOPSIS + Lists immediate subdirectories containing git repositories with pending changes. + +.DESCRIPTION + This script scans all depth-1 directories in the current location. + It filters for valid git repositories and checks if 'git status' returns any output. + Only the names of repositories with uncommitted changes (dirty) are returned. + +.EXAMPLE + PS C:\MyProjects> Get-GitDirty + + Returns a list of folder names that have pending changes. +#> + +Get-ChildItem -Directory | +Where-Object { Test-Path "$($_.FullName)\.git" } | +Where-Object { git -C $_.FullName status --porcelain } | +Select-Object Name
\ No newline at end of file diff --git a/scripts/powershell/Show-GitStatus.ps1 b/scripts/powershell/Show-GitStatus.ps1 new file mode 100644 index 0000000..e8b9548 --- /dev/null +++ b/scripts/powershell/Show-GitStatus.ps1 @@ -0,0 +1,27 @@ +<# +.SYNOPSIS + Displays a color-coded status report for all git repositories in immediate subdirectories. + +.DESCRIPTION + Iterates through all depth-1 directories. If a directory is a git repository, + it checks the status and prints the folder name to the host. + - Prints "[CLEAN]" in Green if there are no pending changes. + - Prints "[DIRTY]" in Red if there are uncommitted changes. + +.EXAMPLE + PS C:\MyProjects> Show-GitStatus + + repo-api [CLEAN] + repo-ui [DIRTY] +#> + +Get-ChildItem -Directory | +Where-Object { Test-Path "$($_.FullName)\.git" } | +ForEach-Object { + if (git -C $_.FullName status --porcelain) { + Write-Host "$($_.Name) [DIRTY]" -ForegroundColor Red + } + else { + Write-Host "$($_.Name) [CLEAN]" -ForegroundColor Green + } +}
\ No newline at end of file diff --git a/unsorted/Shadow VRChat Devbox/README.md b/unsorted/Shadow VRChat Devbox/README.md new file mode 100644 index 0000000..0084437 --- /dev/null +++ b/unsorted/Shadow VRChat Devbox/README.md @@ -0,0 +1,19 @@ +# Shadow VRChat Devbox Setup Script + +This PowerShell script automates the setup of a VRChat development environment on a Shadow cloud-based PC. It installs essential software and configures them to sane defaults ready for VRChat development. + +## Quick Start + +Run ONE of the following commands in PowerShell on your Shadow PC: + +**Reliable cached version:** + +```powershell +iex (New-Object Net.WebClient).DownloadString('https://zue.dev/shadow-vrchat.ps1') +``` + +**Latest version (may be unstable):** + +```powershell +iex (New-Object Net.WebClient).DownloadString('https://forgejo.sovereign.zue.dev/zuedev/monorepo/raw/branch/main/unsorted/Shadow%20VRChat%20Devbox/setup.ps1') +``` diff --git a/unsorted/Shadow VRChat Devbox/VRChat Avatars (bayla preset + poipro).alcomtemplate b/unsorted/Shadow VRChat Devbox/VRChat Avatars (bayla preset + poipro).alcomtemplate new file mode 100644 index 0000000..cc8d20f --- /dev/null +++ b/unsorted/Shadow VRChat Devbox/VRChat Avatars (bayla preset + poipro).alcomtemplate @@ -0,0 +1,18 @@ +{ + "$type": "com.anatawa12.vrc-get.custom-template", + "formatVersion": "1.0", + "displayName": "VRChat Avatars (bayla preset + poipro)", + "updateDate": "2025-12-19T10:20:48.285745200Z", + "id": "com.anatawa12.vrc-get.user.8fee84c2febe4d8c85d5e24dfd1b22dc", + "base": "com.anatawa12.vrc-get.vrchat.avatars", + "unityVersion": "2022.3.22", + "vpmDependencies": { + "com.vrchat.avatars": "*", + "com.vrcfury.vrcfury": "*", + "com.llealloo.audiolink": "*", + "vrchat.blackstartx.gesture-manager": "*", + "gogoloco": "*", + "nadena.dev.modular-avatar": "*" + }, + "unityPackages": [] +}
\ No newline at end of file diff --git a/unsorted/Shadow VRChat Devbox/repositories.txt b/unsorted/Shadow VRChat Devbox/repositories.txt new file mode 100644 index 0000000..a42272c --- /dev/null +++ b/unsorted/Shadow VRChat Devbox/repositories.txt @@ -0,0 +1,4 @@ +https://vcc.vrcfury.com/ +https://spokeek.github.io/goloco/index.json +https://adjerry91.github.io/VRCFaceTracking-Templates/index.json +https://vpm.nadena.dev/vpm.json diff --git a/unsorted/Shadow VRChat Devbox/setup.ps1 b/unsorted/Shadow VRChat Devbox/setup.ps1 new file mode 100644 index 0000000..d1c8acd --- /dev/null +++ b/unsorted/Shadow VRChat Devbox/setup.ps1 @@ -0,0 +1,136 @@ +<# +.SYNOPSIS + Setup VRChat Devbox on Shadow PC + +.DESCRIPTION + This script installs necessary software for VRChat development on a Shadow cloud-based PC. + +.NOTES + Shadow: https://shadow.tech/ + VRChat: https://vrchat.com/ +#> + +# Are we in an elevated session? +If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) +{ + Write-Warning "You do not have Administrator rights to run this script! Please re-run this script as an Administrator!" + Break +} + +# is chocolatey installed? +if (-not (Get-Command choco -ErrorAction SilentlyContinue)) { + # Install Chocolatey + Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) +} + +# pass -y to all choco installs +choco feature enable -n allowGlobalConfirmation + +# disable checksum checks +choco feature disable -n checksumFiles + +# Download and install Winget v1.6.3482 as Shadow's default Winget version is broken +$targetWingetVersion = "v1.6.3482" +$currentWingetVersion = (winget --version 2>$null) + +if ($currentWingetVersion -ne $targetWingetVersion) { + Write-Host "Current Winget version ($currentWingetVersion) differs from target ($targetWingetVersion). Downgrading..." + Invoke-WebRequest -Uri "https://github.com/microsoft/winget-cli/releases/download/v1.6.3482/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle" -OutFile "C:\Users\Shadow\Downloads\Winget_Old.msixbundle" + + # Install the downloaded Winget package + Add-AppxPackage -Path "C:\Users\Shadow\Downloads\Winget_Old.msixbundle" + + # Clean up downloaded Winget package + Remove-Item -Path "C:\Users\Shadow\Downloads\Winget_Old.msixbundle" -Force +} else { + Write-Host "Winget is already at the target version ($targetWingetVersion). Skipping downgrade." +} + +# Reset Winget source and remove msstore (has certificate issues on Shadow) +winget source reset --force +winget source remove msstore + +# mass-install required software that doesn't need special setup +winget install Unity.Unity.2022 -v "2022.3.22f1" # current LTS version vrchat uses +winget install Unity.UnityHub # needed because life is pain +winget install anatawa12.ALCOM # better vrchat creator companion +winget install Git.Git # version control +winget install tailscale.tailscale # private network connectivity +winget install motrix.Motrix # download manager +winget install 7zip.7zip # archive manager +winget install microsoft.VisualStudioCode # code editor +winget install JanDeDobbeleer.OhMyPosh # fancy terminal prompt + +choco install googlechrome # browser + +# Remove all stuff from desktop (both user and public desktop) +Remove-Item -Path "C:\Users\Shadow\Desktop\*" -Recurse -Force -ErrorAction SilentlyContinue +Remove-Item -Path "C:\Users\Public\Desktop\*" -Recurse -Force -ErrorAction SilentlyContinue + +# Reload environment variables to ensure newly installed software is recognized +$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") + +# set up oh my posh +oh-my-posh font install Meslo + +# set powershell prompt to oh my posh +$profilePath = "$HOME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1" + +if (-not (Test-Path -Path $profilePath)) { + New-Item -ItemType File -Path $profilePath -Force +} + +$ohMyPoshInit = 'oh-my-posh init pwsh | Invoke-Expression' + +if (-not (Get-Content $profilePath | Select-String -Pattern 'oh-my-posh')) { + Add-Content -Path $profilePath -Value $ohMyPoshInit +} + +# update windows terminal font +$wtSettingsPath = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" + +if (Test-Path $wtSettingsPath) { + $wtSettings = Get-Content $wtSettingsPath | ConvertFrom-Json + foreach ($profile in $wtSettings.profiles.list) { + $profile.fontFace = "MesloLGS NF" + } + $wtSettings | ConvertTo-Json -Depth 32 | Set-Content $wtSettingsPath +} + +# Set desktop wallpaper to vrchat +$wallpaperUrl = "https://forgejo.sovereign.zue.dev/zuedev/monorepo/raw/branch/main/unsorted/Shadow%20VRChat%20Devbox/wallpaper.png" +$wallpaperPath = "C:\Users\Shadow\Pictures\vrchat_wallpaper.png" +Invoke-WebRequest -Uri $wallpaperUrl -OutFile $wallpaperPath +Add-Type -TypeDefinition @" +using System; +using System.Runtime.InteropServices; +public class Wallpaper { + [DllImport("user32.dll", SetLastError = true)] + public static extern bool SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); +} +"@ +[Wallpaper]::SystemParametersInfo(20, 0, $wallpaperPath, 3) + +# Set Unity Hub to use installed Unity version +$unityHubConfigPath = "C:\Users\Shadow\AppData\Roaming\UnityHub\preferences.json" +if (Test-Path $unityHubConfigPath) { + $config = Get-Content $unityHubConfigPath | ConvertFrom-Json + $config.defaultUnityVersion = "2022.3.22f1" + $config | ConvertTo-Json | Set-Content $unityHubConfigPath +} + +# Set Git global configuration +git config --global user.name "zuedev" +git config --global user.email "zuedev@gmail.com" + +# show file extensions in explorer +Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "HideFileExt" -Value 0 + +# show hidden files in explorer +Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "Hidden" -Value 1 + +# reload explorer to apply changes +Stop-Process -Name explorer -Force + +# Final message +Write-Host "VRChat Devbox setup complete."
\ No newline at end of file diff --git a/unsorted/Shadow VRChat Devbox/wallpaper.png b/unsorted/Shadow VRChat Devbox/wallpaper.png Binary files differnew file mode 100644 index 0000000..d695f47 --- /dev/null +++ b/unsorted/Shadow VRChat Devbox/wallpaper.png diff --git a/unsorted/docker-compose.bash/README.md b/unsorted/docker-compose.bash/README.md new file mode 100644 index 0000000..adf9086 --- /dev/null +++ b/unsorted/docker-compose.bash/README.md @@ -0,0 +1,67 @@ +# docker-compose.bash + +A bash script for managing multiple Docker Compose stacks from a single root directory. Designed for servers running multiple containerized services. + +## Features + +- Automatically detects and manages all Docker Compose projects in subdirectories +- Supports multiple compose file naming conventions (`compose.yaml`, `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`) +- Provides batch operations across all stacks +- Includes scheduled task commands for automation (cron-friendly) + +## Configuration + +By default, the script looks for compose stacks in: + +```bash +ROOT_DIR="/mnt/user/root/docker-compose" +``` + +Modify this variable to match your setup. + +## Usage + +```bash +./docker-compose.bash <command> +``` + +### Commands + +| Command | Description | +| ------- | ----------------------------------------------------------- | +| `up` | Start all compose stacks in detached mode | +| `down` | Stop all compose stacks | +| `pull` | Pull latest images for all stacks | +| `build` | Build images for all stacks | +| `prune` | Remove all unused Docker data (images, containers, volumes) | + +### Scheduled Task Commands + +These commands are designed for use with cron or other schedulers: + +| Command | Description | +| ---------- | ---------------------------------------------- | +| `minutely` | No-op (placeholder for future use) | +| `hourly` | Runs `up` to ensure all services are running | +| `daily` | Runs system prune to clean up unused resources | +| `reboot` | Starts all stacks and prunes the system | + +## Example Directory Structure + +``` +/mnt/user/root/docker-compose/ +├── pihole/ +│ └── docker-compose.yaml +├── nginx/ +│ └── compose.yaml +└── postgres/ + └── docker-compose.yml +``` + +## Example Cron Setup + +```cron +@hourly /path/to/docker-compose.bash hourly +@daily /path/to/docker-compose.bash daily +@reboot /path/to/docker-compose.bash reboot +``` diff --git a/unsorted/docker-compose.bash/docker-compose.bash b/unsorted/docker-compose.bash/docker-compose.bash new file mode 100644 index 0000000..8e5af31 --- /dev/null +++ b/unsorted/docker-compose.bash/docker-compose.bash @@ -0,0 +1,223 @@ +#!/bin/bash + +ROOT_DIR="/mnt/user/root/docker-compose" + +# check pwd to see if we're in coder, change root dir +if [[ "$(pwd)" == "/home/coder/project" ]]; then + ROOT_DIR="/home/coder/project" +fi + +LOG_DIR="$ROOT_DIR/logs" + +# color setup (ANSI, with tput fallback). Disabled if not a TTY. +if [ -t 1 ]; then + if command -v tput >/dev/null 2>&1; then + BOLD=$(tput bold) + RESET=$(tput sgr0) + BLUE=$(tput setaf 4) + GREEN=$(tput setaf 2) + RED=$(tput setaf 1) + YELLOW=$(tput setaf 3) + else + BOLD='\033[1m' + RESET='\033[0m' + BLUE='\033[34m' + GREEN='\033[32m' + RED='\033[31m' + YELLOW='\033[33m' + fi +else + BOLD='' + RESET='' + BLUE='' + GREEN='' + RED='' + YELLOW='' +fi + +# make sure we're in the right directory +cd $ROOT_DIR + +# ensure logs directory exists +mkdir -p "$LOG_DIR" + +# list of compose files to detect (in order of priority) +COMPOSE_FILES=("compose.yaml" "compose.yml" "docker-compose.yaml" "docker-compose.yml") + +function has_compose_file { + for file in "${COMPOSE_FILES[@]}"; do + if [ -f "$1/$file" ]; then + return 0 + fi + done + return 1 +} + +function execute_in_subdir { + # check if directory exists + if [ -d "$1" ]; then + # run command in directory + cd $1 && $2 && cd .. + fi +} + +function execute_in_all_subdirs { + # command to run (preserve spacing) + local cmd="$*" + local dirs=() + local pids=() + + # iterate subdirectories safely + for d in */; do + # remove trailing slash + local dir="${d%/}" + # check if directory contains a compose file + if has_compose_file "$dir"; then + local logfile="$LOG_DIR/${dir}.log" + printf "[%s] %s▶%s %s%s%s: %s → %s\n" "$(date -Is)" "$BLUE" "$RESET" "$BOLD" "$dir" "$RESET" "$cmd" "$logfile" + ( + echo "[$(date -Is)] START ${dir}: ${cmd}" > "$logfile" + cd "$dir" && eval "$cmd" >> "$logfile" 2>&1 + local status=$? + echo "[$(date -Is)] END ${dir} status=${status}" >> "$logfile" + exit $status + ) & + dirs+=("$dir") + pids+=("$!") + fi + done + + # wait for all background jobs to complete and summarize + local i status failcount=0 + for i in "${!pids[@]}"; do + local dir="${dirs[$i]}" + wait "${pids[$i]}" + status=$? + if [ $status -eq 0 ]; then + printf "[%s] %s✔%s %s completed\n" "$(date -Is)" "$GREEN" "$RESET" "$dir" + else + printf "[%s] %s✖%s %s failed (status %d). See %s/%s.log\n" "$(date -Is)" "$RED" "$RESET" "$dir" "$status" "$LOG_DIR" "$dir" + failcount=$((failcount+1)) + fi + done + + # return non-zero if any failures + if [ $failcount -gt 0 ]; then + return 1 + fi +} + +function dc_pull_up { + # check if directory contains a compose file + if has_compose_file "$1"; then + # run docker compose + cd $ROOT_DIR/$1 && docker compose pull && docker compose up -d --remove-orphans && cd $ROOT_DIR + fi +} + +function dc_build_up { + # check if directory contains a compose file + if has_compose_file "$1"; then + # run docker compose + cd $ROOT_DIR/$1 && docker compose build && docker compose up -d --remove-orphans && cd $ROOT_DIR + fi +} + +case $1 in +up) + execute_in_all_subdirs "docker compose up -d --remove-orphans" + ;; +down) + execute_in_all_subdirs "docker compose down" + ;; +pull) + execute_in_all_subdirs "docker compose pull" + ;; +build) + execute_in_all_subdirs "docker compose build" + ;; +prune) + docker system prune --all --volumes --force + ;; +minutely) + echo "Nothing to do!" + ;; +hourly) + execute_in_all_subdirs "docker compose up -d --remove-orphans" + ;; +daily) + docker system prune --all --volumes --force + ;; +reboot) + execute_in_all_subdirs "docker compose up -d --remove-orphans" + docker system prune --all --volumes --force + ;; +check-tags) + issues_total=0 + problematic_images=() + + for d in */; do + dir="${d%/}" + if has_compose_file "$dir"; then + printf "[%s] %s▶%s Checking %s%s%s...\n" "$(date -Is)" "$BLUE" "$RESET" "$BOLD" "$dir" "$RESET" + cd "$dir" + images=$(docker compose config 2>/dev/null | grep -E '^\s*image:' | awk '{print $2}') + has_issues=0 + + while IFS= read -r image; do + if [ -n "$image" ]; then + if [[ "$image" != *":"* ]] || [[ "$image" == *":latest" ]]; then + printf " %s⚠%s %s\n" "$YELLOW" "$RESET" "$image" + has_issues=1 + issues_total=$((issues_total+1)) + problematic_images+=("$dir: $image") + fi + fi + done <<< "$images" + + if [ $has_issues -eq 0 ]; then + printf "[%s] %s✔%s %s: No issues found\n" "$(date -Is)" "$GREEN" "$RESET" "$dir" + fi + + cd "$ROOT_DIR" + fi + done + + if [ $issues_total -gt 0 ]; then + printf "\n%s⚠ Found %d image(s) with dynamic tags:%s\n" "$YELLOW" "$issues_total" "$RESET" + for img in "${problematic_images[@]}"; do + printf " - %s\n" "$img" + done + exit 1 + else + printf "\n%s✔ All images use pinned tags%s\n" "$GREEN" "$RESET" + fi + ;; +b2sync) + # is rclone installed? + if ! command -v rclone >/dev/null 2>&1; then + echo "rclone is not installed. Please install rclone to use this feature." + exit 1 + fi + + # directory exclusions + EXCLUDE_DIRS=("unity-accelerator/agent") + B2_EXCLUDE_PARAMS=() + for exdir in "${EXCLUDE_DIRS[@]}"; do + B2_EXCLUDE_PARAMS+=("--exclude" "$exdir/**") + done + + # perform backup using rclone + B2_BUCKET_NAME="sovereign-docker-compose-sync-clone" + B2_KEY_ID="B2_KEY_ID" + B2_KEY_SECRET="B2_KEY_SECRET" + RCLONE_REMOTE=":b2,fast_list,hard_delete,account=$B2_KEY_ID,key=$B2_KEY_SECRET:$B2_BUCKET_NAME" + + echo "Starting backup to Backblaze B2..." + rclone sync "$ROOT_DIR/$dir" "$RCLONE_REMOTE/$dir" --progress "${B2_EXCLUDE_PARAMS[@]}" --checkers=32 --transfers=32 + echo "Backup completed." + ;; +*) + echo "Unrecognized command: $1" + ;; +esac diff --git a/unsorted/docker_compose_stacks/README.md b/unsorted/docker_compose_stacks/README.md new file mode 100644 index 0000000..c139989 --- /dev/null +++ b/unsorted/docker_compose_stacks/README.md @@ -0,0 +1,5 @@ +# Docker Compose Stacks + +My docker compose stacks. + +Each stack is contained in its own directory with a `docker-compose.yaml` file and a `README.md` file describing the stack and its configuration. Other files may be present as needed for configuration or data persistence. diff --git a/unsorted/docker_compose_stacks/code-server-via-tailscale/README.md b/unsorted/docker_compose_stacks/code-server-via-tailscale/README.md new file mode 100644 index 0000000..9e3b897 --- /dev/null +++ b/unsorted/docker_compose_stacks/code-server-via-tailscale/README.md @@ -0,0 +1,134 @@ +# Code Server via Tailscale + +This Docker Compose stack deploys [code-server](https://github.com/coder/code-server) (VS Code in the browser) accessible securely through your [Tailscale](https://tailscale.com/) network. + +## What This Does + +- Runs code-server (web-based VS Code) on port 80 +- Exposes code-server exclusively through Tailscale (not accessible on local network) +- Provides secure remote access to your development environment from anywhere on your Tailnet + +## Prerequisites + +- Docker and Docker Compose installed +- A Tailscale account +- Tailscale authentication key (get one from [Tailscale Admin Console](https://login.tailscale.com/admin/settings/keys)) + +## Configuration + +### 1. Set Code Server Password + +Edit `docker-compose.yaml` and change the default password: + +```yaml +environment: + - PASSWORD=CHANGEME # Change this to a secure password +``` + +### 2. Configure Tailscale + +Before starting the stack, you need to provide a Tailscale auth key. You can either: + +**Option A: Set environment variable** + +```bash +export TS_AUTHKEY="tskey-auth-xxxxx" +``` + +**Option B: Edit docker-compose.yaml** + +Add the auth key to the tailscale service environment variables: + +```yaml +environment: + - TS_AUTHKEY=tskey-auth-xxxxx + - TS_AUTH_ONCE="true" + - TS_STATE_DIR=/var/lib/tailscale +``` + +### 3. (Optional) Customize Hostname + +The service will appear as `code-server` in your Tailscale admin console. To change this, edit the `hostname` field in the tailscale service. + +## Deployment + +1. Start the stack: + + ```bash + docker compose up -d + ``` + +2. Check that both services are running: + + ```bash + docker compose ps + ``` + +3. View logs to confirm Tailscale authentication: + ```bash + docker compose logs tailscale + ``` + +## Accessing Code Server + +1. Find your code-server URL in the [Tailscale Admin Console](https://login.tailscale.com/admin/machines) +2. Navigate to `http://code-server` (or the custom hostname you set) in your browser +3. Enter the password you configured +4. Start coding! + +## Directory Structure + +After deployment, the following directories will be created: + +- `./config` - Code-server configuration and settings +- `./project` - Your project files and workspace +- `./tailscale-data` - Tailscale state data (authentication and network info) + +## Important Notes + +- **Security**: Code-server is only accessible through your Tailscale network, providing zero-trust security +- **Network Mode**: The code-server container uses the tailscale service's network stack (`network_mode: service:tailscale`) +- **Password**: Make sure to change the default password before deploying to production +- **Persistence**: All data is stored in local volumes, so your work persists across container restarts +- **Resource Access**: The tailscale service needs `NET_ADMIN` and `NET_RAW` capabilities to manage the VPN tunnel + +## Stopping the Stack + +```bash +docker compose down +``` + +To remove all data (including your projects): + +```bash +docker compose down -v +rm -rf config project tailscale-data +``` + +## Troubleshooting + +### Can't connect to code-server + +1. Verify Tailscale is authenticated: + + ```bash + docker compose logs tailscale + ``` + +2. Check that both containers are running: + + ```bash + docker compose ps + ``` + +3. Ensure you're connected to Tailscale on your client device + +### Authentication issues + +- Make sure your Tailscale auth key is valid and not expired +- Auth keys can be reusable or one-time use - check your key settings in the Tailscale admin console + +## Version Information + +- **code-server**: 4.107.0-39 +- **tailscale**: v1.92.4 diff --git a/unsorted/docker_compose_stacks/code-server-via-tailscale/docker-compose.yaml b/unsorted/docker_compose_stacks/code-server-via-tailscale/docker-compose.yaml new file mode 100644 index 0000000..f18ba3b --- /dev/null +++ b/unsorted/docker_compose_stacks/code-server-via-tailscale/docker-compose.yaml @@ -0,0 +1,25 @@ +services: + code-server: + image: codercom/code-server:4.107.0-39 + network_mode: service:tailscale + environment: + - PASSWORD=CHANGEME + volumes: + - ./config:/home/coder/.local/share/code-server + - ./project:/home/coder/project + restart: unless-stopped + command: ["--bind-addr", "0.0.0.0:80", "--auth", "password"] + + tailscale: + image: tailscale/tailscale:v1.92.4 + hostname: code-server + environment: + - TS_AUTH_ONCE="true" + - TS_STATE_DIR=/var/lib/tailscale + volumes: + - ./tailscale-data:/var/lib/tailscale + - /dev/net/tun:/dev/net/tun + cap_add: + - NET_ADMIN + - NET_RAW + restart: unless-stopped
\ No newline at end of file diff --git a/unsorted/docker_compose_stacks/pihole-via-tailscale/README.md b/unsorted/docker_compose_stacks/pihole-via-tailscale/README.md new file mode 100644 index 0000000..47b6869 --- /dev/null +++ b/unsorted/docker_compose_stacks/pihole-via-tailscale/README.md @@ -0,0 +1,34 @@ +# Pi-hole via Tailscale + +A Docker Compose stack that runs [Pi-hole](https://pi-hole.net/) behind [Tailscale](https://tailscale.com/), making your Pi-hole instance accessible only via your Tailnet. + +## Services + +- **Pi-hole** - Network-wide ad blocking DNS server +- **Tailscale** - Secure mesh VPN for private network access + +## Setup + +1. Change the `WEBPASSWORD` environment variable in `docker-compose.yaml` to a secure password +2. Start the stack: + ```bash + docker compose up -d + ``` +3. Get the Tailscale login URL: + ```bash + docker compose logs -f tailscale + ``` +4. Open the login URL in your browser to authenticate with Tailscale +5. Access Pi-hole's admin interface at `http://pihole:80/admin` from any device on your Tailnet + +## Configuration + +- **Timezone**: Set via `TZ` environment variable (default: `Europe/London`) +- **Web Password**: Set via `WEBPASSWORD` environment variable +- **DNS Listening Mode**: Set to `ALL` to accept queries from all origins + +## Volumes + +- `./etc-pihole` - Pi-hole configuration +- `./etc-dnsmasq.d` - dnsmasq configuration +- `./tailscale-data` - Tailscale state diff --git a/unsorted/docker_compose_stacks/pihole-via-tailscale/docker-compose.yaml b/unsorted/docker_compose_stacks/pihole-via-tailscale/docker-compose.yaml new file mode 100644 index 0000000..f5a8070 --- /dev/null +++ b/unsorted/docker_compose_stacks/pihole-via-tailscale/docker-compose.yaml @@ -0,0 +1,30 @@ +services: + pihole: + image: pihole/pihole:2025.11.1 + network_mode: service:tailscale + environment: + TZ: "Europe/London" + WEBPASSWORD: "CHANGEME" + FTLCONF_dns_listeningMode: "ALL" + volumes: + - "./etc-pihole:/etc/pihole" + - "./etc-dnsmasq.d:/etc/dnsmasq.d" + restart: unless-stopped + cap_add: + - SYS_NICE + depends_on: + - tailscale + + tailscale: + image: tailscale/tailscale:v1.92.4 + hostname: pihole + environment: + - TS_AUTH_ONCE="true" + - TS_STATE_DIR=/var/lib/tailscale + volumes: + - ./tailscale-data:/var/lib/tailscale + - /dev/net/tun:/dev/net/tun + cap_add: + - NET_ADMIN + - NET_RAW + restart: unless-stopped diff --git a/unsorted/docker_compose_stacks/pihole/README.md b/unsorted/docker_compose_stacks/pihole/README.md new file mode 100644 index 0000000..e19a1a8 --- /dev/null +++ b/unsorted/docker_compose_stacks/pihole/README.md @@ -0,0 +1,89 @@ +# Pi-hole Docker Stack + +A Docker Compose configuration for running [Pi-hole](https://pi-hole.net/), a network-wide ad blocker that acts as a DNS sinkhole. + +## Features + +- DNS-based ad blocking for your entire network +- Web-based admin interface +- DHCP server capability +- NTP server for time synchronization + +## Exposed Ports + +| Port | Protocol | Service | +| ---- | -------- | --------------------- | +| 53 | TCP/UDP | DNS | +| 80 | TCP | HTTP (Web Interface) | +| 443 | TCP | HTTPS (Web Interface) | +| 67 | UDP | DHCP | +| 123 | UDP | NTP | + +## Configuration + +### Environment Variables + +| Variable | Description | Default | +| -------------------------------- | ---------------------------- | --------------- | +| `TZ` | Timezone | `Europe/London` | +| `FTLCONF_webserver_api_password` | Admin web interface password | `CHANGEME` | +| `FTLCONF_dns_listeningMode` | DNS listening mode | `ALL` | + +> ⚠️ **Important:** Change `FTLCONF_webserver_api_password` to a secure password before deployment. + +### Volumes + +- `./etc-pihole` - Pi-hole configuration files +- `./etc-dnsmasq.d` - dnsmasq configuration files + +### Capabilities + +The container requires the following Linux capabilities: + +- `NET_ADMIN` - Network administration (required for DHCP) +- `SYS_TIME` - System time modification (required for NTP) +- `SYS_NICE` - Process priority adjustment + +## Usage + +### Starting the Stack + +```bash +docker compose up -d +``` + +### Accessing the Web Interface + +Navigate to `http://<host-ip>/admin` and log in with the password set in `FTLCONF_webserver_api_password`. + +### Stopping the Stack + +```bash +docker compose down +``` + +### Viewing Logs + +```bash +docker compose logs -f pihole +``` + +## Network Configuration + +To use Pi-hole as your DNS server, configure your devices or router to use the host machine's IP address as the primary DNS server. + +### Option 1: Per-Device + +Set the DNS server on individual devices to point to the Pi-hole host IP. + +### Option 2: Router-Level + +Configure your router's DHCP settings to distribute the Pi-hole host IP as the DNS server to all clients. + +### Option 3: DHCP Server + +Disable DHCP on your router and let Pi-hole handle DHCP by configuring it through the web interface. + +## Image Version + +This stack uses Pi-hole version `2025.11.1`. diff --git a/unsorted/docker_compose_stacks/pihole/docker-compose.yaml b/unsorted/docker_compose_stacks/pihole/docker-compose.yaml new file mode 100644 index 0000000..f258ef4 --- /dev/null +++ b/unsorted/docker_compose_stacks/pihole/docker-compose.yaml @@ -0,0 +1,27 @@ +services: + pihole: + image: pihole/pihole:2025.11.1 + ports: + # DNS + - "53:53/tcp" + - "53:53/udp" + # HTTP + - "80:80/tcp" + # HTTPS + - "443:443/tcp" + # DHCP + - "67:67/udp" + # NTP + - "123:123/udp" + environment: + TZ: "Europe/London" + FTLCONF_webserver_api_password: "CHANGEME" + FTLCONF_dns_listeningMode: "ALL" + volumes: + - "./etc-pihole:/etc/pihole" + - "./etc-dnsmasq.d:/etc/dnsmasq.d" + cap_add: + - NET_ADMIN + - SYS_TIME + - SYS_NICE + restart: unless-stopped diff --git a/unsorted/docker_compose_stacks/sovereign-docker-compose-editor/README.md b/unsorted/docker_compose_stacks/sovereign-docker-compose-editor/README.md new file mode 100644 index 0000000..6f152b7 --- /dev/null +++ b/unsorted/docker_compose_stacks/sovereign-docker-compose-editor/README.md @@ -0,0 +1,99 @@ +# Sovereign Docker Compose Editor + +A secure, web-based code editor for managing Docker Compose files, accessible through Tailscale. + +## Overview + +This stack provides a code-server instance that allows you to edit Docker Compose files through a web interface. It's connected to Tailscale for secure remote access and has direct access to the host's Docker socket for managing containers. + +## Services + +### code-server + +- **Base Image**: `codercom/code-server:4.107.0-bookworm` +- **Purpose**: Web-based VS Code editor +- **Features**: + - Docker CLI installed for container management + - Password authentication + - Accessible via Tailscale network + +### tailscale + +- **Image**: `tailscale/tailscale:v1.92.4` +- **Purpose**: Secure network access via Tailscale VPN +- **Hostname**: `sovereign-docker-compose-editor` + +## Setup + +1. **Configure Password** + + Edit the `PASSWORD` environment variable in the `docker-compose.yaml`: + + ```yaml + environment: + - PASSWORD=your-secure-password-here + ``` + +2. **Tailscale Authentication** + + On first run, check the logs to get the Tailscale authentication URL: + + ```bash + docker compose logs tailscale + ``` + + Visit the URL to authenticate the device to your Tailscale network. + +3. **Start the Services** + ```bash + docker compose up -d + ``` + +## Access + +Once running and authenticated with Tailscale: + +- Access the editor at: `http://sovereign-docker-compose-editor` +- Login with the password you configured + +## Volumes + +- `./config` - code-server configuration and settings +- `/mnt/user/root/docker-compose/` - Project directory (editable Docker Compose files) +- `./tailscale-data` - Tailscale state and configuration +- `/var/run/docker.sock` - Host Docker socket for container management + +## Security Notes + +- The editor runs as root to access the Docker socket +- Access is restricted to your Tailscale network +- Change the default password immediately +- The Docker socket provides full control over host containers - use with caution + +## Managing Docker Containers + +With the Docker CLI installed and socket mounted, you can: + +- View running containers: `docker ps` +- Manage compose stacks: `docker compose up/down` +- View logs: `docker compose logs` +- All standard Docker commands are available + +## Customization + +### Change the Port + +The editor listens on port 80 within the Tailscale network. To change: + +```yaml +command: ["--bind-addr", "0.0.0.0:8080", "--auth", "password"] +``` + +### Change Project Directory + +Update the volume mount to point to your Docker Compose files: + +```yaml +volumes: + - /your/compose/files:/home/coder/project +``` diff --git a/unsorted/docker_compose_stacks/sovereign-docker-compose-editor/docker-compose.yaml b/unsorted/docker_compose_stacks/sovereign-docker-compose-editor/docker-compose.yaml new file mode 100644 index 0000000..8dd20c1 --- /dev/null +++ b/unsorted/docker_compose_stacks/sovereign-docker-compose-editor/docker-compose.yaml @@ -0,0 +1,41 @@ +services: + code-server: + build: + context: . + dockerfile_inline: | + FROM codercom/code-server:4.107.0-bookworm + + # Switch to root to install packages + USER root + + # Install Docker CLI + RUN curl https://get.docker.com | sh + + # Switch back to the default user + USER coder + + network_mode: service:tailscale + environment: + - PASSWORD=CHANGEME + volumes: + - ./config:/home/coder/.local/share/code-server + - /mnt/user/root/docker-compose/:/home/coder/project + # Mount the Host Docker Socket + - /var/run/docker.sock:/var/run/docker.sock + restart: unless-stopped + command: ["--bind-addr", "0.0.0.0:80", "--auth", "password"] + user: root + + tailscale: + image: tailscale/tailscale:v1.92.4 + hostname: sovereign-docker-compose-editor + environment: + - TS_AUTH_ONCE="true" + - TS_STATE_DIR=/var/lib/tailscale + volumes: + - ./tailscale-data:/var/lib/tailscale + - /dev/net/tun:/dev/net/tun + cap_add: + - NET_ADMIN + - NET_RAW + restart: unless-stopped diff --git a/unsorted/resume.md b/unsorted/resume.md new file mode 100644 index 0000000..39ca48f --- /dev/null +++ b/unsorted/resume.md @@ -0,0 +1,110 @@ +# zuedev's Resume + +Results-oriented Software Engineer and Solutions Architect with over 14 years’ experience designing and implementing scalable and redundant system architecture. + +## Personal Information + +- **Full Name:** Alexander James Pooley +- **Location:** Harwich, Essex, United Kingdom +- **Email:** alex@zue.dev +- **Phone:** +44 7 943 941 456 +- **Website:** [zue.dev](https://zue.dev) + +### Socials + +- **GitHub:** [github.com/zuedev](https://github.com/zuedev) +- **LinkedIn:** [linkedin.com/in/zuedev](https://linkedin.com/in/zuedev) +- **Twitter/X:** [x.com/zuedev](https://x.com/zuedev) +- **ORCID:** [orcid.org/0009-0006-6460-8957](https://orcid.org/0009-0006-6460-8957) + +## Summary + +Enthusiastic and accomplished leader of distributed, cross-functional development teams, with over a decade of experience delivering world-class technical solutions that impact millions of users. My background in engineering highly scalable and redundant systems powers my ability to lead efficient cross-domain teams, even remotely. I thrive in challenging, fast-paced environments and am always committed to providing quality work. Core strengths include leadership, technical acumen, a drive for impactful solutions, and a genuine passion for gaming that informs my understanding of user needs and market trends. + +## Career Experience + +### Director of Engineering, [Unnamed Group](https://unnamed.group/) + +- **Period:** December 2022 - Present +- **Location:** Harwich, Essex, United Kingdom + +As the Director of Engineering at Unnamed Group, I am dedicated to fostering an active and inclusive gaming community while spreading the joy of gaming. Our organization hosts regular streaming events to promote and fundraise for the charity SpecialEffect, which empowers physically disabled individuals to enjoy video games. + +### Solutions Architect, [November Games](https://novembergames.com/) + +- **Period:** February 2022 - December 2022 +- **Location:** Wellington, New Zealand + +As the principle backend lead, I designed, deployed and maintained a globally scalable game server and API infrastructure to support the first-ever play-to-partner game in partnership with Twitch. Overall, my solutions architecture expertise enabled the successful delivery of a complex project with a tight timeline, delivering an unparalleled user experience for the gaming community. + +### Technical Account Manager, [Linguascope](https://www.linguascope.com/) + +- **Period:** January 2019 - February 2022 +- **Location:** Colchester, Essex, United Kingdom + +### Lead DevOps Engineer, [CoreSciences](https://www.coresciences.co.uk/) + +- **Period:** November 2018 - October 2021 +- **Location:** Colchester, Essex, United Kingdom + +### Solutions Architect, [CORE Data Systems](https://www.coredatasystems.co.uk/) + +- **Period:** March 2018 - February 2022 +- **Location:** Colchester, Essex, United Kingdom + +I was the lead developer for a fluctuating team of 5-10 developers. My responsibilities included organizing the team’s efforts to ensure high rates of productivity and maintaining a low technical debt. I also held the responsibility for the uptime of applications by incorporating modern technologies, such as continuous integration pipelines, Kubernetes deployment manifests, app health checks, complicated cluster charts, and more. + +### Site Reliability Engineer, [World Anvil](https://worldanvil.com/) + +- **Period:** December 2017 - February 2023 +- **Location:** London, United Kingdom + +I provided technical consultation for both the infrastructure and automation elements of the project. My hands-on approach to resolving issues allowed me to practice using first-response measures for maintaining site reliability as well as how to plan and implement long-term solutions for scaling and distribution. I also worked on the mobile app built with React Native and Expo for both iOS and Android platforms. + +### Full Stack Developer, [Aspen Woolf](https://aspenwoolf.co.uk/) + +- **Period:** April 2017 - March 2018 +- **Location:** Colchester, Essex, United Kingdom + +As the sole web developer working cooperatively with the SEO company BayCat, I thrived under the challenge of honing my ability to deliver high-quality work in a fast-paced, highly bureaucratic environment. I developed a deep understanding of the critical factors required to ensure flawless performance, balancing the needs of both users and decision-makers. + +### Full Stack Developer, [Baycat Digital](https://www.baycat.co.uk/) + +- **Period:** March 2017 - March 2018 +- **Location:** Colchester, Essex, United Kingdom + +I primarily worked with BayCat as a white-label provider for hosting and WordPress development services, the former utilizing a combination of Kubernetes and Load-Balancers to achieve high availability across a CDN-backed infrastructure. I also provided support for the development of WordPress sites, including the creation of custom plugins and themes, as well as troubleshooting and resolving technical issues. + +### Backend Engineer, [World Registration Systems](https://find-and-update.company-information.service.gov.uk/company/06370780) + +- **Period:** November 2016 - April 2017 +- **Location:** London, United Kingdom + +Primarily working with PHP and MySQL, I gained valuable experience working with a much older codebase which was over 8 years old. This was also my first experience providing professional hosting services, which was built upon Ubuntu VMs. + +### Junior Web Developer, [Peccy Networks](https://web.archive.org/web/20160305203701/http://peccy.net/) + +- **Period:** July 2014 - November 2016 +- **Location:** Colchester, Essex, United Kingdom + +I was responsible for the development and maintenance of the company’s website, which was built using WordPress. I also provided support for the company’s clients, which included troubleshooting technical issues and providing solutions to improve their online presence. + +## Volunteer Experience + +### Coronavirus Toolkit + +- **Period:** March 2020 - July 2021 +- **Location:** London, United Kingdom + +Oversaw the development of a free, evidence-based toolkit to combat COVID-19 and promote vaccinations, which reached a global audience. Spearheaded the development team, ensuring timely and efficient delivery of features, while designing and building a user-friendly application with a focus on accessibility and scalability. By leading the development of this toolkit, I demonstrated my ability to manage complex projects and collaborate with stakeholders to achieve a common goal. Additionally, my technical expertise in designing user-friendly and scalable applications, implementing robust security measures, and maintaining high code quality contributed to the overall success of the project. + +## Certifications + +- [**Responsive Web Design**](https://www.freecodecamp.org/certification/zuedev/responsive-web-design) by [freeCodeCamp](https://www.freecodecamp.org/) (28th of June, 2024) +- [**JavaScript Algorithms and Data Structures**](https://www.freecodecamp.org/certification/zuedev/javascript-algorithms-and-data-structures-v8) by [freeCodeCamp](https://www.freecodecamp.org/) (28th of June, 2024) +- [**Scientific Computing with Python**](https://www.freecodecamp.org/certification/zuedev/scientific-computing-with-python-v7) by [freeCodeCamp](https://www.freecodecamp.org/) (28th of June, 2024) +- [**Data Visualization**](https://www.freecodecamp.org/certification/zuedev/data-visualization) by [freeCodeCamp](https://www.freecodecamp.org/) (2nd of July, 2024) +- [**Manage Kubernetes in Google Cloud**](https://www.credly.com/badges/c5c9fd85-290b-4002-bd2d-9b4f66bdec9b/public_url) by [Google](https://google.com/training/certifications/manage-kubernetes-engine/) (5th of March, 2026) +- [**Secure Software Delivery**](https://www.credly.com/badges/90f1cd04-ae67-40f5-9afa-f42233de519b/public_url) by [Google](https://google.com/training/certifications/manage-kubernetes-engine/) (5th of March, 2026) +- [**Analyze Images with the Cloud Vision API**](https://www.credly.com/badges/41396cd5-38e0-4931-afc2-6e54843a8a01/public_url) by [Google](https://google.com/training/certifications/manage-kubernetes-engine/) (5th of March, 2026) +- [**Develop GenAI Apps with Gemini and Streamlit**](https://www.credly.com/badges/47480e9e-ca61-4ea6-a96a-a858aa7b7342/public_url) by [Google](https://google.com/training/certifications/manage-kubernetes-engine/) (6th of March, 2026) |
