Skip to content
View AC-DAC's full-sized avatar
🎯
Focusing
🎯
Focusing

Block or report AC-DAC

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
AC-DAC/README.md

Hey, I'm Alex πŸ‘‹

Digital Producer with 14+ years in multimedia and design, transitioning into DevOps engineering. I bring systems thinking from a production background, understanding how things are built, delivered, and maintained, and I'm applying that to infrastructure, automation, and deployment pipelines.

I started in graphic design where details matter because someone experiences them. Then spent a decade as a Digital Producer, translating between human experience and technical execution. DevOps was the natural next step. It's the same translation problem, just at the infrastructure layer instead of the interface layer.

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚         ABSTRACTION         β”‚
    β”‚   patterns Β· systems Β·      β”‚
    β”‚   architecture Β· strategy   β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚           BRIDGE            β”‚
    β”‚   translation Β· context Β·   β”‚
    β”‚   documentation Β· empathy   β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚           DETAIL            β”‚
    β”‚   precision Β· execution Β·   β”‚
    β”‚   implementation Β· craft    β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   └──────────────────────────────┐
                                                  β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚
    β”‚         ABSTRACTION         β”‚β—„β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    β”‚   informed by detail Β·      β”‚
    β”‚   grounded Β· accurate       β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

What I'm Working On

Live Translator β€” a mobile web app for real-time Korean speech-to-English translation, built for live video calls with Korean-speaking family. Most translation apps (Google Translate, Papago, Microsoft Translator) stop transcribing on silence, which breaks natural conversation with a speaker who pauses mid-sentence. This captures continuously and only stops when explicitly told to.

