AI News HubLIVE
站內改寫6 分鐘閱讀

待翻譯:I turned a Mac Studio into an always-on AI development server

AI 服務暫時不可用,以下為來源摘要,待恢復後補全翻譯:I like the MacBook Air because it is a computer I do not resent carrying. Unfortunately, the way we build Polyform is almost a lab experiment designed to make a thin laptop reconsider its career choices. A normal change…

來源Hacker News AI作者: ahmedelsama

AI 服務暫時不可用,以下為來源正文,待恢復後補全翻譯。

I like the MacBook Air because it is a computer I do not resent carrying. Unfortunately, the way we build Polyform is almost a lab experiment designed to make a thin laptop reconsider its career choices. A normal change can touch our database, backend, and UI together. I want every branch to have its own code, dependencies, services, test database, and preview. I also want several AI coding agents working at once. That means multiple Git worktrees, development containers, local databases, application servers, Storybook, browsers, and test runners all asking for memory at the same time. The Air was not the problem. Asking it to be a portable laptop and a small data center was the problem. So I kept it. I bought a Mac Studio, connected it to Ethernet, and turned it into the machine that runs the work. Then I wrote a small command-line tool called Workspaces to make the remote machine feel local. The architecture Every branch becomes a self-contained remote environment Git worktrees let one repository have several branches checked out at the same time. The worktree is the isolation boundary for the source code; the development container is the isolation boundary for the runtime. When I start a new workspace, the tool creates a branch from the latest origin/main, adds a linked worktree on the Studio, makes sure the container runtime is available, opens the repository in its development container, and creates a named tmux session. One pane is for Codex. Another is for the application. One command, one durable environmentThe branch is the name CLI · 01Create a workspace Name the branch and repository profile. Git · 02Add the worktree Check out a fresh branch from origin/main. Container · 03Start the full stack Run the app, backend, database, and tools together. tmux · 04Keep sessions alive Detach without stopping the agent or server. SSH · 05Forward the ports Carry web, API, and Storybook ports home. Caddy · 06Open a stable URL Review the exact workspace in a normal browser. The workspace can outlive the laptop lid, a train ride, and an unreliable Wi-Fi connection. The real implementation has recovery checks, port allocation, stale-tunnel handling, repository profiles, and cleanup. The core operation is still pleasantly boring: def create_workspace(branch, worktree_path): remote("git fetch origin main") remote( f"git worktree add -b {quote(branch)} " f"{quote(worktree_path)} origin/main" ) ensure_devcontainer(worktree_path) ensure_tmux_session(branch, worktree_path) ensure_preview_tunnels(branch) That is a simplified excerpt from our Workspaces CLI. The important design choice is that the tool owns the routine. I do not manually remember which worktree maps to which container, which tmux session, or which forwarded port. tmux is what makes the agents durable An SSH connection is temporary. A tmux session is not. tmux keeps the programs running on the Studio when the client disconnects, then lets me reattach from another terminal later. The workspace creates a named session and a repeatable pane layout. In simplified form: tmux new-session -d -s "$WORKSPACE" -c "$WORKTREE" tmux rename-window -t "$WORKSPACE:0" dev tmux select-pane -T codex tmux split-window -h -t "$WORKSPACE:0" -c "$WORKTREE" tmux select-pane -T app tmux attach-session -t "$WORKSPACE" I can begin on the MacBook, close it, answer a question from my phone, and reattach from the MacBook later. The agent, dev server, and logs remain where they were. The phone is not a good place to review a database migration. It is a surprisingly good place to answer, “Yes, preserve the existing API contract and continue.” Poly is showing the work state, not proof that the change is correct. The tests and review still have that job. SSH makes it remote; keepalives make it tolerable The Studio has macOS Remote Login enabled and my public key in its authorized keys. The CLI connects with SSH keepalives so a temporary network wobble is detected instead of leaving a terminal in a mysterious half-alive state. ssh \ -o ServerAliveInterval=15 \ -o ServerAliveCountMax=3 \ -t "$WORKSPACE_REMOTE_HOST" \ "tmux attach -t '$WORKSPACE'" I use a private hostname in my SSH configuration. Do not copy an internal hostname from a blog post, and do not expose a home Mac's SSH port to the public internet just because you can. Use a trusted network or private VPN, key-based authentication, and the smallest firewall surface that works for you. The same SSH connection carries local port forwards. Each workspace receives its own local ports for the web application, API, and Storybook. The implementation uses a reusable SSH control socket so one durable connection can own several forwards: ssh -M -S "$CONTROL_SOCKET" -N \ -L "127.0.0.1:$LOCAL_WEB:127.0.0.1:$REMOTE_WEB" \ -L "127.0.0.1:$LOCAL_API:127.0.0.1:$REMOTE_API" \ -L "127.0.0.1:$LOCAL_STORYBOOK:127.0.0.1:$REMOTE_STORYBOOK" \ "$WORKSPACE_REMOTE_HOST" The ports are now local, but numbered ports are a miserable user interface. That is where Caddy comes in. Caddy turns forwarded ports into memorable preview URLs The Workspaces tool writes a small Caddy snippet for each environment. Caddy reverse-proxies a stable .localhost name to the port forwarded over SSH. Browsers treat .localhost names as local, and Caddy can manage local HTTPS for them. web.feature-sql-costs.polyform.localhost { reverse_proxy 127.0.0.1:45127 } api.feature-sql-costs.polyform.localhost { reverse_proxy 127.0.0.1:45128 } storybook.feature-sql-costs.polyform.localhost { reverse_proxy 127.0.0.1:45129 } Now the backend and database can run on the Studio while the preview opens on the Air like any other local site. I can keep browser devtools, screenshots, and visual review on the computer in front of me without making that computer run the whole stack. The URL is also recoverable. If the tunnel disappears, the tool checks the listener, recreates the control connection, reloads the workspace snippet, and tries again. A remote development setup feels good only when the common failure path is one command, not a networking séance. Why containers still matter on a machine I control The Studio could run everything directly on macOS. I still use development containers because a remote host does not eliminate dependency drift. Each worktree should be able to start the same database services, backend dependencies, Node version, and tooling without competing with another branch. The container gives the AI agent a complete environment it can test. A change that touches the schema, server, and interface can be exercised together before I review it. This is also what makes parallel AI development safer. Worktree isolation alone prevents two agents from editing the same files. Runtime isolation prevents their databases and application processes from quietly editing each other's state. What moved off the laptop?Keep interaction local, move pressure remote MacBook Air Codex interface, terminal client, browser, screenshots, design review, and the keyboard I am actually using. Mac Studio Worktrees, containers, databases, application servers, tests, Storybook, tmux, and the long-running agent processes. The $200 subscription changes the economics for me I use ChatGPT Pro, currently listed at $200 per month, for Codex. For this workflow, that means I can use the subscription's Codex access instead of building the system around separately metered API calls. Usage limits and guardrails still apply; this is not a promise of infinite compute. The Studio is a fixed hardware cost, plus electricity and the small amount of maintenance any server needs. The important economic benefit is predictability. Adding another worktree mostly consumes compute I already own. The agent can continue while my portable computer sleeps, and I do not pay for a separate hosted development machine for every branch. Cloud workspaces are still the right answer for many teams. They are easier to standardize, easier to place near cloud services, and easier to replace. My setup is optimized for one founder who already wanted macOS, uses the same machine every day, and likes knowing that the computer has a screen attached if an authentication dialog ever decides to become philosophical. A practical setup order Put the remote machine somewhere boring. Connect it to Ethernet, power, and a display you can reach when macOS requires local attention. Enable secure remote access. Turn on Remote Login, install your SSH public key, disable password access if your environment allows it, and use a private network or VPN. Install the runtime. Set up Git, tmux, Caddy, your container runtime, and the development-container command line. Clone one canonical repository. Let linked worktrees fan out from that repository instead of cloning the entire history for every branch. Name everything from the branch. Worktree directory, tmux session, container project, port allocation, and local URL should derive from one stable identifier. Automate recovery before scale. Detect stale worktrees, missing containers, dead SSH listeners, and old Caddy snippets. Test the full path. Create a branch, migrate its test database, run backend tests, open Storybook, inspect the UI, disconnect, and reattach from another device. You do not need my CLI to use the pattern. A short script around git worktree, a development-container command, tmux, SSH port forwarding, and Caddy gets most of the benefit. The custom tool became worthwhile when I wanted cleanup, repository profiles, predictable URLs, and repair behavior. What this does not solve The Studio is a single machine. If it loses power, runs out of disk, or waits on a macOS dialog, every workspace feels it. Back up the repository state that is not already pushed. Monitor disk and memory. Keep important work committed and pushed. Know how to reach the machine locally. Remote development also adds a network dependency. tmux protects the process from a dropped client, but it does not make a bad connection fast. Large file transfers, video-heavy previews, and latency-sensitive interactions may still be better locally. Finally, isolation has limits. A development container does not automatically make credentials safe, a database disposable, or an AI-generated migration correct. Use scoped secrets, synthetic data, separate test resources, and the same review gates you would use on a cloud development machine. My favorite part is still the light laptop It would be easy to describe this as a Mac Studio project. It is really a MacBook Air preservation project. The Studio lets the Air be what it is good at: a quiet, light window into work happening somewhere more muscular. I can run several realistic Polyform environments, let Codex continue through long tasks, open the exact preview on the device in front of me, and close the lid without turning “away from keyboard” into “development environment deleted.” If you love carrying a heavy laptop, I cannot help you. If you love carrying almost nothing while a small aluminum server at home runs your containers, this setup is for you. It is one practical example of the broader Polyform approach to durable AI work: give the agent a real environment, preserve the state, expose evidence, and keep the person in control of review. References and further reading Git: git-worktree documentation tmux: Getting Started Caddy: reverse_proxy directive Caddy: Automatic HTTPS and local HTTPS Development Containers specification OpenAI: ChatGPT pricing