AI agents, Docker, Ubuntu and VPS hosting

Self-hosting Amp Orbs on a 4 GB VPS

Amp released self-hosted Orbs in October 2026. With them, the container where the coding agent runs its tools moves to a server you own, and the model, the agent loop and the thread stay with Amp. A small virtual private server with 4 GB of memory is enough for one orb at a time, if the repository is small. The note below sizes the server, describes an installation kit and its 145-line Docker dispatcher, explains how model usage can be billed to a linked ChatGPT subscription, and says what a paused container keeps and what it loses.

An outlined server box holding three stacked blocks, one dark and two light grey. A line leaves the box from a small dot and ends at a red circle on the right.
One server with three orb containers. The dark block is a running container, and the two grey blocks are paused containers whose files are still on disk. The line is the outbound connection from the server to Amp, shown as the red circle. Amp never opens a connection in the other direction.

A hosted coding agent charges by the minute for a container that is idle most of the time. Amp's self-hosted Orbs, released on 22 October 2026, let you move that container to your own server, while the agent loop, the model routing and the thread interface stay with Amp. For one person with small repositories, the server can be a 4 GB virtual private server from the cheap end of a hosting catalogue. The difficult part is not the hardware. The difficult part is making the environment start on demand, keep its files across a pause, reconnect after a reboot, and produce no surprises on either the hosting bill or the Amp bill.

Summary.A 2 vCPU, 4 GB Ubuntu server runs one light Amp orb at a time. The provider process on the server opens an outbound connection to Amp, and Amp never connects in. A 145-line Bash dispatcher turns Amp's spawn, pause and delete requests into Docker commands, with a 3 GiB memory limit, a native ARM64 or x86-64 image, and project snapshots stored on the same disk. A paused orb keeps its files and loses its running processes. Self-hosted orbs are free on Amp's Hobby plan. With a ChatGPT subscription linked and the ChatGPT Only preset applied, OpenAI model usage is billed to the subscription instead of Amp credits. The server is billed for as long as it exists, whether or not an orb is running. The kit passed 19 simulated dispatcher tests and has not been installed on a real server yet.

What runs on the server and what stays with Amp

Amp describes the feature in one sentence. You provide the compute, and Amp turns it into orbs. In practice, a provider process runs on your server and opens an outbound HTTPS connection to Amp. When a thread needs an environment, Amp sends the provider one of three jobs, spawn, pause or delete, and the provider passes the job to a dispatch program that you supply. The dispatch program creates or resumes a container. Inside the container, a bootstrap command connects the orb to Amp, so Amp can set up the repository and run the agent's tools there.

The model never runs on the server. Whichever provider Amp routes a mode to serves the tokens, and the usage is billed wherever Model Routing says it is billed. The thread, its history and its interface stay with Amp as well. The setup self-hosts the execution environment only. Amp's announcement says that most users probably should not self-host, and that Amp supports only its own end of the contract. Amp built the feature for companies whose rules restrict where code may run. For an individual, the reason is cost, and the rest of the note checks whether the cost works out.

Server size for one orb

Amp's hosted small orb has 2 CPUs and 4 GB of memory, and Amp's sizing page recommends it for most single-package projects and routine coding tasks. A self-hosted server has to fit Ubuntu, Docker and the provider next to the container, so 4 GB is a starting point rather than a guarantee. The installer refuses to run on less than 3,500 MiB of memory or less than 12 GiB of free disk, and it sets the container defaults from the size of the host.

ResourceDefault in the kit
Server2 vCPU, 4 GB RAM, 40 GB disk
Operating systemUbuntu 24.04 LTS or 26.04 LTS
Active orbsOne
Container memory3 GiB on a 4 GB host, 6 GiB on 8 GB, host minus 2 GiB above 14 GiB
Container CPUsAll of the host's cores
Shared memory1 GiB, for browser tooling
Swap2 GiB file, created when no swap is active
Free disk guard5 GiB before any new container or snapshot
ArchitecturesLinux x86-64 and ARM64, with a native image for each

Swap absorbs a short memory peak, and it does not make a memory-heavy build fast. Repeated swapping on a server with 2 vCPUs can turn a two-minute test run into a ten-minute one. In practice, a 4 GB server suits a repository whose test suite fits in the spare memory of a laptop.

