Skip to main content
Advanced Search
Search Terms
Content Type

Exact Matches
Tag Searches
Date Options
Updated after
Updated before
Created after
Created before

Search Results

228 total results found

Three databases, on purpose

Data & Observability

The platform runs three relational databases — PostgreSQL (10.100.100.13), MariaDB (10.100.100.14), and MySQL (10.100.100.15) — each on its own VM, each on local disk, not on the cluster's NFS. Why three? Because real applications disagree about what they want...

Tuning a database for the hardware it has

Data & Observability

A freshly installed database ships with cautious, generic defaults. On a box you've sized deliberately (4 vCPU, 4 GiB RAM, SSD-backed disk), a little tuning goes a long way. The themes are the same across all three engines: Let it use the RAM. Tell the engine...

Every app gets its own credentials

Data & Observability

This is a hard rule in the lab: no application ever connects as the database admin. Each app gets its own database, its own user, and its own password, scoped to just that database. # for an app 'foo', on PostgreSQL: CREATE DATABASE foo; CREATE USER foo WITH P...

Seeing what the cluster is doing: logs to Loki

Data & Observability

The lab already had a central log store (Loki — see its book in Core Infrastructure), with a Promtail agent on every VM shipping system logs. When the cluster arrived, the job was to feed its logs in too. On the Kubernetes nodes the node-level Promtail agent w...

Lessons on data and observability

Data & Observability

Match storage to the workload: databases get local disk on dedicated VMs, never NFS. Tune for the box you have: give the engine the RAM, tell it the disk is SSD, log slow queries. MariaDB ≠ MySQL: running both proved it. Check settings against your actual eng...

The front door

Edge Networking with pfSense

Everything that's reachable from the outside world passes through one VM: a pfSense firewall/router (10.100.100.1 inside, a public IP outside). It wears three hats: Router/NAT — gives the private 10.100.100.0/24 VMs a way out to the internet, and is the defau...

NAT: how private VMs reach the world

Edge Networking with pfSense

The VMs live on a private range that isn't routable on the internet. They still need to fetch packages, pull container images, and so on. pfSense handles that with outbound NAT: as a VM's traffic leaves for the internet, pfSense rewrites the source to its own ...

HAProxy: one door, many rooms

Edge Networking with pfSense

All the web services share a single public IP, so something has to look at each incoming request and send it to the right backend. That's HAProxy, running on pfSense, routing by hostname: https://git.example.com -> GIT-Server 10.100.100.2:3000 htt...

TLS terminates here, once

Edge Networking with pfSense

There is exactly one place in the whole lab that deals with certificates: HAProxy on pfSense. It holds a wildcard certificate for *.example.com and terminates TLS for every service. Behind it, traffic to the backends is plain HTTP on the trusted private networ...

A gotcha that cost an afternoon

Edge Networking with pfSense

A war story, because the lessons that stick are the ones that bit you. A backend's address was changed in the HAProxy GUI, Apply was clicked, and… HAProxy kept sending traffic to the old port. The config on disk said one thing; the running proxy did another. B...

Why a jump host

The SSH Bastion (Jump Host)

None of the internal VMs accept SSH from the internet. There's exactly one machine you can SSH to from outside — the jump host (or bastion) at 10.100.100.254, which also holds a public address. From there, you hop to anything internal. you --SSH--> Jump host...

The ProxyJump pattern

The SSH Bastion (Jump Host)

You don't want to manually SSH to the bastion and then SSH again — that's clumsy and breaks tooling. SSH has a built-in feature for exactly this: ProxyJump (and its lower-level cousin, ProxyCommand). It transparently tunnels your connection to the internal hos...

Hardening, and a host-key surprise

The SSH Bastion (Jump Host)

Because the bastion is the one publicly-reachable SSH endpoint, it's the one that gets the most attention: keep it patched, restrict who can log in, prefer keys, watch its auth logs (they ship to the central log store like everything else). A surprise worth wr...

Lessons on bastion access

The SSH Bastion (Jump Host)

One way in. Internal VMs expose no SSH to the internet; the bastion is the single public SSH endpoint. ProxyJump makes it painless. Bastion-only access with none of the two-hop hassle — tooling included. Harden the one box hard. It's the door everyone uses; p...

Why golden images

Golden-Image VM Provisioning

There are ~15 VMs in this lab. Not one of them was installed from an ISO by hand. Every single one is a clone of a single golden image — one carefully prepared template — customised at first boot by cloud-init. The alternative (install Ubuntu by hand, fifteen ...

The template

Golden-Image VM Provisioning

The template is one VM (ID 9999) prepared once: a current Ubuntu cloud image, the QEMU guest agent, the logging agent, sensible defaults — and then turned into a Proxmox template so it can only be cloned, not run directly. A few things are deliberately baked i...

Injecting per-VM identity with cloud-init

Golden-Image VM Provisioning

Cloning gives you fifteen identical machines. Cloud-init is what makes each one itself on first boot — its hostname, its IP, its login. The flow for creating a VM here is a small, repeatable recipe: 1. clone the template (9999) -> new VM with the next free I...

Grow-on-first-boot, and a clean teardown

Golden-Image VM Provisioning

Two finishing touches make the recipe pleasant to live with. Disks grow to fit. The template's disk is small. When you clone and resize the new VM's disk to, say, 250 GiB, cloud-init's growpart/resize on first boot expands the filesystem to fill it automatical...