Practical guides on Linux, AI, self-hosting, and developer tools

Build Powerful TUI Apps in Python with Textual and Rich

Terminal apps used to mean raw curses calls and a lot of pain. Today, Python’s Textual and Rich libraries have flipped that experience entirely. In under 50 lines of Python you can have a full-screen app with styled layouts, interactive widgets, keyboard navigation, and live data updates - no web browser, no Electron, no JavaScript. This post walks through both libraries, shows you how they fit together, and builds up to a complete working example you can extend immediately.

Gemini CLI: Google's Free AI Coding Agent with 1,000 Requests Per Day

Gemini CLI is Google’s open-source (Apache 2.0) terminal AI coding agent, and its defining feature is a free tier that no competitor matches: 1,000 requests per day and 60 requests per minute using nothing more than a personal Google account. No credit card required, no API key, no trial period that expires after 30 days. This persistent free tier, combined with a 1M token context window and Gemini 3 Flash as the default model, has driven Gemini CLI to roughly 97K GitHub stars - making it the most-starred AI coding CLI on the platform. The catch is code quality: Gemini 3 Flash gets things right on the first try about 50-60% of the time on complex tasks, well behind Claude Code’s 95%. That trade-off defines who should and should not use it.

How to Migrate from X11 to Wayland on an Existing Linux Install

You can switch your existing Linux installation from X11 to Wayland without reinstalling anything. The migration boils down to selecting a Wayland session at your display manager’s login screen, then working through three categories of follow-up: Xwayland compatibility for legacy X11 applications, input device configuration via libinput instead of xorg.conf, and environment variable tweaks so that toolkits like Qt, GTK, and Electron render natively through Wayland instead of falling back to X11. Most people can finish the whole process in an afternoon, keeping an X11 session as a fallback until they are satisfied everything works.

How to Harden Your Docker Images: A Container Security Checklist

Hardening a Docker image means eliminating the attack surface at every layer. Start from a minimal base image like distroless or Alpine, run as a non-root user, set the filesystem read-only, drop all Linux capabilities and add back only what the application actually needs, pin dependency versions with verified checksums, and scan images with Trivy or Grype before pushing to a registry. Each layer of this checklist is independently valuable. You can adopt them incrementally without rewriting existing Dockerfiles, and every single item you check off reduces your exposure to real-world container exploits.

How to Implement OAuth 2.0 Login from Scratch

You implement OAuth 2.0 login by using the Authorization Code flow with PKCE (Proof Key for Code Exchange). Your web app redirects the user to the provider’s authorization endpoint with a code_challenge, the user authenticates and consents, the provider redirects back with an authorization code, and your backend exchanges that code along with the code_verifier for an access token. PKCE is mandatory for all OAuth 2.0 clients under the OAuth 2.1 draft specification (currently at draft-ietf-oauth-v2-1-15) and eliminates the need for a client secret in public clients. Building this from scratch - without Auth0, Clerk, or NextAuth - takes roughly 200 lines of code and teaches you exactly how token exchange, session management, and token refresh actually work.

Why Is My USB-C Charger So Slow? Understanding USB Power Delivery

USB Power Delivery (USB-PD) is supposed to be the universal charging standard that ends cable chaos. In practice, plugging in the wrong cable or charger gives you a device that charges at 5W instead of 100W - or refuses to charge at all. The root cause is almost always one of three things: a cable rated below what the device needs, a charger that advertises high wattage but only supports a narrow set of voltage profiles, or confusion between USB-PD and the half-dozen proprietary fast-charging protocols that coexist with it.

How to Deploy with Docker Compose and Traefik in Production

Deploy a production-ready stack by running Traefik v3 as a Docker container that automatically discovers your services through Docker labels, provisions and renews Let’s Encrypt TLS certificates via the ACME protocol, and routes incoming HTTPS traffic to the correct backend container. Everything lives in a single docker-compose.yml file with no separate Nginx or Apache configs to maintain. Traefik’s Docker provider watches the Docker socket for container start and stop events, reads routing rules from labels like traefik.http.routers.myapp.rule=Host('app.example.com'), and reconfigures itself in real time. Combined with middleware for rate limiting, authentication, and security headers, this gives you a self-managing reverse proxy that handles multi-service deployments on a single VPS with zero manual certificate management.

How to Set Up Wildcard SSL Certificates with Let's Encrypt and DNS

A wildcard SSL certificate for *.example.com from Let’s Encrypt covers every single-level subdomain - app.example.com, git.example.com, status.example.com - under one certificate. You obtain it by running Certbot with the DNS-01 challenge, which requires creating a TXT record at _acme-challenge.example.com to prove domain ownership. A DNS plugin like certbot-dns-cloudflare or certbot-dns-route53 automates this by creating and cleaning up the TXT record through your DNS provider’s API. Once issued, a single wildcard cert replaces the need to manage individual certificates for every self-hosted service behind your reverse proxy.