For a price reference, Hetzner's published EU monthly prices on 29 October 2026 were €5.99 for the x86 CX23 plan and €6.49 for the ARM CAX11 plan, each including one IPv4 address and excluding VAT. A checkout on 1 November showed the CAX11 at €7.85, which is the list price plus 21% VAT. The cheap plans are often out of stock in a given location, and a provider that cannot be trusted with your source code is not a good choice at any price. Nothing below depends on Hetzner. The kit is named after Hetzner because it was first written for a Hetzner server.

Creating the Ubuntu server

Create the server from a plain Ubuntu image with a public IPv4 address and your SSH public key. In the hosting provider's firewall, allow inbound TCP port 22 from your own address only, and leave outbound traffic open, because the provider process needs to reach Amp, your Git host, the Ubuntu package mirrors and Google's container registry. Give the orb provider its own server. The agent runs development commands with full permissions inside the orb, and the service account that manages the containers can control Docker on the host. Both are acceptable on a server used for nothing else, and neither is acceptable next to production services.

ssh root@SERVER_IP

Some images log you in as ubuntu rather than root. Use the account the image provides, and put sudo in front of the administrative commands. Compare the SSH host key with the one shown in the hosting dashboard before accepting it.

The Ghostty terminal error

On a minimal Ubuntu image, the first SSH session from the Ghostty terminal can fail with the following message:

ncurses: cannot initialize terminal type ($TERM="xterm-ghostty"); exiting

The server has no terminfo entry for Ghostty's terminal type. The error has nothing to do with Docker or Amp. In the SSH session, switch to a terminal type that every Ubuntu installation has:

export TERM=xterm-256color
printf '%s\n' "$TERM"

To stop the error from recurring, add the following lines to the user's ~/.bashrc on the server:

if [ "$TERM" = "xterm-ghostty" ]; then
    export TERM=xterm-256color
fi

Installing Ghostty's own terminfo entry on the server is the complete fix, and it is needed when Ghostty's terminal features matter. For running an installer and reading logs, the fallback is enough.

Creating the provider token in Amp

In Amp, open Settings, then Orbs, and add a provider. A personal provider works without a workspace. Name the provider so you will recognise it in the thread picker, for example vps-orbs. Amp shows a provider token that starts with aop_live_, and it shows the token only once. Copy the token and keep it somewhere private until the installer asks for it.

The token is a provider credential. It is not an OpenAI key and not an Amp login. The provider uses it to authenticate its outbound connection, so you do not need to open an inbound port for Amp. Do not put the token in a repository, a command-line argument, a screenshot or the installation archive. Amp's documentation adds one rule, which the kit enforces through systemd. Run exactly one provider process per token, because two providers sharing a token each claim part of the jobs, and a thread's orb can end up split between them.

What the installer does

The kit is a small ZIP archive. It contains an installer, a dispatcher, a provider wrapper, a systemd unit, a management command, a Python test file, a checksum list and a few short documents. The kit is not distributed with this page. The dispatcher and the systemd unit are reproduced below in full, because they are the parts that define the behaviour. The installer is 381 lines of checks and file placement, and the list below describes it instead. From the kit directory on the server, run the following commands:

apt-get update
apt-get install -y unzip
unzip amp-hetzner-kit.zip
cd amp-hetzner-kit
sha256sum -c SHA256SUMS
bash install.sh

The checksum step confirms that the extracted files match the list packed in the archive. It does not tell you who made the archive, so you need to trust the source you got it from. The installer then does the following:

  • Checks for Ubuntu 24.04 or 26.04, a native amd64 or arm64 CPU, at least 3,500 MiB of memory and 12 GiB of free disk under /var/lib.
  • Installs Docker Engine from Docker's own Ubuntu repository when Docker is absent, and stops if a Docker installation without systemd is present.
  • Creates a system account named amp-orbs with docker as a supplementary group, and installs the official Amp CLI for that account.
  • Selects the native orb image for the CPU architecture and pulls it before the provider starts, so the first thread does not wait for a download.
  • Creates a 2 GiB swap file when no swap is active; --no-swap skips the step.
  • Asks for the provider token with hidden input and writes it to a file under /etc/amp-orbs that only root can read. Non-secret settings go in a second file in the same directory.
  • Installs the amp-orbs management command and the systemd service, and starts the service.

On ARM64 the installer uses the image Amp publishes for that architecture:

us-central1-docker.pkg.dev/amp-prod-0/amp-orb/amp-orb-arm64:latest

