Choosing the Right Go Toolchain: Podman vs Docker, Caddy, USQL, and AI Assistants

This article summarizes Go Podcast Episode 72, comparing container runtimes, web servers, database CLIs, AI‑assisted coding, and deployment strategies, while highlighting how tool choices reflect engineers' workflows, performance needs, and discipline in modern Go development.

Radish, Keep Going!
Radish, Keep Going!
Radish, Keep Going!
Choosing the Right Go Toolchain: Podman vs Docker, Caddy, USQL, and AI Assistants

Containerization Debate: Podman vs "I Won't Install Docker"

Dominic champions Podman for its rootless operation and near‑identical CLI to Docker, arguing it eliminates daemon and privileged mode requirements. Example commands:

# Podman commands compatible with Docker
podman run -d --name pg -p 5432:5432 -e POSTGRES_PASSWORD=dev postgres:latest

podman run -d --name redis -p 6379:6379 valkey/valkey:latest

Morten prefers installing dependencies directly, using Docker Compose files for local development, and values knowing exactly where each component resides.

"Containerized development promises consistency, but in practice it often feels slower than running services directly."

Dominic counters that for services like Valkey, Redis or Postgres, containerization avoids cluttering the host machine.

Caddy: An Underrated Go Infrastructure Tool

Caddy, written in Go, is a web server and reverse proxy with automatic HTTPS. Its standout feature is dynamic SSL certificate generation via the Admin API, ideal for multi‑tenant SaaS where each customer has a custom domain.

"You can let Caddy accept all traffic; if a domain lacks an SSL certificate, it calls a specified API to fetch allowed domains and automatically generates the cert."

Using the Admin API to add routes without restarting:

# Dynamically add a route via Caddy Admin API (no restart)
curl localhost:2019/config/apps/http/servers/srv0/routes \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "match": [{"host": ["newclient.example.com"]}],
    "handle": [{"handler": "reverse_proxy", "upstreams": [{"dial": "localhost:8080"}]}]
  }'

Compared to the configuration complexity of Nginx or Traefik, Caddy’s simplicity and Go‑native extensibility stand out.

Database Tools: Stay in the Terminal

USQL

is a Go‑written universal CLI supporting PostgreSQL, MySQL, SQLite, SQL Server, and more, offering a consistent command set across databases.

# Connect to different databases with the same commands
usql postgres://localhost/mydb
usql mysql://root@localhost/mydb
usql sqlite:///path/to/db.sqlite

# List tables (psql‑style)
\dt
"I don't need to switch between psql and MySQL CLI; USQL feels like a thin wrapper around psql that works with all databases."
DBLab

provides a terminal UI (TUI) for database interaction, though Morten prefers the GUI client DBeaver in production for its stronger security safeguards.

Dominic praises SQLite for its code quality and test coverage, recommending it for analytics, caching, or embedded storage.

AI‑Assisted Development: $20 for Discipline

Morten subscribes to Anthropic and OpenAI’s $20 monthly plans, finding the token limit forces careful selection of tasks to hand off to AI.

"The quota is just enough; it forces me to stay in the middle, still writing code and carefully reviewing AI output."

Dominic uses Claude to review his open‑source marketing site, while both agree AI should assist, not replace, architectural and security decisions.

Dominic: avoids AI‑generated Go code due to quality concerns, but lets AI write front‑end/React code.

Morten: treats AI as a brainstorming partner and migration aid, retaining final decision‑making.

"If you use AI to speed up coding, you must accept sloppier code. You can't have it both fast and perfect."

A case was cited where an AI‑assisted project leaked millions of driver records via an insecure S3 bucket, underscoring that security responsibility remains with the developer.

Deployment Philosophy: Docker or Bare Metal?

Morten deploys SaaS products directly on bare metal using systemd services:

# Example systemd unit for a Go service
[Unit]
Description=My Go API Server
After=network.target

[Service]
Type=simple
ExecStart=/opt/myapp/server
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

For zero‑downtime, Docker + Traefik can auto‑detect new containers and shift traffic, but Dominic accepts a few seconds of downtime for simplicity.

The guiding principle: avoid adding complexity for problems you don't have; Kubernetes is powerful but unnecessary for a single‑machine service.

Notable Go Ecosystem Tools

Crush : AI programming assistant written in Go with LSP integration (formerly OpenCode).

MailPit : Local mail server for testing email functionality.

Traefik : Go‑based reverse proxy with automatic service discovery and Docker integration.

Whisper : OpenAI speech‑to‑text model useful for workflow automation.

Ideas for Tools Yet to Be Built

Dominic envisions a true CLI email client (not TUI) that interacts with IMAP/SMTP and displays mail lists in text tables.

Morten wants a video transcription and auto‑editing tool using Whisper for speech recognition, noting a Rust implementation exists on YouTube creator "Dreams of Code".

Both ideas share the belief that Go’s fast compilation, single‑binary output, and cross‑platform nature make it ideal for building friction‑reducing CLI utilities.

Key Takeaways

Tools should serve the workflow, not dictate it; Morten skips Docker for faster local installs.

Constraints (e.g., a $20 AI quota) foster disciplined code review habits.

Simplicity wins: use systemd over Kubernetes when it suffices.

Prefer Go‑written tools (Caddy, Traefik, USQL, Crush) for easier source inspection.

AI is a tool, not a replacement; use it for mundane tasks while retaining architectural and security decisions.

References

Go Podcast Episode 072: The tools we're using as Go SWE

Podman: https://podman.io/

Caddy: https://caddyserver.com/

USQL: https://github.com/xo/usql

DBLab: https://github.com/danvergara/dblab

Crush (Go AI assistant): https://github.com/charmbracelet/crush

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

backendGoToolingcontainers
Radish, Keep Going!
Written by

Radish, Keep Going!

Personal sharing

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.