The interesting constraint: the target phone runs GrapheneOS, which blocks Google Play Services β€” so the browser-native Web Speech API (which depends on Google's speech recognition) simply doesn't work there. That ruled out the obvious approach and pushed the whole STT/translation layer off-device onto edge compute instead.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Pi (self-hosted)                β”‚
β”‚  nginx β€” static hosting          β”‚
β”‚  serves React build only         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ 1. loads app
             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Phone (any browser)             β”‚
β”‚  React SPA                       β”‚
β”‚  MediaRecorder API               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ 2. audio chunks
             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Cloudflare Workers AI           β”‚
β”‚  Whisper β†’ Korean STT            β”‚
β”‚  Llama 3.1 β†’ English translation β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Audio capture via MediaRecorder API (works in any browser, no Google services required), streamed to Cloudflare Workers AI: Whisper handles Korean STT, Llama 3.1 8B handles translation with a rolling context window for coherence across sentences. Self-hosted on the same Raspberry Pi running the rest of the home lab β€” nginx serves the static build only, no backend proxy needed since the browser talks to Workers AI directly. Security layered across Cloudflare Access (email-allowlisted PIN gate on the subdomain), the Workers AI API key living only in the Worker's environment, and nginx rate limiting as a backstop.

React Cloudflare Workers AI Whisper Llama 3.1 nginx systemd Let's Encrypt Cloudflare


Projects

Privacy-first workout tracking app for Android. No ads, no account required, all data stored on-device. Features custom workout creation, guided session mode, stats and insights, reminders, and QR code workout sharing. Built in React Native / Expo with a custom Material Design-inspired design system. Currently in closed testing on the Google Play Store.

CI/CD pipeline: GitHub Actions test β†’ build β†’ submit on version tag push. Jest unit test suite. EAS Build produces AAB artifact; EAS Submit delivers to Play Store internal track via Google Service Account (least-privilege permissions). Actions pinned to immutable commit SHAs with permissions: contents: read at workflow level. Lefthook + gitleaks for pre-commit secret scanning.

React Native Expo GitHub Actions EAS Build Jest Android


WordPress plugin built at Ironbark Marketing that generates a branded link directory page at yourdomain.com/quicklinks/. Customisable profile image, background and button colours, drag-and-drop link reordering. CI/CD pipeline via GitHub Actions: PHPCS validation enforcing WordPress Coding Standards, zip packaging, and automated GitHub Releases on version tag push.

WordPress PHP GitHub Actions PHPCS


Self-hosted centralised management dashboard for over 15 production WordPress client sites, built on MainWP and deployed to a dedicated subdomain. Replaces a manual, site-by-site update workflow with a single control plane covering bulk updates, uptime monitoring, and security visibility across all managed sites.

Key implementation decisions: real server-level cron over WP-Cron (unreliable on a low-traffic dashboard-only subdomain); per-site OpenSSL key pairs with Unique Security IDs replacing password authentication; maintenance mode for frontend obscurity after directory password protection was evaluated and rejected (intercepts WordPress core HTTP requests). Backup strategy layered across UpdraftPlus per-site (weekly) and VentraIP server-level hourly snapshots.

Mothership Dashboard

MainWP WordPress Apache MariaDB Linux Cron


Self-hosted NAS on a Raspberry Pi 4B, replacing an end-of-life Netgear ReadyNAS. Two 1TB NVMe SSDs in a software RAID 1 array via mdadm, served through FileBrowser Quantum over the local network. Daily incremental backup of selected folders from connected devices via rsync over SSH, managed by anacron.

Key implementation decisions: OMV rejected to avoid conflicts with existing Pi services; Time Machine rejected (all-or-nothing system backup); cron replaced with anacron for missed-run tolerance; FileBrowser original replaced with Quantum fork after diagnosing a routing bug in v2.63.4; powered USB hub added after diagnosing Pi 4B USB power budget limitation via dmesg. CVE patched same session as release.

Monitoring stack: Node Exporter on the Pi, Prometheus + Grafana on a separate host. Custom textfile collector metrics for backup job success (backup_last_success) and RAID array health (raid_health). Alert rules fire to email on backup failure or array degradation.

External access via Cloudflare Tunnel β€” replaces port forwarding after ISP change blocked inbound ports on residential plan. Pi static IP configured via systemd-networkd for stability across router reboots.

Pi Monitor Dashboard

mdadm ext4 rsync anacron systemd Linux SSH Prometheus Grafana Node Exporter Cloudflare Tunnel


Network-wide DNS-based ad/tracker filtering for the home lab, deployed on the same Raspberry Pi 4B already running Pi NAS and Aersia. No application code in this repo β€” the deliverable is the architecture, the security review process, and two debugging case studies, written up as a standalone documentation repo rather than a thing to clone and run.

Key implementation decisions: four-category security review applied to the install script before execution (external fetches, obfuscation, excessive permissions, rogue persistence) rather than trusting curl | bash on faith; failure-domain analysis rejecting a second Pi-hole as DNS2 fallback since it would share the same host/power/storage as the primary; DNS-01 (not HTTP-01) certificate challenge for an intentionally internet-unreachable admin subdomain. Diagnosed and resolved a live incident where a port-binding conflict silently broke an unrelated service's IPv6 traffic, and separately ruled out a false alarm that looked like a filtering failure but traced to an unrelated browser privacy setting.

  LAN device ──▢ Filtering host ──▢ Matches blocklist?
                                       β”‚             β”‚
                                      yes            no
                                       β”‚             β”‚
                                       β–Ό             β–Ό
                              0.0.0.0 / NXDOMAIN   Forward to
                              (blocked locally)     upstream resolver

Linux DNS Nginx systemd Let's Encrypt Security Review Raspberry Pi


Self-hosted video game music player running on a Raspberry Pi 4B. Forked and significantly extended from an upstream HTML5 player: migrated playlist parsing from XML to JSON (vipvgm.net API), added sequential playback mode, Source playlist with CDN fallback logic, and Omni playlist (client-side merge of VIP, Mellow, and Exiled sorted A-Z). Full localStorage persistence across sessions with sequential position restoration fix.

Infrastructure: Nginx, Let's Encrypt TLS (DNS-01 challenge via Cloudflare plugin), Cloudflare Tunnel for external access (replaces dynamic DNS + port forwarding), CORS resolved via local Pi proxy serving roster files refreshed weekly by cron.

Aersia VIP Player

Nginx Let's Encrypt Cloudflare Cloudflare Tunnel Bash Linux Cron


Native Android companion app to the self-hosted web player, built as a fork of VidyaMusic by MateusRodCosta. The web player originally shipped a PWA for mobile use, but background audio proved unreliable on Android due to OS power management β€” a native app was the correct solution.

Extended from upstream to achieve full playlist parity with the web player: XML/XSPF roster support for WAP and CPP playlists, Source playlist with source-file filtering, and Omni (concurrent fetch of all six playlists, merged and sorted A-Z). Per-playlist position memory with atomic snapshot persistence, shuffle state persistence, and Bluetooth auto-launch notification support.

CI/CD pipeline: GitHub Actions assembleDebug on version tag push, APK attached to GitHub Release. Actions pinned to immutable commit SHAs. Licensed AGPLv3.

Kotlin Jetpack Compose Media3 GitHub Actions Gradle Android


Technologies

Infrastructure & DevOps Linux Β· Nginx Β· Docker Β· Docker Compose Β· GitHub Actions Β· Bash Β· Cron Β· Anacron Β· UFW Β· SSH Β· mdadm Β· ext4 Β· rsync Β· systemd Β· DNS Β· Cloudflare Β· Cloudflare Tunnel Β· Cloudflare Workers AI Β· Let's Encrypt Β· Certbot Β· EAS CLI Β· Prometheus Β· Grafana Β· Node Exporter Β· Ansible

Cloud AWS Β· IAM Β· VPC Β· EC2 Β· S3 Β· RDS Β· Lambda Β· API Gateway Β· AWS CLI Β· Secrets Manager Β· Terraform

Development React Native Β· Expo Β· React Β· Kotlin Β· JavaScript Β· PHP Β· HTML Β· CSS

Tools Git Β· Jest Β· Lefthook Β· EAS Build Β· PHPCS Β· Composer Β· gitleaks Β· VS Code


Background

Before pivoting to DevOps I spent 6+ years as a Digital Producer at Ironbark Marketing, spanning UI/UX design, front-end development, WordPress plugin development, and multimedia production. That background shapes how I approach infrastructure: documentation, system design, and the gap between what developers build and what operations teams maintain.


Connect

LinkedIn

Pinned Loading

  1. FitForge-Public FitForge-Public Public

    Privacy-first workout tracking app for Android. Built with React Native, Expo, and EAS.

  2. Quicklinks-Public Quicklinks-Public Public

    A WordPress plugin that creates a dedicated landing page for sharing shortcut links on your website.

  3. Mothership-Public Mothership-Public Public

    Mothership is a self-hosted, centralised management dashboard for over 15 WordPress client sites, built on MainWP and deployed to a dedicated subdomain on shared hosting.

  4. pi-nas pi-nas Public

    Self-hosted NAS on a Raspberry Pi 4B β€” mdadm RAID 1, FileBrowser Quantum, rsync backup, Cloudflare Tunnel

  5. aersia-vip-player-self-hosted-fork aersia-vip-player-self-hosted-fork Public

    Self-hosted music player running on a Raspberry Pi 4B.

    HTML

  6. aersia-vip-player-android aersia-vip-player-android Public

    Native Android companion app to the self-hosted web player

    Kotlin