🔄Maintain and update
A machine that's always on stays clean over time. The OS, the dependencies, the tools, the agents: what you automate, what you update by hand, and how to avoid breaking anything.
A machine that runs 24/7 and is reachable from the outside is never “done.” It’s alive, and like everything that’s alive, it needs a bit of upkeep. The good news: 90% of it comes down to two habits, one automatic, the other monthly. Let’s look at which ones, and above all how to update without breaking anything.
The OS: the base system
Your Ubuntu is the foundation. Two levels of upkeep:
# The routine move: refresh the package list, then install updates
sudo apt update && sudo apt upgrade -y
# Clean out packages that have become useless
sudo apt autoremove --purge
For security, you’ve already automated everything in System settings with unattended-upgrades: the machine applies critical patches on its own. That’s the automatic habit we mentioned.
Once every two years, a new LTS version of Ubuntu comes out. You migrate with sudo do-release-upgrade, but take your time: back up first (see Git, GitHub & backups), and read the release notes. Nothing urgent here, an LTS is supported for years.
Dependencies: what your projects rest on
This is where the surprises hide, because a dependency that jumps a major version can break a project.
- Node (via
nvm):nvm install --ltsinstalls the latest LTS,nvm alias defaultsets it as the default. Keep the old one around long enough to confirm your projects still run. - A project’s packages:
npm outdatedshows what’s behind,npm updateupdates within the bounds of yourpackage.json. For major versions, read the changelog first: that’s where the breaking changes live. - The habit that saves you: lockfiles. Version your
package-lock.json/requirements.txt. They guarantee your project reinstalls exactly the same versions, everywhere, and that nothing shifts behind your back.
Tools and agents
The rest of your stack updates cleanly, each in its own way:
- Docker: follows the system’s
aptupdates. Remember to clean up what piles up (see below). - Ollama: rerun the install script to move to the latest version (
curl -fsSL https://ollama.com/install.sh | sh). And for models, you grab a new vintage withollama pull <model>: the local version is replaced. - Your coding agents: Claude Code and OpenCode keep themselves up to date almost on their own, and otherwise an
npm update -g(or their own update command) does the job. An up-to-date agent means new capabilities for free. - Tailscale and cloudflared: installed via their own repos, they update with the system. Nothing special to do.
Disk space: the silent trap
Models, Docker images, and old packages fill a disk without warning, and a full machine starts crashing in mysterious ways. The cleanup comes down to three commands:
df -h # how much room is left
docker system prune -a # drop unused images and containers
ollama rm <model> # remove a model you no longer use
sudo apt autoremove --purge # orphaned packages
Let the agent help you
This is exactly the kind of chore your agent loves. “Check what’s due for an update on this machine, summarize the important changes for me, and propose a plan”: it lists the packages that are behind, reads the changelogs for you, and offers to act step by step. You keep your finger on the button, it does the investigative work.