Bootstrap script for a freshly provisioned OCI Ubuntu (Ampere A1 / ARM64) instance.
| Item | Method | Notes |
|---|---|---|
| Base packages | apt |
curl, git, build-essential, unzip, gnupg, tmux, … |
| tmux persistence | tpm + resurrect + continuum + systemd | Sessions auto-save and are restored after a reboot |
GitHub CLI (gh) |
official apt repo | arm64 supported |
| Node.js LTS | NodeSource | For MCP servers / npm tooling |
| Emacs | apt |
emacs-nox by default (headless); set EMACS_GUI=1 for full |
| Default editor | env + alternatives | Emacs set as EDITOR/VISUAL, git core.editor, system editor |
| Claude Code | official native installer | ARM64 supported, auto-updates |
| OpenAI Codex CLI | official installer (npm fallback) | aarch64 musl binary |
| Antigravity CLI | official installer | antigravity.google/cli/install.sh; linux-arm supported |
| zsh | apt + chsh |
set as default shell, with oh-my-zsh |
| Shell aliases | .zshrc / .bashrc |
e=emacs, ll=ls -al, ucc=claude --dangerously-skip-permissions |
The script is idempotent (safe to re-run) and does not touch the firewall, SSH, or networking — per your setup.
On a fresh instance:
curl -fsSL https://raw.githubusercontent.com/jay-jang/dev-server-setup/main/setup.sh | bash
⚠️ curl … | bashruns remote code immediately. Inspect the script first (open the raw URL in a browser) before piping it to a shell.
Pass options inline, e.g. skip oh-my-zsh:
curl -fsSL https://raw.githubusercontent.com/jay-jang/dev-server-setup/main/setup.sh | SKIP_OHMYZSH=1 bashgh repo clone jay-jang/dev-server-setup
cd dev-server-setup
chmod +x setup.sh
./setup.shRun as the normal ubuntu user (not root) so the AI CLIs install into your home dir.
SKIP_OHMYZSH=1 ./setup.sh # skip oh-my-zsh
EMACS_GUI=1 ./setup.sh # full Emacs instead of emacs-noxYour tmux sessions are saved and come back automatically after the instance reboots. Two pieces make that work:
- Restore session contents — tmux-resurrect + tmux-continuum (installed
via tpm). Continuum auto-saves every 15 min and restores the last saved
environment whenever the tmux server starts (
@continuum-restore on). - Restart the server at boot — a systemd user service
(
~/.config/systemd/user/tmux.service) plus user lingering, so the tmux server (and therefore the continuum restore) comes back at boot without anyone logging in. On a clean reboot the service also saves once on stop, so you get the latest state rather than only the last 15-min auto-save.
On a real instance the service is enabled during setup. If systemd wasn't reachable at setup time (e.g. you ran inside a container), enable it once on the box:
systemctl --user enable --now tmux.serviceVerify after a reboot: tmux ls should list your previous sessions.
The test/ scripts spin up a fresh-OCI-like arm64 Ubuntu container and run the
real setup.sh inside it. test/run.sh is the host-side launcher (needs Docker):
./test/run.sh # default: setup smoke test (docker-test.sh)
./test/run.sh tmux-reboot-test.sh # prove tmux sessions survive a reboot
./test/run.sh uninstall-test.sh # setup → uninstall round-tripThe reboot test creates a tmux session, lets resurrect save it, kills the whole tmux server (the part of a reboot that matters to tmux), brings the server back up the way the boot service does, and asserts the session/window are restored.
One-liner (prompts for confirmation, reading your terminal even through the pipe):
curl -fsSL https://raw.githubusercontent.com/jay-jang/dev-server-setup/main/uninstall.sh | bashOr from a clone:
./uninstall.shConservative by default — base/system packages (curl, git, build-essential, …)
are kept, and app data dirs are removed. Options (work with either form, e.g.
curl -fsSL …/uninstall.sh | ASSUME_YES=1 bash):
ASSUME_YES=1 ./uninstall.sh # no confirmation prompt (required for unattended runs)
KEEP_DATA=1 ./uninstall.sh # keep ~/.claude, ~/.codex, Antigravity logins/config
KEEP_NODE=1 ./uninstall.sh # keep Node.js + NodeSource repo
REMOVE_BASE=1 ./uninstall.sh # also purge base packages (keeps curl + ca-certificates)It reverts the default shell to bash and the default editor to the system auto choice, and does not touch firewall/SSH/networking.
exec zsh(or log out/in) to pick up zsh + PATH changes.- Authenticate:
claude→ browser logincodex→ ChatGPT/OpenAI loginagy→ Antigravity CLI login flowgh auth login→ GitHub CLI
- Verify:
git --version,gh --version,claude --version,codex --version,agy --version,emacs --version,echo $EDITOR