2serverDocumentationGitHub
2server / DocumentationRead Markdown (.md) View source

Quick start

Let your coding agent help you take this app live. Open your project in the agent you already use, then copy this one prompt:

text
Help me deploy this project's app with 2server. Read https://2found.dev/docs/2server.md and explore https://github.com/2found/2server as needed.
Inspect the project, prepare its container image and deployment config, and guide me through any missing setup.
First help me choose: use my existing VM, or provision one with Terraform in my Google Cloud or AWS account. If I have neither, guide me through account setup, billing and login. Explain the proposed resources and costs before creating them.
Then help me connect my domain to Cloudflare and create a scoped API Token with the required permissions. Have me save credentials in a private local file; never ask me to paste secrets into chat.
Validate and plan the deployment, explain what will change, then deploy within the scope I authorize. Verify app readiness and public HTTPS. Report the live URL or the exact remaining blocker without exposing credentials.

You do not need to install a special agent plugin first. An agent that can read docs and run terminal commands can follow this guide. The optional Claude and Codex plugins provide reusable operating instructions.

What you and your agent need

For an app with a public domain, there are two things to arrange: a server to run it and Cloudflare access to connect the domain. Your agent prepares the configuration and commands. You choose the account, approve cloud spending and complete browser sign-in or token creation.

Have your project ready and decide which hostname should serve it. If you do not have a domain, register one first; the agent can then help add it to Cloudflare. Container builds and registry setup can be handled as part of the deployment.

1. Choose where your app runs

Use what you already have. You do not need both Google Cloud and AWS.

Your starting pointWhat you provideWhat the agent does
An existing VMSSH host, username and local key path, or GCP IAP connection detailsChecks access and server requirements; connects to an already managed VM or bootstraps a fresh one
A Google Cloud accountProject, region and permission to provision resourcesHelps you sign in, prepares Terraform inputs, previews and provisions the VM through 2server
An AWS accountAccount/profile, region and permission to provision resourcesHelps you sign in, selects a supported image and SSH setup, previews and provisions the VM through 2server
No VM or cloud account yetYour choice of Google Cloud or AWSWalks you through account creation, billing and local login, then follows the matching path above

Use an existing VM

Supported hosts are Debian 12/13 or Ubuntu 22.04/24.04 with Python 3, trusted key-based SSH and passwordless sudo. The VM must be able to pull your container image as root. Share the key's path, not its contents. The agent should inspect an existing server before making changes.

For a VM already managed by 2server:

sh
2srv connect --ssh [email protected] --identity ~/.ssh/server_key

For a fresh server, the agent generates an empty manifest and fills its SSH settings before bootstrap:

sh
2srv init server my-server -o server.local.json
2srv server bootstrap -f server.local.json --env-file /private/cloudflare.env --apply

Keep server.local.json and .2server/ private and ignored by Git. Bootstrap is for an empty server manifest with no published 2server state; connecting to an existing deployment does not require bootstrap.

Create a VM with Google Cloud or AWS

You complete the account's billing and interactive login. The agent can help install the provider CLI and Terraform, confirm the account/project and prepare the private inputs. Start with the provider you already use; compare the proposed VM, disk and public-IP costs if you are choosing a new one. Cloud resources are billed by your provider.

On Google Cloud, local Terraform uses Application Default Credentials, commonly set up with gcloud auth application-default login. GCP IAP also needs the operator's gcloud login and OS Login/IAP permissions. On AWS, use an existing local profile or your organization's IAM Identity Center login. Let the agent resolve missing permissions for the selected path.

The agent checks the provisioning contract and the repository's Terraform inputs. GCP needs a project; AWS also needs a verified Debian/Ubuntu amd64 AMI, SSH public key and restricted SSH source ranges. Do not paste cloud credentials into chat.

For example, once the GCP inputs are prepared:

sh
2srv provision gcp /absolute/private/server.tfvars --output server.local.json
2srv provision gcp /absolute/private/server.tfvars --output server.local.json --apply

