cd /news/developer-tools/one-command-turns-a-fresh-ubuntu-ser… Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-66630] src=dev.to β†— pub= topic=developer-tools verified=true sentiment=↑ positive

One Command Turns a Fresh Ubuntu Server into a 24/7 AI Development Machine

A developer created ubuntu-server-dotfiles (v1.3.0), a one-command bootstrap that turns a fresh Ubuntu 24.04 server into a 24/7 AI development machine. The tool installs a full developer environment including zsh, Neovim, Node, Rust, Docker, and AI CLIs like Claude Code, opencode, and OpenAI Codex, enabling persistent long-running AI coding sessions that survive laptop lid closures and network interruptions.

read7 min views6 publishedJul 21, 2026

AI coding agents changed the shape of my development day. A session with Claude Code isn't a burst of typing anymore β€” it's a long-running conversation where the agent researches, implements, runs tests, and iterates while I check in. And that exposed the weakest link in my setup: the laptop. Close the lid, lose the session. Spotty cafΓ© Wi-Fi, lose the session. Want the agent grinding through a migration overnight? The laptop stays open on the kitchen counter.

The fix is old and boring: do the work on a server, keep the sessions in tmux, connect from wherever you are. What was missing was the setup cost β€” a fresh VPS is a bare shell, and provisioning zsh, Neovim, Node, Rust, Docker, and the whole AI toolchain by hand is half a day of yak-shaving before the first prompt.

So I made it one command. This post is about the developer profile in ubuntu-server-dotfiles (v1.3.0): what it installs, how the AI layer gets set up, and the actual 24/7 working pattern it enables. I covered the underlying GNU Stow + idempotent-bash machinery in an earlier post β€” this one is about what it's for.

On any fresh Ubuntu 24.04 server, as a non-root user with sudo:

f=$(mktemp) && curl -fsSL https://raw.githubusercontent.com/VimukthiShohan/ubuntu-server-dotfiles/main/bootstrap.sh -o "$f" && bash "$f"

(Download-then-run instead of curl | bash

, so a truncated download can never execute a partial script.)

Two questions later, you're done:

ubuntu

or root

's cousin. Answer y

, name the user, and bootstrap creates it, gives it sudo, copies your authorized_keys

over (hardened β€” refuses symlinks, uses install

with exact modes), and hands the entire installation off to that account. Your daily-driver user never shares state with the cloud default.

Select a profile:
  1) minimal    β€” server essentials only
  2) developer  β€” everything (editor stack, runtimes, AI CLIs)
  3) custom     β€” essentials + groups you pick
Choice [1-3]: 2

Pick 2

, go make coffee. The choice is saved to ~/.config/dotf/profile

, so re-runs never re-ask.

Everything, in dependency order, from plain-text manifests:

Layer What you get
Shell zsh (login shell) + powerlevel10k, tmux + TPM, fzf, zoxide, direnv
Ergonomics ripgrep, fd, bat, eza, delta, btop, lazygit, yazi, gh, just, shellcheck
Editor Neovim from the official tarball (apt's 0.9 is too old), lua-language-server, tree-sitter
Runtimes Node via fnm, bun, pnpm, Rust via rustup, Go, Python + uv/pipx
Services Docker (enabled + your user in the group), postgres/redis clients
Cloud AWS CLI v2
AI CLIs
Claude Code, opencode, OpenAI Codex, rtk

The AI row is the point. claude

, opencode

, and codex

are installed by the same manifest discipline as everything else β€” official installers, guarded, idempotent. rtk

(a token-optimizing CLI proxy for agent sessions) comes along via cargo.

Then the optional layer on top: AI skill frameworks. After the toolchain lands, dotf skills

offers a picker:

AI skill frameworks (comma-separated numbers, empty for none):
  1) SuperClaude Framework
  2) Superpowers (obra)
  3) mattpocock/skills
  4) Graphify
  5) react-devtools (Callstack)
  6) Callstack agent-skills (React Native)

Each installs user-globally and unattended-safe (that took real debugging β€” one CLI liked to stall on an interactive scope prompt). Re-running is always safe; the installer re-runs each framework's official install command rather than presence-skipping, so updates come for free.

Here's an actual session, field-tested on a fresh EC2 instance running Ubuntu 24.04.

Once, at provision time:

ssh dev@your-server       # as the new user
claude auth login         # authenticate the agents once per machine
gh auth login

Every working session after that:

ssh dev@your-server
tmx                       # tmux workspace bootstrapper, ships with the repo
claude                    # start the agent on whatever you're building