On x86-64 it uses the default image:

us-central1-docker.pkg.dev/amp-prod-0/amp-orb/amp-orb:latest

Native images are important, because running x86-64 development tools under emulation on an ARM server is slow and fails in unexpected places, and the saving on an ARM plan is one or two euros a month. The installer configures the host's own platform, and the dispatcher refuses any platform value other than the two native ones.

The systemd unit is the part that keeps the provider running after a reboot. It waits for Docker, runs as the service account with no new privileges, restarts five seconds after any exit, and reads the token from the root-only file through systemd rather than from a shell environment:

[Unit]
Description=Amp self-hosted orb provider
Wants=network-online.target
After=network-online.target docker.service
Requires=docker.service

[Service]
Type=simple
User=amp-orbs
Group=amp-orbs
SupplementaryGroups=docker
WorkingDirectory=/var/lib/amp-orbs
Environment=PATH=/var/lib/amp-orbs/.local/bin:/var/lib/amp-orbs/.amp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
EnvironmentFile=/etc/amp-orbs/orbs.env
EnvironmentFile=/etc/amp-orbs/provider.env
ExecStart=/opt/amp-orbs/provider.sh
Restart=always
RestartSec=5
TimeoutStopSec=45
RuntimeDirectory=amp-orbs
RuntimeDirectoryMode=0750
UMask=0077
NoNewPrivileges=true
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

The dispatcher script

Amp's contract for a dispatch program consists of three operations and a few environment variables. The variables are ORB_OPERATION, ORB_ID, a short-lived ORB_TOKEN for the bootstrap, the ORB_IMAGE to use, and an optional ORB_SNAPSHOT_ID when Amp wants a prepared project saved or reused. The kit implements the contract for one persistent Docker host in 145 lines of Bash. The script has a few design choices that are easy to miss. It takes a lock file so two jobs cannot overbook the single slot, and it labels every container it creates so it can refuse to touch containers it did not create. It checks free disk space before any operation that writes, it puts a timeout on image pulls and snapshot commits, and it passes the bootstrap token as a bare --env name so the token never appears in process arguments or in the container's saved configuration.

#!/usr/bin/env bash
# Amp's dispatch contract, implemented for one persistent Docker host.
# Reference: https://ampcode.com/docs/orbs/self-hosted
set +x
set -Eeuo pipefail
umask 0077

log() { printf '[amp-orbs] %s\n' "$*" >&2; }
die() { log "$*"; exit 1; }
trap 'log "Dispatch failed. Inspect sudo amp-orbs logs; no credentials are printed by this script."' ERR

operation=${ORB_OPERATION:-}
orb=${ORB_ID:-}
case "$operation" in spawn|pause|delete) ;; *) die 'Expected ORB_OPERATION=spawn, pause, or delete.' ;; esac
[[ "$orb" =~ ^amp-[A-Za-z0-9][A-Za-z0-9_.-]*$ ]] || die 'Invalid or missing ORB_ID.'

platform=${AMP_ORBS_PLATFORM:-linux/amd64}
memory=${AMP_ORBS_MEMORY:-3g}
cpus=${AMP_ORBS_CPUS:-2}
max_running=${AMP_ORBS_MAX_RUNNING:-1}
shm_size=${AMP_ORBS_SHM_SIZE:-1g}
min_free_gb=${AMP_ORBS_MIN_FREE_GB:-5}
runtime_dir=${AMP_ORBS_RUNTIME_DIR:-/run/amp-orbs}
managed_label=io.ampcode.hetzner-kit