The first command previews resources. The second creates them after you approve the target and spending. AWS uses provision aws with the SSH user matching its AMI. The output is a private bootstrap manifest, not a fully deployed app. Keep the absolute inputs path stable and back up the reported Terraform state; then bootstrap as above.

2. Give 2server access to Cloudflare

The “Cloudflare key” needed here is a scoped API Token, stored as CLOUDFLARE_API_TOKEN. A Global API Key or Origin CA key will not work in its place.

  1. Sign in to the Cloudflare dashboard, add your domain if needed, and update the nameservers at your registrar. Wait for the zone to become Active; a pending zone cannot serve this deployment flow.
  2. Open My Profile → API Tokens and choose Create Token → Create Custom Token. An account-owned service token under Manage Account → API Tokens is also supported; see the token guide for that path.
  3. Name the token for this deployment, select Zone for all five rows below, and limit Zone Resources to the specific domain you will deploy. The Edit zone DNS template alone is insufficient.
CategoryPermissionAccess
ZoneZoneRead
ZoneDNSEdit
ZoneZone SettingsEdit
ZoneCache Rules / Cache SettingsEdit / Write, as shown in the dashboard
ZoneSSL and CertificatesEdit
  1. Review the scope and create the token. Save the value directly into a private local dotenv file using your editor. It is shown once. Use CLOUDFLARE_API_TOKEN=<your token> in that file, restrict its permissions to 0600 and keep it outside Git. Tell the agent only the file path. Follow Cloudflare's token creation guide if dashboard labels differ.
  2. On a fresh server, pass that file to bootstrap's --env-file. On an already connected server, store it on the VM with:
sh
2srv server env --env-file /private/cloudflare.env --apply

The agent can prepare the file with an empty variable and tell you where to fill it. It should confirm that a credential is present without displaying its value. Connected commands read it from the VM; exporting a token in your laptop's shell does not replace a missing VM credential.

For an internal app without a public domain, Cloudflare can wait: remove the generated app's placeholder domains entry. Add it when you want public HTTPS. Workers, email routing and WAF policies need their own scopes; add only the permissions for features you use, following the full token reference.

Deploy the first app

Run from your application repository. The CLI needs Bun ≥ 1.3 and Node ≥ 20. Local Docker is needed when building images; Terraform is needed only for provisioning. The agent can check and install prerequisites as part of your setup.

sh
npm install -g @2server/cli
2srv help
2srv init app api -o api/2server/deploy.yaml

Set the app's real image, port, readiness endpoint and resource limits. Set its domain and Cloudflare zone, or remove the placeholder domain for an internal app. Build and push the image to a registry the VM can access. Commit the App file; secrets and connection files remain private. Read the App file reference when configuring secrets or migrations.

sh
2srv validate -f api/2server/deploy.yaml
2srv plan -f api/2server/deploy.yaml
2srv deploy -f api/2server/deploy.yaml --apply
2srv app api get

validate is offline. plan inspects the VM, registry and declared domains; it may pull image layers but does not roll out the app, run migrations or prove write permissions. Remote changes require --apply.

Deployment waits for readiness before switching app traffic, then reconciles domains and verifies public HTTPS. The agent should report the observed URL, app health and any unfinished stage. One VM remains one failure domain; traffic rollback does not undo database migrations. See reliability and recovery for production planning.

If setup gets stuck

BlockerNext step
No cloud account or billing enabledFinish account/billing setup in the provider's browser flow; the agent can prepare app files while you do this
SSH denied or provisioning permission missingConfirm the local identity, account/project, SSH user and required permission before retrying
Cloudflare zone pending or token returns 401/403Check nameservers, token type, expiry, zone scope and the reported missing permission; do not grant all account permissions
Readiness failsInspect 2srv app api logs and the app's readiness path before retrying
App is healthy but DNS/TLS failedInspect the reported app/domain state, correct the Cloudflare issue and re-plan; do not assume the whole release failed

Read more