tmx

(stowed alias for scripts/tmx/main.sh

) spins up my named tmux dev workspace β€” editor pane, agent pane, shell. The part that changes everything:

Ctrl-Space d              # detach β€” the agent keeps working

(Ctrl-Space

is the prefix this repo's .tmux.conf

ships; stock tmux uses Ctrl-b

.)

Close the laptop. The session doesn't care. Claude Code is still running the test suite, opencode is still mid-refactor. Reattach from anywhere:

ssh dev@your-server -t tmux attach

From the same laptop at home, from a different machine at the office, from an SSH client on your phone while waiting in line. The session is exactly where you left it β€” scrollback, agent context, running processes, all of it. Kick off a long agent task in the evening, check the result over breakfast.

The phone, without SSH: Remote Control. SSH-from-a-phone works, but a terminal on a 6-inch screen is an act of stubbornness. Claude Code has a better answer β€” start the agent with Remote Control enabled:

claude --remote-control

The session pairs with the Claude app on your phone, and you drive it from there: read what the agent did, answer its questions, approve the next step, send follow-up prompts β€” a native mobile UI instead of a squinted-at terminal. Run it inside the tmux workspace and you get both worlds: the full terminal when you're at a keyboard, the app when you're not. This is what makes the always-on server click for agent work β€” the agent asks "should I refactor these call sites too?" while you're out for lunch, and you answer from your pocket instead of losing the afternoon's momentum. Sessions are named by hostname by default, so if you run several servers, each shows up distinctly in the app.

And keeping the machine current is two commands:

dotf update    # git pull --ff-only, then converge
dotf doctor    # read-only drift check β€” exits 1 if anything's off

Opinionated and brief: 2 vCPUs and 4 GB RAM is the comfortable floor for the developer profile. The single heaviest step is compiling yazi from source via cargo (a few minutes on 2 vCPUs); everything else is downloads. 2 GB works if you add swap, but the first cargo install

will make you regret it. Disk: 25 GB+ once Docker images enter the picture. The AI CLIs themselves are lightweight β€” the agents' heavy lifting happens on the provider's side, not your box.

Don't overprovision for the agents; provision for your builds and containers.

No SSH private keys, no GitHub auth state, no API tokens β€” ever. The repo is public; machine identity is not, and a static guard test fails the build if a forbidden pattern sneaks into a tracked file. Authentication happens exactly once per machine, by you:

claude auth login

/ codex

first-run auth for the agentsgh auth login

for GitHub~/.gitconfig.local

for git identity, ~/.config/zsh/local.zsh

for machine-local env β€” both untracked, both included automatically by the stowed configsThis is also why the new-user step matters: your AI development identity lives in a clean account you created, not in whatever the cloud image shipped.

Why a server instead of just running agents on my laptop?

Persistence and symmetry. Agent sessions are long-lived; laptops aren't. A server gives every device you own β€” laptop, desktop, phone β€” the same view of the same session: tmux for terminals, claude --remote-control

for the Claude app. Suspend/resume, network switching, and "I need to leave now" stop being session-killers.

Why not Codespaces / devcontainers?

Those are per-project workspaces that spin down; this is a persistent machine that's yours. Different tools. I want tmux sessions that survive for weeks, Docker services that stay up, and cron running dotf doctor

. Also: a plain VPS is provider-agnostic and often cheaper than always-on cloud IDEs.

What if I don't want the full developer profile?

That's what profiles are for. minimal

gives you a working shell + git + the dotf

CLI on boxes that don't need more. custom

lets you pick groups β€” dependencies resolve automatically (picking nvim

pulls in build

and node

; the picker shows each group's contents so you know what you're getting).

Is re-running safe?

Yes β€” that's the core design constraint. apply.sh

converges: every step checks before it acts. Bootstrap refuses to touch a ~/.dotfiles

that isn't this repo, verifies the clone matches upstream before executing anything, and re-asks nothing you've already answered.

Can I use this repo directly?

Yes β€” clone it, gut my configs, keep the skeleton. The manifests and profile machinery don't care whose dotfiles are in home/

.

The complete setup is at github.com/VimukthiShohan/ubuntu-server-dotfiles, released as v1.3.0. One command, one coffee, and every device you own is a thin client to a development machine that never sleeps.

── more in #developer-tools 4 stories Β· sorted by recency
── more on @vimukthishohan 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/one-command-turns-a-…] indexed:0 read:7min 2026-07-21 Β· β€”