[[ "$platform" == linux/amd64 || "$platform" == linux/arm64 ]] || die 'Unsupported AMP_ORBS_PLATFORM.'
[[ "$memory" =~ ^[1-9][0-9]*[kKmMgG]$ ]] || die 'AMP_ORBS_MEMORY must be a size such as 3g.'
[[ "$shm_size" =~ ^[1-9][0-9]*[kKmMgG]$ ]] || die 'AMP_ORBS_SHM_SIZE must be a size such as 1g.'
[[ "$cpus" =~ ^[1-9][0-9]*([.][0-9]+)?$ ]] || die 'AMP_ORBS_CPUS must be positive.'
[[ "$max_running" =~ ^[1-9][0-9]*$ ]] || die 'AMP_ORBS_MAX_RUNNING must be a positive integer.'
[[ "$min_free_gb" =~ ^(0|[1-9][0-9]*)$ ]] || die 'AMP_ORBS_MIN_FREE_GB must be a nonnegative integer.'
[[ "$runtime_dir" == /* ]] || die 'AMP_ORBS_RUNTIME_DIR must be an absolute path.'

command -v docker >/dev/null || die 'Docker is not installed.'
command -v flock >/dev/null || die 'flock is not installed (install util-linux).'
mkdir -p -- "$runtime_dir"
exec 9>"$runtime_dir/dispatch.lock"
flock -w 30 9 || die 'Another orb operation is still running. Retry shortly.'

# A missing container is different from an unreachable Docker daemon.
docker_root=$(docker info --format '{{.DockerRootDir}}')
[[ -n "$docker_root" ]] || die 'Docker did not report its data directory.'

container_exists() { docker container inspect "$orb" >/dev/null 2>&1; }
container_running() {
    [[ "$(docker container inspect --format '{{.State.Running}}' "$orb")" == true ]]
}
assert_owned() {
    local owner
    owner=$(docker container inspect --format "{{ index .Config.Labels __DISPATCH__quot;$managed_label__DISPATCH__quot; }}" "$orb")
    [[ "$owner" == 1 ]] || die "Refusing to change $orb: it was not created by this kit."
}
valid_image_ref() { [[ "$1" =~ ^[A-Za-z0-9][A-Za-z0-9._/:@+-]*$ ]]; }
image_owned() {
    local owner
    owner=$(docker image inspect --format "{{ index .Config.Labels __DISPATCH__quot;$managed_label__DISPATCH__quot; }}" "$1" 2>/dev/null) || return 1
    [[ "$owner" == 1 ]]
}
check_free_space() {
    local free_kib required_kib
    (( min_free_gb > 0 )) || return 0
    free_kib=$(df -Pk -- "$docker_root" | awk 'END {print $4}')
    [[ "$free_kib" =~ ^[0-9]+$ ]] || die 'Could not read free space in Docker storage.'
    required_kib=$((min_free_gb * 1024 * 1024))
    (( free_kib >= required_kib )) || die "Docker storage has less than $min_free_gb GiB free. Inspect disk usage; do not prune paused orbs."
}
check_capacity() {
    local names count=0 name
    names=$(docker ps --filter "label=$managed_label=1" --format '{{.Names}}')
    while IFS= read -r name; do
        [[ -n "$name" ]] && count=$((count + 1))
    done <<< "$names"
    (( count < max_running )) || die "All $max_running orb slot(s) are in use. Archive another active thread in Amp, wait for it to pause, then retry."
}

case "$operation" in
    spawn)
        [[ -n ${ORB_TOKEN:-} ]] || die 'Amp did not supply ORB_TOKEN.'
        [[ -n ${ORB_IMAGE:-} ]] || die 'Amp did not supply ORB_IMAGE.'
        valid_image_ref "$ORB_IMAGE" || die 'Invalid ORB_IMAGE reference.'

        if container_exists; then
            assert_owned
            if ! container_running; then
                check_capacity
                check_free_space
                docker start "$orb" >/dev/null
            fi
        else
            check_capacity
            check_free_space
            selected_image=$ORB_IMAGE
            if [[ -n ${ORB_SNAPSHOT_ID:-} ]]; then
                valid_image_ref "$ORB_SNAPSHOT_ID" || die 'Invalid ORB_SNAPSHOT_ID reference.'
                if image_owned "$ORB_SNAPSHOT_ID"; then
                    selected_image=$ORB_SNAPSHOT_ID
                fi
            fi
            # Normal installation pre-pulls the base image. Pulls here are bounded
            # so a missing custom image cannot hold the provider indefinitely.
            if ! docker image inspect "$selected_image" >/dev/null 2>&1; then
                timeout 180 docker pull --platform "$platform" "$selected_image" >/dev/null
                check_free_space
            fi
            docker run --detach --init --platform "$platform" \
                --name "$orb" --label "$managed_label=1" \
                --memory "$memory" --cpus "$cpus" --shm-size "$shm_size" \
                --log-driver local --log-opt max-size=10m --log-opt max-file=3 \
                "$selected_image" sleep infinity >/dev/null
        fi

        # Bare --env names copy the ephemeral token from the environment without
        # putting it in process arguments or the container's saved configuration.
        bootstrap_env=(--env ORB_TOKEN)
        if [[ -n ${AMP_URL:-} ]]; then bootstrap_env+=(--env AMP_URL); fi
        docker exec --detach "${bootstrap_env[@]}" "$orb" amp orb bootstrap
        log "$orb: bootstrap started."
        ;;
    pause)
        if ! container_exists; then
            log "$orb: already absent."
            exit 0
        fi
        assert_owned
        if container_running; then docker stop --time 20 "$orb" >/dev/null; fi
        if [[ -n ${ORB_SNAPSHOT_ID:-} ]]; then
            valid_image_ref "$ORB_SNAPSHOT_ID" || die 'Invalid ORB_SNAPSHOT_ID reference.'
            if docker image inspect "$ORB_SNAPSHOT_ID" >/dev/null 2>&1 && ! image_owned "$ORB_SNAPSHOT_ID"; then
                die 'Refusing to overwrite an image that was not created by this kit.'
            fi
            check_free_space
            timeout 240 docker commit --change 'LABEL io.ampcode.orb.snapshot=1' \
                "$orb" "$ORB_SNAPSHOT_ID" >/dev/null
            log "$orb: project snapshot saved locally."
        fi
        log "$orb: paused; files retained."
        ;;
    delete)
        if container_exists; then
            assert_owned
            docker rm --force "$orb" >/dev/null
        fi
        log "$orb: removed (or already absent)."
        ;;
esac

The pause branch defines the whole design. The container is stopped and not removed, so its writable layer stays on disk. If Amp asked for a snapshot, the stopped container is committed to a local image under the ID Amp supplied, and the next spawn for the same project starts from the image instead of running setup again. The delete branch is the only one that destroys anything, and it only acts on containers that carry the kit's label.

Checking the setup with a first thread

On the server, three commands report whether the local half of the setup is healthy:

sudo amp-orbs doctor
sudo amp-orbs status
systemctl is-active amp-orbs

An active answer from the last command means the provider process is running, and it says nothing about whether an orb can start. The management command also accepts logs, follow, restart, start, stop, token and update. To check the other half, go back to Amp, open a new thread, choose Orb, then Self-Hosted, then the provider's name, and select a repository. A good first prompt asks for facts and changes nothing:

Inspect this environment. Report uname -m, available memory, free disk space, and the current repository path. Do not change any files.

A correct reply shows that the whole chain works. Amp reached the provider, the dispatcher started a container, the bootstrap connected back, and a tool ran inside the container. When the thread fails, read both the provider's journal and the thread's setup log, because each one sees a different half of the failure.

The default configuration allows one active orb. A second thread that asks for an environment receives a capacity message from the dispatcher, which suggests archiving the first thread so Amp pauses its orb. Paused orbs do not count against the slot. The limit is a memory policy for a 4 GB host and not a limit of Amp's, and the AMP_ORBS_MAX_RUNNING setting raises it on a server with more memory.

Where model usage is billed

The server runs no language model. Model usage goes wherever Amp's Model Routing sends each mode, and linking OpenAI can mean two different things with two different bills.

Connection shown in AmpWhere the tokens are billed
ChatGPT SubscriptionEligible OpenAI model usage counts against the linked ChatGPT plan, within the plan's access and limits
OpenAI API KeyOpenAI bills the tokens separately, per request, on the API account

Open Settings, then Model Routing, and read which connection type is listed and what the routing preview says for each mode. With a ChatGPT subscription linked, Amp documents a preset named ChatGPT Only, which pins the main agent of the low, medium and high modes to OpenAI models. At the time of writing, the models are GPT-5.6 Terra, GPT-6.1 Sol and GPT-6 Astra. Amp applies the preset on its own only if you have never changed the dial or Tune Modes. Otherwise, Amp offers the preset, or you can apply it from Settings, Mode Dial, Tune Modes. Without the preset, a change to Amp's default models can move a mode to a model your subscription does not cover, and the usage is then billed to Amp credits.

To link a subscription from a computer with a browser, run the following command:

amp config model-providers add-chatgpt-subscription

Token sharing is not available on every ChatGPT plan, and Business and Enterprise workspaces can switch it off. In both cases the connection stays off, and Model Routing says so. Some Amp features never use the subscription. Image generation, web search, reading web pages and voice are billed to Amp credits, and the ultra mode keeps Amp's own routing. Read the usage page after the first real thread instead of assuming that every line is zero.

The plan side is simpler than the routing side. Amp's free Hobby plan includes unlimited self-hosted orbs at no charge, and it allows you to bring your own subscriptions and keys. The paid Individual plan adds a monthly allowance of Amp-hosted orb minutes and the higher mode tiers. A self-hosted provider does not use the allowance, and the allowance still applies to any thread that runs on Amp's own orbs. A thread picks its orb when it starts, and the plan decides what the hosted orbs cost.

What a paused orb keeps

Docker is the main compromise in the design. Amp's documentation names Docker as the backend that cannot save memory across a pause, in the words "Docker cannot save memory". The kit's pause operation stops the container and keeps its writable filesystem. Files, installed packages, the cloned repository and everything under /home/user remain. Running processes do not remain.

Project setup that runs once belongs in .agents/setup. Anything that has to start again after a resume, for example a database, a development server or a file watcher, belongs in .agents/resume. Amp runs the resume script instead of the setup script when a paused orb with preserved disk wakes up. A thread that starts from a current project snapshot skips setup altogether, and in the kit the snapshot is a Docker image committed on the same disk.

Two costs continue through a pause. First, the hosting provider charges for the server and its IPv4 address for as long as the server exists, whether it is running, stopped or powered off. Second, disk usage grows, because dependency caches, several repositories, stopped containers and snapshot images all live under Docker's data directory. Check the disk from time to time with the following commands:

df -h
sudo docker system df

Do not prune.A paused orb is a stopped container. The commands docker container prune and docker system prune remove stopped containers, which in the kit means removing someone's working files. Delete orbs through Amp, push work to Git, and keep a backup of anything that cannot be recreated. The dispatcher's disk guard repeats the same warning in its error message.

For routine maintenance, run the following commands:

sudo amp-orbs status
sudo amp-orbs update
sudo amp-orbs restart

The update command refreshes the Amp CLI and pulls the configured orb image. Existing containers and snapshots keep the image they were created from, and a new orb uses the new image. Ubuntu and Docker security updates are a separate task that the kit does not perform.

Common failures and their first checks

SymptomLikely causeFirst check
ncurses rejects xterm-ghosttyMissing remote terminfo entryexport TERM=xterm-256color
Provider missing from Amp's pickerWrong personal or workspace context, bad token, or service not connectedsudo amp-orbs logs
Container starts, setup failsGit access, dependency install, disk or memoryThe thread's setup log
Second thread cannot startOne-orb capacity limitsudo amp-orbs status
Build killed before it finishesContainer or host memory exhaustedContainer limit, free memory, swap activity
Services gone after a pauseDocker kept files, not processes.agents/resume
Unexpected Amp chargesA mode or an extra tool used Amp creditsModel Routing and the usage page

A workload that keeps reaching the 3 GiB limit needs an 8 GB server, where the installer sets the limit to 6 GiB. Raising the concurrency limit on a 4 GB host does not add capacity, because two containers then share the memory of one and fail in turn.

How much work the setup takes

The setup is small. It consists of a cheap Ubuntu server, one token copied from Amp's settings, one installer run over SSH, and a first thread that asks the server to describe itself. About an hour covers all of it, and most of the hour is spent waiting for the image download. The dispatcher is one page of Bash, reproduced in full above, and the only rule to remember afterwards is to delete orbs through Amp rather than through Docker. For code that cannot leave your own servers, or for anyone who wants a persistent server with their repositories already on it, the hour is a small cost. For everyone else, Amp's hosted orbs remain the simpler choice, and the page above describes what to do if that changes.

Sources

  1. Amp, Self-hosted orbs documentation: provider contract, Docker behaviour, images, networking and pricing
  2. Amp, Self-hosted orbs announcement, 22 October 2026
  3. Amp, Pricing: Hobby, Individual, Teams and Enterprise plans
  4. Amp, The Dial: ChatGPT subscription routing, the ChatGPT Only preset and features billed to credits
  5. Amp, Orb sizes and costs
  6. Amp, Customizing orbs: project setup and resume scripts
  7. Amp, CLI installation
  8. Docker, docker container prune: stopped containers are removed
  9. Docker, Resource constraints: memory, CPU and shared memory
  10. Docker, Install Docker Engine on Ubuntu
  11. Hetzner, Price adjustment effective 15 June 2026
  12. Hetzner, Cloud billing FAQ: charges for powered-off servers and separately billed resources