<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><title>Starlab blog</title><link>https://starlab.io.vn/blog/</link><description>Scripts, Go services and handbooks for running a small app on one VPS: deploys that drop no requests, backups you can restore, a Go webhook receiver.</description><language>en</language>
<item><title>Zero-downtime deploys on one VPS with Caddy and pm2</title><link>https://starlab.io.vn/blog/zero-downtime-deploys-one-vps/</link><guid>https://starlab.io.vn/blog/zero-downtime-deploys-one-vps/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>Run two copies of a Node app on two ports, health-check the new one, then switch Caddy to it. Commands, the pm2 symlink trap, and measured failed requests.</description></item>
<item><title>How to write a restore runbook you can follow at 3 a.m.</title><link>https://starlab.io.vn/blog/write-a-restore-runbook/</link><guid>https://starlab.io.vn/blog/write-a-restore-runbook/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Backups and recovery</category><description>A fill-in restore runbook template for one VPS covering who does what, the order of steps, RTO and RPO in plain words, and how to drill it until it works.</description></item>
<item><title>Webhook signature checks that fail or quietly pass in Go</title><link>https://starlab.io.vn/blog/webhook-signature-pitfalls/</link><guid>https://starlab.io.vn/blog/webhook-signature-pitfalls/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Webhooks</category><description>Avoid the mistakes that break or weaken webhook signature checks in Go, and see how GitHub, Stripe and Standard Webhooks differ in practice.</description></item>
<item><title>A durable webhook retry queue in SQLite</title><link>https://starlab.io.vn/blog/webhook-retry-queue-sqlite/</link><guid>https://starlab.io.vn/blog/webhook-retry-queue-sqlite/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Webhooks</category><description>Build a webhook job queue on one SQLite table: claim work with leases, retry with jittered backoff, dead-letter poison events and replay them safely.</description></item>
<item><title>Webhook idempotency and dedupe for SQLite and Postgres</title><link>https://starlab.io.vn/blog/webhook-idempotency-dedupe-patterns/</link><guid>https://starlab.io.vn/blog/webhook-idempotency-dedupe-patterns/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Webhooks</category><description>Handle at-least-once webhook delivery safely: pick event ids, use unique constraints, size the dedupe window and make side effects run once.</description></item>
<item><title>Verify Standard Webhooks (Polar) signatures in Go</title><link>https://starlab.io.vn/blog/verify-standard-webhooks-go/</link><guid>https://starlab.io.vn/blog/verify-standard-webhooks-go/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Webhooks</category><description>Write a dependency-free Go verifier for Standard Webhooks signatures as used by Polar, with secret rotation, replay protection and a known-answer test.</description></item>
<item><title>Verify a downloaded binary: checksums, GPG, minisign, cosign</title><link>https://starlab.io.vn/blog/verify-downloads-checksums-signatures/</link><guid>https://starlab.io.vn/blog/verify-downloads-checksums-signatures/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Packaging and releasing CLIs</category><description>Learn what sha256sum, GPG, minisign and cosign each protect against, how to verify a release by hand, and how an installer should chain the checks.</description></item>
<item><title>systemd or pm2 for a small Node app on one VPS?</title><link>https://starlab.io.vn/blog/systemd-or-pm2-small-node-app/</link><guid>https://starlab.io.vn/blog/systemd-or-pm2-small-node-app/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>Compare systemd and pm2 for one Node app on one server: the pm2 symlink trap, restart after a crash, secrets, memory limits, logs, and which we pick.</description></item>
<item><title>What a plain systemctl restart costs a Go service under load</title><link>https://starlab.io.vn/blog/systemctl-restart-drops-requests/</link><guid>https://starlab.io.vn/blog/systemctl-restart-drops-requests/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>We sent 20 requests per second through Caddy while restarting a Go service. About one in four failed. Measure your own restart, then pick a fix that fits.</description></item>
<item><title>SSH, ufw and fail2ban basics for a single VPS</title><link>https://starlab.io.vn/blog/ssh-firewall-fail2ban-basics/</link><guid>https://starlab.io.vn/blog/ssh-firewall-fail2ban-basics/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>VPS operations</category><description>Which sshd_config options matter, how to write ufw rules, and how to set up a fail2ban jail, with a plain account of what each layer does and does not stop.</description></item>
<item><title>systemd socket activation: no dropped requests, but a cost</title><link>https://starlab.io.vn/blog/socket-activation-not-free-lunch/</link><guid>https://starlab.io.vn/blog/socket-activation-not-free-lunch/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>Socket activation let a Go service restart without refusing a connection, but slow requests waited over five seconds. Setup, code, and when to use it.</description></item>
<item><title>Roll back a bad deploy in a minute with release folders</title><link>https://starlab.io.vn/blog/rollback-in-under-a-minute-symlink-releases/</link><guid>https://starlab.io.vn/blog/rollback-in-under-a-minute-symlink-releases/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>Keep each release in its own directory behind a current symlink, switch atomically, prune old ones, and roll back with one command, including the database caveat.</description></item>
<item><title>When a restore succeeds and hands you the wrong data</title><link>https://starlab.io.vn/blog/restore-succeeded-wrong-data/</link><guid>https://starlab.io.vn/blog/restore-succeeded-wrong-data/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Backups and recovery</category><description>Restores that exit 0 can return old, empty or partial data. Learn six ways it happens and how to check row counts and freshness so a restore proves itself.</description></item>
<item><title>Restore PostgreSQL to a timestamp with recovery_target_time</title><link>https://starlab.io.vn/blog/restore-postgres-to-a-timestamp/</link><guid>https://starlab.io.vn/blog/restore-postgres-to-a-timestamp/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Postgres and data</category><description>Step by step PITR on PostgreSQL 15 to 17 with recovery.signal, restore_command and recovery_target_time, plus timelines and how to verify the result.</description></item>
<item><title>restic forget and prune: how the keep flags decide</title><link>https://starlab.io.vn/blog/restic-retention-policies-explained/</link><guid>https://starlab.io.vn/blog/restic-retention-policies-explained/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Backups and recovery</category><description>How restic forget --keep-daily, --keep-weekly and --keep-monthly combine, what prune really deletes, and how to pick a policy and test it with --dry-run.</description></item>
<item><title>A restic backup recipe for SQLite and Postgres on one VPS</title><link>https://starlab.io.vn/blog/restic-backup-sqlite-postgres/</link><guid>https://starlab.io.vn/blog/restic-backup-sqlite-postgres/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Backups and recovery</category><description>Back up a small server with restic without corrupt databases, using SQLite online backup, pg_dump with roles, aborts on bad dumps and a restore test.</description></item>
<item><title>Reproducible Go builds: build twice, compare the hashes</title><link>https://starlab.io.vn/blog/reproducible-go-builds-two-directories/</link><guid>https://starlab.io.vn/blog/reproducible-go-builds-two-directories/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Packaging and releasing CLIs</category><description>Build the same Go commit in two directories, compare the bytes, and learn which flags and settings make the hashes match or differ.</description></item>
<item><title>Receiving signed webhooks in Go with a durable queue</title><link>https://starlab.io.vn/blog/receiving-webhooks-go/</link><guid>https://starlab.io.vn/blog/receiving-webhooks-go/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Webhooks</category><description>Build a webhook receiver in Go that verifies signatures, dedupes deliveries, stores events in SQLite and processes them with retries, on one VPS.</description></item>
<item><title>PostgreSQL WAL archiving from scratch on a single Debian VPS</title><link>https://starlab.io.vn/blog/postgres-wal-archiving-from-scratch/</link><guid>https://starlab.io.vn/blog/postgres-wal-archiving-from-scratch/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Postgres and data</category><description>Turn on archive_mode, write a safe archive_command, take a pg_basebackup, and prove with pg_stat_archiver that WAL really reaches the archive.</description></item>
<item><title>How much data a disk failure costs with WAL archiving</title><link>https://starlab.io.vn/blog/pitr-how-much-can-you-lose/</link><guid>https://starlab.io.vn/blog/pitr-how-much-can-you-lose/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Postgres and data</category><description>We killed a PostgreSQL server mid-write and restored from the archive alone, so you can choose archive_timeout from measured loss instead of guessing.</description></item>
<item><title>pg_dump vs physical backup vs PITR: which to use</title><link>https://starlab.io.vn/blog/pg-dump-vs-physical-backup-vs-pitr/</link><guid>https://starlab.io.vn/blog/pg-dump-vs-physical-backup-vs-pitr/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Postgres and data</category><description>A decision guide to logical dumps, pg_basebackup and point-in-time recovery, with a comparison table and recommendations by database size and RPO.</description></item>
<item><title>Monitoring backups so that silence never means success</title><link>https://starlab.io.vn/blog/monitoring-backups-so-silence-is-not-success/</link><guid>https://starlab.io.vn/blog/monitoring-backups-so-silence-is-not-success/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Backups and recovery</category><description>Set up dead-man&#x27;s-switch pings, exit-code handling, snapshot age checks and failure alerts for a restic backup, so a job that stops running gets noticed.</description></item>
<item><title>Monitor one VPS without Prometheus, Grafana or a stack</title><link>https://starlab.io.vn/blog/monitor-one-vps-without-a-stack/</link><guid>https://starlab.io.vn/blog/monitor-one-vps-without-a-stack/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>VPS operations</category><description>Cron, curl and systemd are enough to catch a down app, a filling disk, low memory, an expiring certificate and a silent backup. Working scripts included.</description></item>
<item><title>Database migrations that survive a zero-downtime deploy</title><link>https://starlab.io.vn/blog/migrations-during-zero-downtime-deploys/</link><guid>https://starlab.io.vn/blog/migrations-during-zero-downtime-deploys/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>Use expand and contract to change a SQLite or Postgres schema while two releases overlap, with the lock pitfalls and the safe forms of common changes.</description></item>
<item><title>Find what filled your VPS disk and keep it from happening</title><link>https://starlab.io.vn/blog/journald-logrotate-disk-full/</link><guid>https://starlab.io.vn/blog/journald-logrotate-disk-full/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>VPS operations</category><description>Cap journald, rotate app logs, limit Docker logs, and find the culprit with du and ncdu when a small server reports no space left on device.</description></item>
<item><title>Harden a fresh Debian VPS in the first hour, step by step</title><link>https://starlab.io.vn/blog/harden-a-fresh-debian-vps/</link><guid>https://starlab.io.vn/blog/harden-a-fresh-debian-vps/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>VPS operations</category><description>A first-hour checklist for a new Debian VPS: updates, a non-root user, SSH keys, a firewall, unattended-upgrades, swap and time sync, with real commands.</description></item>
<item><title>Graceful shutdown for a Go HTTP server under systemd</title><link>https://starlab.io.vn/blog/graceful-shutdown-go-http-server/</link><guid>https://starlab.io.vn/blog/graceful-shutdown-go-http-server/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Go in production</category><description>Handle SIGTERM with signal.NotifyContext, drain requests with Server.Shutdown, stop workers cleanly and set TimeoutStopSec so systemd waits long enough.</description></item>
<item><title>A GoReleaser v2 config for a small Go CLI, line by line</title><link>https://starlab.io.vn/blog/goreleaser-config-small-cli/</link><guid>https://starlab.io.vn/blog/goreleaser-config-small-cli/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Packaging and releasing CLIs</category><description>Write a .goreleaser.yaml for a one-binary Go CLI covering builds, archives, checksums, version ldflags and changelog, and publish to GitHub or GitLab.</description></item>
<item><title>GOMEMLIMIT in an 80 MB container, with the numbers</title><link>https://starlab.io.vn/blog/gomemlimit-in-an-80mb-container/</link><guid>https://starlab.io.vn/blog/gomemlimit-in-an-80mb-container/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Go in production</category><description>A Go program with 40 MiB of live data was OOM-killed in an 80 MiB container. See what GOMEMLIMIT fixes, what it costs in CPU, and where the limit is soft.</description></item>
<item><title>Go SQLite reads returning 404 for rows that exist</title><link>https://starlab.io.vn/blog/go-sqlite-stale-reads/</link><guid>https://starlab.io.vn/blog/go-sqlite-stale-reads/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Go in production</category><description>Under load, a Go service answered 404 for rows it had just written. How we found it, the regression test that catches it, and what to check in your pool.</description></item>
<item><title>log/slog setup for a small Go service on journald</title><link>https://starlab.io.vn/blog/go-slog-small-services/</link><guid>https://starlab.io.vn/blog/go-slog-small-services/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Go in production</category><description>Configure log/slog with JSON or text output, a runtime log level, request ids on every line, secret redaction, and queries that work in journalctl.</description></item>
<item><title>Go HTTP server timeouts that survive slow and stuck clients</title><link>https://starlab.io.vn/blog/go-http-timeouts-slow-clients/</link><guid>https://starlab.io.vn/blog/go-http-timeouts-slow-clients/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Go in production</category><description>Set ReadHeaderTimeout, ReadTimeout, WriteTimeout and IdleTimeout correctly, add per-handler deadlines, and prove a slowloris client gets cut off.</description></item>
<item><title>I destroyed my server on purpose and timed the recovery</title><link>https://starlab.io.vn/blog/destroy-your-server-recovery-drill/</link><guid>https://starlab.io.vn/blog/destroy-your-server-recovery-drill/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Backups and recovery</category><description>Script a disaster-recovery drill for one VPS. Destroy the server, rebuild from restic, check the data, and see timings and five failures it found.</description></item>
<item><title>Deploy health checks that catch bad releases</title><link>https://starlab.io.vn/blog/deploy-health-checks-that-mean-something/</link><guid>https://starlab.io.vn/blog/deploy-health-checks-that-mean-something/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>Design a health endpoint and a deploy gate that reject broken releases, with readiness versus liveness, consecutive passes, and the false greens to avoid.</description></item>
<item><title>What a curl | sh installer for a Go binary should refuse</title><link>https://starlab.io.vn/blog/curl-pipe-sh-installer-checks/</link><guid>https://starlab.io.vn/blog/curl-pipe-sh-installer-checks/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Packaging and releasing CLIs</category><description>Write an install script for a Go release that stops on a bad checksum, odd version, plain http or unknown platform, and test each refusal.</description></item>
<item><title>Caddy or nginx for a one-person VPS stack, compared</title><link>https://starlab.io.vn/blog/caddy-vs-nginx-one-person-stack/</link><guid>https://starlab.io.vn/blog/caddy-vs-nginx-one-person-stack/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>VPS operations</category><description>An honest comparison of Caddy and nginx for one small server: automatic TLS, config size, what each does better, and when nginx is the right pick.</description></item>
<item><title>Caddy blue/green config for a one-server app, line by line</title><link>https://starlab.io.vn/blog/caddy-blue-green-config-walkthrough/</link><guid>https://starlab.io.vn/blog/caddy-blue-green-config-walkthrough/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Deploys and releases</category><description>Switch a Caddy 2 reverse proxy between two upstream ports with a generated snippet and a graceful reload, with health checks and retry settings explained.</description></item>
<item><title>The 3-2-1 backup rule applied to a single VPS</title><link>https://starlab.io.vn/blog/backup-3-2-1-for-one-vps/</link><guid>https://starlab.io.vn/blog/backup-3-2-1-for-one-vps/</guid><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><category>Backups and recovery</category><description>Translate 3-2-1 backups to one small server. See what counts as a copy, where the offsite one goes, how object storage compares with SFTP, and what it costs.</description></item>
</channel></rss>
