78 lines
10 KiB
JSON
78 lines
10 KiB
JSON
[
|
|
{
|
|
"id": 1,
|
|
"title": "Building a Self-Hosted Empire",
|
|
"slug": "self-hosted-empire",
|
|
"date": "2026-03-28",
|
|
"excerpt": "How I ditched big tech and built my own infrastructure from the ground up. Gitea, Plex, search engines — all on one box.",
|
|
"content": "## The Breaking Point\n\nThere comes a moment in every developer's life when you look at your Google Drive, your Gmail, your hosted repos on GitHub, and you think: *why am I handing all of this to someone else?* For me, that moment came at 2 AM on a Tuesday, staring at a Terms of Service update email that basically said 'we own your soul now.'\n\nSo I did what any rational person would do. I bought a VPS and started building.\n\n## The Stack\n\nThe foundation is a Debian box sitting in a data centre somewhere in Europe. On top of that:\n\n- **Gitea** for git hosting — lightweight, fast, and mine\n- **Plex** for media — because why pay for streaming when you have a 2TB drive\n- **Nginx** as the reverse proxy tying it all together\n- **Docker** containers for everything that can be containerised\n- **WireGuard** for secure remote access\n\nThe whole thing runs on 4GB of RAM and barely breaks a sweat.\n\n## The Hard Parts\n\nDNS was a nightmare at first. Getting wildcard SSL certs with Let's Encrypt took three attempts and a lot of swearing. Docker networking still makes me want to throw my laptop out the window sometimes.\n\nBut the worst part? Email. Self-hosted email is a rabbit hole I'm still climbing out of. Every major provider treats your IP as spam by default. You need SPF, DKIM, DMARC, a reverse DNS entry, and probably a blood sacrifice to get Gmail to accept your messages.\n\n## Was It Worth It?\n\nAbsolutely. I own my data. I control my infrastructure. When a service goes down, it's my fault and I can fix it. There's something deeply satisfying about `ssh root@mybox` and knowing that everything running on that machine is mine.\n\nThe total cost? About £8 a month for the VPS. That's less than a single streaming subscription.\n\n## What's Next\n\nI'm looking at adding a self-hosted AI inference server, a personal search engine, and maybe a Matrix server for comms. The empire keeps growing.",
|
|
"tags": ["self-hosted", "infrastructure", "linux", "docker"],
|
|
"mood": 4,
|
|
"energy": 5,
|
|
"motivation": 5,
|
|
"heart_rate": 82,
|
|
"threat_level": "LOW",
|
|
"coffee": 3,
|
|
"focus": 4,
|
|
"difficulty": 3,
|
|
"time_written": "02:34 AM",
|
|
"word_count": 347
|
|
},
|
|
{
|
|
"id": 2,
|
|
"title": "Securing the Perimeter: VPS Hardening 101",
|
|
"slug": "vps-hardening-101",
|
|
"date": "2026-03-25",
|
|
"excerpt": "Your fresh VPS is a sitting duck. Here's how I lock mine down — SSH keys, fail2ban, firewalls, and a healthy dose of paranoia.",
|
|
"content": "## You Just Deployed a Server. You're Already Under Attack.\n\nI'm not being dramatic. Within five minutes of spinning up a fresh VPS, check your auth logs. You'll see hundreds of brute-force SSH attempts from IPs all over the world. Bots are scanning every IP range constantly, looking for default credentials and open ports.\n\nWelcome to the internet.\n\n## Step 1: SSH Hardening\n\nFirst thing, always:\n\n```bash\n# Generate a key pair on your local machine\nssh-keygen -t ed25519 -C \"your@email.com\"\n\n# Copy it to the server\nssh-copy-id root@your-server\n\n# Then disable password auth\nsed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config\nsystemctl restart sshd\n```\n\nChange the default SSH port while you're at it. Security through obscurity isn't real security, but it cuts the noise in your logs by 95%.\n\n## Step 2: Firewall\n\nUFW is your friend:\n\n```bash\nufw default deny incoming\nufw default allow outgoing\nufw allow 2222/tcp # your SSH port\nufw allow 80/tcp\nufw allow 443/tcp\nufw enable\n```\n\nThat's it. Everything else gets dropped.\n\n## Step 3: Fail2Ban\n\nFail2ban watches your logs and auto-bans IPs that fail authentication too many times. Install it, configure it for SSH, and forget about it. It'll do its job quietly in the background.\n\n## Step 4: Unattended Upgrades\n\nSecurity patches should install themselves. You shouldn't need to remember to run `apt update` every day:\n\n```bash\napt install unattended-upgrades\ndpkg-reconfigure unattended-upgrades\n```\n\n## Step 5: The Paranoia Layer\n\n- Disable root login over SSH (use a regular user + sudo)\n- Set up 2FA with Google Authenticator PAM module\n- Monitor with Netdata or similar\n- Regular `lynis audit system` scans\n- Keep backups. Always keep backups.\n\n## The Mindset\n\nSecurity isn't a destination, it's a process. You're never 'done' securing a server. New vulnerabilities drop daily. The trick is making your box harder to crack than the next one. Attackers are lazy — they'll move on to easier targets.",
|
|
"tags": ["security", "linux", "sysadmin", "hardening"],
|
|
"mood": 3,
|
|
"energy": 4,
|
|
"motivation": 5,
|
|
"heart_rate": 91,
|
|
"threat_level": "HIGH",
|
|
"coffee": 4,
|
|
"focus": 5,
|
|
"difficulty": 4,
|
|
"time_written": "11:47 PM",
|
|
"word_count": 312
|
|
},
|
|
{
|
|
"id": 3,
|
|
"title": "AI Agents at 3AM: Building Agent Zero",
|
|
"slug": "ai-agents-3am",
|
|
"date": "2026-03-20",
|
|
"excerpt": "What happens when you give an AI root access to your server and tell it to build things? Chaos, learning, and surprisingly good code.",
|
|
"content": "## The Rabbit Hole\n\nIt started with a simple question: what if an AI could actually *do* things on my server, not just talk about doing them?\n\nI'd been messing around with LLMs for months — ChatGPT, Claude, local models on my GPU. They're brilliant at explaining things and writing snippets, but there's always that gap between 'here's the code' and 'it's actually running.' You still have to copy, paste, debug, fix the hallucinated import, debug again.\n\nThen I found Agent Zero.\n\n## What Is It?\n\nAgent Zero is an AI agent framework. You give it access to a terminal, a browser, memory, and tools. Then you tell it what you want. It figures out the steps, writes the code, runs it, checks the output, and iterates until it works.\n\nThe first time I watched it SSH into my VPS, install nginx, write a config file, test it, and reload the service — all without me touching the keyboard — I felt something between excitement and genuine unease.\n\n## The Good\n\n- It handles complex multi-step tasks that would take me an hour of googling\n- It remembers previous solutions and applies them to new problems\n- It can debug its own mistakes (most of the time)\n- It never gets frustrated at 3 AM\n\n## The Bad\n\n- It sometimes gets stuck in loops, trying the same failing approach repeatedly\n- Token costs add up fast on complex tasks\n- You need to be specific — vague instructions produce vague results\n- It occasionally decides to 'improve' things you didn't ask it to touch\n\n## The Philosophy\n\nThere's a real debate about whether giving AI tools like these is a good idea. I get it. But here's my take: these tools exist. They're getting better. The question isn't whether people will use them, it's whether you'll understand how they work when they become mainstream.\n\nI'd rather be the person who built with the early versions than the person trying to catch up later.\n\n## Current Setup\n\nMy Agent Zero instance runs in Docker on the VPS. It has access to the terminal, can browse the web, and maintains long-term memory. I use it for everything from server maintenance to building websites.\n\nYes, including this one.",
|
|
"tags": ["ai", "agent-zero", "automation", "development"],
|
|
"mood": 5,
|
|
"energy": 3,
|
|
"motivation": 4,
|
|
"heart_rate": 76,
|
|
"threat_level": "MED",
|
|
"coffee": 5,
|
|
"focus": 3,
|
|
"difficulty": 4,
|
|
"time_written": "03:22 AM",
|
|
"word_count": 340
|
|
},
|
|
{
|
|
"id": 4,
|
|
"title": "The 4AM Deploy: When Everything Goes Wrong",
|
|
"slug": "4am-deploy",
|
|
"date": "2026-03-15",
|
|
"excerpt": "A war story about a production deploy that went sideways, the frantic debugging that followed, and what I learned from nuking my own DNS.",
|
|
"content": "## It Was Supposed To Be Quick\n\nFamous last words. All I wanted to do was update the nginx config to add a new subdomain. Five minutes, tops. I'd done it a hundred times before.\n\n```bash\nnginx -t && systemctl reload nginx\n```\n\nExcept this time, `nginx -t` returned an error I'd never seen. Something about a duplicate server name. I'd accidentally created a circular include that referenced itself through a symlink.\n\n## The Cascade\n\nIn my sleep-deprived wisdom, I decided to 'fix' it by removing what I thought was the duplicate config file. Turns out, that was the main config for jaeswift.xyz. Not the duplicate. The main one.\n\nNginx went down. All services went dark. Git, Plex, the docs site, everything. At 4 AM.\n\n## The Panic\n\nMy phone started buzzing. Uptime monitors screaming. I tried to restore from the backup. The backup was three days old because I'd been meaning to set up daily snapshots but hadn't got round to it.\n\nThree days of config changes, gone.\n\n## The Recovery\n\nI spent the next two hours reconstructing the nginx config from memory and bash history. `history | grep nginx` became my best friend. I found most of the server blocks in various terminal scrollback sessions.\n\nBy 6 AM, everything was back online. Mostly. The Plex config took another day to get right because I'd customised the proxy headers and couldn't remember the exact settings.\n\n## The Lessons\n\n1. **Backup your configs to git.** Not tomorrow. Now.\n2. **Never deploy after midnight.** Your brain is lying to you about how awake you are.\n3. **Test in staging.** I know, I know. But actually do it.\n4. **Document everything.** Past-you is the best resource for future-you, but only if past-you wrote things down.\n5. **Set up automated backups.** I now have hourly snapshots of all critical configs.\n\n## Silver Lining\n\nThe reconstructed config was actually cleaner than the original. Sometimes you need to burn it down to build it better.\n\nBut maybe not at 4 AM.",
|
|
"tags": ["devops", "war-story", "nginx", "lessons"],
|
|
"mood": 2,
|
|
"energy": 1,
|
|
"motivation": 2,
|
|
"heart_rate": 112,
|
|
"threat_level": "CRITICAL",
|
|
"coffee": 5,
|
|
"focus": 2,
|
|
"difficulty": 5,
|
|
"time_written": "04:13 AM",
|
|
"word_count": 338
|
|
}
|
|
]
|