provision-droplet10.8 KB
View saved version →
---
name: provision-droplet
description: >
Use when the user wants to spin up / create / launch / provision a
DigitalOcean droplet (or "a remote dev box on DO") and connect to it from
Codex as a remote SSH workspace.
---
# Provision a DigitalOcean droplet as a Codex remote workspace
Follow these steps in order. Do not skip or reorder them.
**Only the installed Codex DigitalOcean app tools and the bundled Python scripts
may be used. doctl, ad hoc integration configs, and any other DigitalOcean CLI
tools are prohibited.**
## Before you start
- **Prerequisites:** a funded DigitalOcean account, the installed and
authenticated Codex **DigitalOcean** app, a local `ssh`/`ssh-keygen`
(OpenSSH), Python 3, and the Codex desktop app.
- **Cost:** the droplet bills **hourly from creation until you delete it**.
Sizes in step 5 show approximate monthly rates. Remind the user to delete it
when done (see *Cleanup* below).
- **Time:** end-to-end takes ~10–15 minutes — roughly 7 minutes waiting for the
droplet to boot (steps 7-8) plus up to 7 minutes for cloud-init (step 9). This
is normal; do not abort.
- **Locate the bundled scripts first (do this before Step 2).** The helper
scripts live in the `scripts/` folder **next to this `SKILL.md`** (i.e.
`provision-droplet/scripts/`). Your current working directory is **not** the
skill directory, so bare relative paths like `scripts/keygen.py` will fail.
Resolve the absolute directory that contains this `SKILL.md` and call it
`<skill_dir>`. If you don't already know it, find it — the installed plugin may
nest it under a version folder (e.g. `.../<version>/provision-droplet/`), so
locate the directory that actually contains `scripts/keygen.py`. Use
`<skill_dir>/scripts/<name>.py` (an absolute path) in **every** command below.
## Step 1 — Verify DigitalOcean app access
This plugin depends on the single Codex **DigitalOcean** app. Use it for all
DigitalOcean operations; do not register or log in to separate plugin-owned app
integrations.
The **DigitalOcean** app provides both:
- SSH key tools: `key-create`, `key-list`, `key-delete`.
- Droplet tools: `droplet-create`, `droplet-get`, `droplet-delete`.
Confirm that these tools are available before continuing. If the app's tools are
missing or unauthenticated, stop and tell the user to install or authenticate
the DigitalOcean app in Codex. Do not fall back to doctl, API tokens, or a local
integration config.
## Step 2 — Generate SSH key pair
```bash
python3 <skill_dir>/scripts/keygen.py
```
Parse the JSON output and keep these values for the steps below:
`prefix`, `name`, `key_name`, `key_path`, `pub_key`.
How these relate (all derived from one random `prefix` like `bright-hawk-a3f2`):
- `name` = `codex-<prefix>` — the **droplet name** and the **local SSH alias**
(they are identical).
- `key_name` = `codex-key-<prefix>` — the label for the key on DigitalOcean's
side only.
- `key_path` — the local private key file.
## Step 3 — Upload SSH public key
Call the **DigitalOcean** app tool **`key-create`**:
| Parameter | Value |
|-----------|-------|
| `Name` | `key_name` from step 2 |
| `PublicKey` | `pub_key` from step 2 |
Extract `ssh_key.id` from the response — this is `<key_id>`.
If the call fails because a key with that name or fingerprint **already exists**
(e.g. a previous run), do not create a duplicate: call the **DigitalOcean** app
tool **`key-list`**, find the entry whose `name` matches `key_name` (or whose
fingerprint matches the uploaded key), and use its `id` as `<key_id>`.
## Step 4 — Choose a region
Ask the user, in chat:
> Use the defaults — region **`nyc3`** (New York, US) and size
> **`s-4vcpu-8gb`** (4 vCPU / 8 GB / 160 GB, ~$48/mo) — or customize them?
If they choose the defaults, use `nyc3` as `<region>` and `s-4vcpu-8gb` as
`<size>`, then skip step 5 and continue to step 6.
If they want to customize the defaults, present this region list first and ask
them to reply with a slug:
| Sl
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 3 — file references are metadata, not package contents.