Deploy a Next.js app
Last updated: June 21, 2026
You built a Next.js app in Claude Code, Cursor, or v0. It runs on localhost. Now you want it on a real server, on your own domain, with HTTPS — without learning Linux, nginx, or DNS first.
This recipe hands the whole job to your AI assistant. With the American Cloud MCP server connected, your assistant can pick a region, size a server, show you the cost, create the VM, open the right ports, install everything over SSH, point your domain at it, and turn on TLS — all from prompts you paste in.
Why Claude Code for this
Any MCP client can create the infrastructure. But deploying a Next.js app also means running commands on the server: SSH in, install Node, build the app, configure a service. Claude Code combines the American Cloud tools with your terminal, so a single session can provision the VM and deploy to it without you switching tools. That's the setup this recipe assumes. Cursor and the other clients work too — you'll just run the SSH steps yourself when the assistant tells you to.
Provisioning is a write operation. You'll need a read-write API key from
console.americancloud.com/api-keys
and the --allow-writes flag on the MCP server. See the
overview for setup and safety details. Start read-only,
get comfortable, then switch the key when you're ready to build.
Before you start
- A working Next.js app in a local git repo (it runs with
next buildandnext start). - A domain you control, with the ability to point its nameservers or DNS at American Cloud.
- The MCP server connected to your assistant with a read-write key and
--allow-writes.
The one prompt that does it
Open your project in Claude Code and paste this, filling in the two placeholders. Read the cost estimate it shows you before approving anything.
I have a Next.js app in this repo. Deploy it to American Cloud on the domain
{your-domain.com}.
Plan it out first, then walk through it step by step:
1. List the available regions and Ubuntu images, and the VM packages.
Recommend a small, low-cost size that can build a Next.js app.
2. Check whether I already have an SSH key registered. If not, create one
for me and tell me where the private key is.
3. Show me a monthly cost estimate for the VM before creating anything.
Wait for me to confirm.
4. Create a small Ubuntu VM with that SSH key, on an isolated network, and
open inbound ports 22, 80, and 443. Wait until it's fully running.
5. Over SSH: install Node.js LTS and nginx. Clone or copy this repo to the
server, run the production build with Next.js standalone output, and run
the app as a systemd service that restarts on boot and on crash.
6. Configure nginx as a reverse proxy in front of the app on port 80.
7. Add a DNS A record pointing {your-domain.com} at the VM's public IP.
8. Once DNS resolves, provision a Let's Encrypt TLS certificate with certbot
and switch nginx to HTTPS with auto-renewal.
Confirm the site is live at https://{your-domain.com} when you're done.What your assistant will do
Grounded in real MCP tools, here's the sequence:
- Survey the options. It calls
list_regions,list_images(filtered to Ubuntu), andlist_vm_packagesto find a region near you, a current Ubuntu LTS image, and a small compute tier within its CPU/memory limits. - Sort out the SSH key. It calls
list_ssh_keysto see what's already registered. If nothing fits,create_ssh_keygenerates a new pair — the private key is returned once and never stored, so your assistant saves it locally (for example to~/.ssh/) and sets the right permissions. It needs this key both to register on the VM and to SSH in afterward. - Price it first. It calls
get_cost_estimate_vmwith the exact region, package, size, and image — and shows you the hourly and monthly numbers before creating anything. Nothing is billed yet. - Create the server. On your go-ahead,
create_vmprovisions a small Ubuntu VM. The same call carriesnetworkAccessto open inbound ports 22 (SSH), 80 (HTTP), and 443 (HTTPS) on the network's public IP, andkeypairsto install your SSH key. The VM provisions asynchronously, so the assistant pollsget_vmuntil its status reachesSTARTEDand it has a public IP. - Set up the server over SSH. Now in the terminal, it installs Node.js LTS and nginx, pulls your code onto the VM, and runs the production build. For Next.js it uses standalone output (
output: "standalone"innext.config), which bundles only the files the server needs into.next/standalone— smaller, faster to copy, and easy to run with a plainnode server.js. - Make it a service. It writes a
systemdunit so the app starts on boot, restarts if it crashes, and runs on a local port (commonly 3000). - Put nginx in front. nginx listens on port 80 and reverse-proxies to the Next.js process, so the public ports you opened map to your app.
- Point the domain at it. It calls
list_dns_zonesto see if your domain is already hosted. If not,create_dns_zoneadds it (you'll then update your registrar's nameservers to American Cloud's, which the assistant can show you). Thencreate_dns_recordadds anArecord for the domain pointing at the VM's public IP. - Turn on HTTPS. Once DNS resolves to the VM, it runs certbot to obtain a Let's Encrypt certificate, reconfigures nginx for port 443, and enables automatic renewal.
When it's done, you have a Next.js app served over HTTPS on your own domain, on a server you own and can SSH into.
Tell the assistant to explain each step before it runs it if you want to follow along — "narrate what you're about to do and why." Destructive operations are flagged regardless, and clients that support confirmations will prompt you before anything irreversible.
Follow-up: a one-prompt deploy command
The first deploy is the hard part. Make every future deploy trivial by asking your assistant to script it:
Set up a deploy script in this repo that I can run to ship updates to the
server. It should: push the latest committed code to the VM over SSH, run the
production build there, and restart the systemd service. Add a "deploy" entry
to package.json scripts that runs it. Document the one command I run from now on.After this, shipping a change is "run the deploy script" — or just "deploy the latest" and the assistant runs it for you.
Follow-up: add a database on the same server
If your app needs a database, your assistant can install one directly on the VM over SSH:
My app needs PostgreSQL. Install it on the VM, create a database and user for
this app, store the connection string in the app's environment file, and
restart the service. Keep PostgreSQL listening only on localhost so it isn't
exposed to the internet.This keeps the database private to the server — nothing new is opened on the firewall, and only your app talks to it over localhost.
Static site instead?
If your Next.js app is fully static (output: "export"), the same recipe gets simpler: no Node process and no systemd service — nginx serves the exported files directly, so the smallest VM tier is plenty. Just tell the assistant your app uses static export and it adapts the plan. And if your app handles user uploads or large assets, pair the VM with object storage instead of filling the server's disk.
Troubleshooting
The domain doesn't load right after the DNS record is added. DNS changes take time to propagate — anywhere from a few minutes to a couple of hours, depending on your registrar and the record's TTL. Ask your assistant to "check what {your-domain.com} currently resolves to and tell me when it points at the VM's IP." certbot also needs DNS to resolve to the VM before it can issue a certificate, so the HTTPS step may have to wait for propagation.
The site is unreachable on port 80 or 443. Ask your assistant to "list the firewall rules on the VM's public IP and confirm 80 and 443 are open." It can call list_firewall_rules, and add any missing rule with create_firewall_rule. Also have it check the VM is STARTED with get_vm and that both the app service and nginx are running on the server.
The build runs out of memory on a small VM. Next.js builds can be memory-hungry. If the build is killed, ask your assistant to either "add swap space on the VM and retry the build," or "build the app locally and copy the standalone output to the server instead of building on the VM." Both are one prompt each.
SSH connection refused. Confirm port 22 is open (same list_firewall_rules check) and that the private key from the create_ssh_key step is the one your assistant is using. If the key was lost, your assistant can reset access with reset_vm_password or open a browser console session.
Next steps
- Things to try with the MCP server — more prompt ideas across compute, networking, and DNS
- Use American Cloud with Claude Code — the build-and-deploy client setup
- Object storage with your AI assistant — uploads, assets, and backups for your app
- Migrate from Vercel — move an existing Next.js deployment
- Run on Kubernetes — when one VM isn't enough
- Write an AGENTS.md for your project — teach your assistant your deploy conventions