Automatically retry Oracle Cloud Infrastructure (OCI) compute instance launches until capacity is available — especially useful for Free Tier ARM (VM.Standard.A1.Flex) instances that are often out of stock.
Runs in Docker on Windows, macOS, and Linux. Configure once, start the container, and let it poll until your instance is created.
Inspired by hitrov/oci-arm-host-capacity.
- Check whether an instance with your configured name already exists.
- If not, attempt to create it in each configured availability domain.
- Sleep for
SLEEP_TIMEseconds, then repeat. - Exit once the instance exists.
The container is lightweight: near-zero CPU while sleeping, ~5 MB RAM idle, brief spikes during API calls.
| Requirement | Notes |
|---|---|
| Docker Desktop or Docker Engine | Windows, macOS, or Linux |
| OCI account | With API key access |
| SSH key pair | Public key is uploaded to the new instance |
| Make (optional) | Recommended on all platforms; see Without Make below |
| OS | Recommended shell | Notes |
|---|---|---|
| Windows | Git Bash or WSL | Docker Desktop required. Use Git Bash/WSL for make targets. |
| macOS | Terminal / iTerm | Docker Desktop for Mac. make works out of the box. |
| Linux | Any shell | Docker Engine + make. Add your user to the docker group. |
oci-capacity-nabber/
├── .env.example # Configuration template (copy to .env)
├── storage/ # Mount point for keys (gitignored)
│ ├── api_key.pem # OCI API private key
│ └── ssh_key.pub # SSH public key for the instance
├── docker/
│ ├── Dockerfile
│ └── docker-compose.yaml
├── scripts/ # Container entrypoint scripts
└── Makefile # Cross-platform dev commands
Do not commit
.env,*.pem, or*.pub. They are gitignored.
git clone https://github.com/paalamugan/oci-capacity-nabber.git
cd oci-capacity-nabbermake initOr manually:
mkdir -p storage
cp .env.example .envPlace your files in storage/:
| File | Description |
|---|---|
api_key.pem |
OCI API private key (downloaded when creating an API key) |
ssh_key.pub |
SSH public key for instance login |
Generate an SSH key (if you do not have one):
ssh-keygen -t rsa -b 4096 -f storage/ssh_key -C "oci-instance"
# Use storage/ssh_key.pub in storage/- Sign in to the Oracle Cloud Console.
- Open Profile → User settings → API Keys.
- Click Add API Key and download the private key.
- Save it as
storage/api_key.pem. - Note the values shown in the configuration preview:
- fingerprint
- tenancy OCID
- region
Also copy your user OCID from the profile page.
Edit .env with your credentials:
USER_OCID=ocid1.user.oc1..aaaa...
FINGERPRINT=aa:bb:cc:...
PRIVATE_KEY_FILE=api_key.pem
TENANCY_OCID=ocid1.tenancy.oc1..aaaa...
REGION_NAME=ap-singapore-1
HELPER=trueLeave instance fields empty for now.
Helper mode connects to OCI and prints availability domains, shapes, networks, and images.
With Make:
make testWith Docker Compose (from any platform):
# Build the image first
make build
# Run helper (HELPER=true in .env)
cd docker
docker compose run --rm nabberYou should see sections for AVAILABILITY DOMAINS, SHAPES, NETWORKS, and IMAGES.
Copy the values you need into .env:
| Variable | Example | Description |
|---|---|---|
AVAIL_DOMAIN_1 |
EXdS:AP-SINGAPORE-1-AD-1 |
At least one required; up to three supported |
SHAPE |
VM.Standard.A1.Flex |
Free Tier ARM shape |
NETWORK_ID |
ocid1.subnet.oc1... |
Subnet OCID |
IMAGE_ID |
ocid1.image.oc1... |
OS image OCID (run helper again after setting SHAPE) |
Free Tier shapes:
| Shape | CPU (CPU) |
RAM (RAM) |
|---|---|---|
VM.Standard.A1.Flex (ARM) |
1–4 | 6, 12, 18, or 24 GB |
VM.Standard.E2.1.Micro (x86) |
1 | 1 GB |
HELPER=false
AVAIL_DOMAIN_1=EXdS:AP-SINGAPORE-1-AD-1
INSTANCE_NAME=my-oci-instance
SHAPE=VM.Standard.A1.Flex
NETWORK_ID=ocid1.subnet.oc1...
IMAGE_ID=ocid1.image.oc1...
CPU=2
RAM=12
SSH_PUB_FILE=ssh_key.pub
SLEEP_TIME=120Start in the background:
make upFollow logs:
make logsStop:
make downWhen the instance is created, the container exits on its own.
| Variable | Required | Description |
|---|---|---|
USER_OCID |
Yes | Your OCI user OCID |
FINGERPRINT |
Yes | API key fingerprint |
PRIVATE_KEY_FILE |
Yes | Private key filename inside storage/ (usually api_key.pem) |
TENANCY_OCID |
Yes | Tenancy OCID |
REGION_NAME |
Yes | Region identifier (e.g. ap-singapore-1) |
HELPER |
Yes | true = list OCI resources; false = run nabber loop |
AVAIL_DOMAIN_1 |
Yes* | Primary availability domain |
AVAIL_DOMAIN_2 |
No | Second domain to try |
AVAIL_DOMAIN_3 |
No | Third domain to try |
INSTANCE_NAME |
Yes | Display name for the new instance |
SHAPE |
Yes | Compute shape |
NETWORK_ID |
Yes | Subnet OCID |
IMAGE_ID |
Yes | Image OCID |
CPU |
Yes | OCPUs for flex shapes |
RAM |
Yes | Memory in GB for flex shapes |
SSH_PUB_FILE |
Yes | SSH public key filename inside storage/ |
SLEEP_TIME |
No | Seconds between retries (default: 20) |
# From repo root — build image
docker build -t oci-capacity-nabber:local -f docker/Dockerfile docker/_context
# Or copy scripts first:
mkdir -p docker/_context && cp docker/Dockerfile scripts/*.sh docker/_context/
docker build -t oci-capacity-nabber:local -f docker/Dockerfile docker/_context
# Run helper or nabber
cd docker
docker compose run --rm nabber # foreground
docker compose up -d # background (uses image from compose)
docker compose logs -f
docker compose down# Initialize
New-Item -ItemType Directory -Force -Path storage
Copy-Item .env.example .env
# Build
mkdir -Force docker\_context
Copy-Item docker\Dockerfile, scripts\*.sh docker\_context\
docker build -t oci-capacity-nabber:local -f docker/Dockerfile docker/_context
# Run
cd docker
$env:NABBER_IMAGE = "oci-capacity-nabber:local"
docker compose run --rm nabberUse forward slashes in Docker volume paths on Windows, or run commands from Git Bash / WSL for the fewest path issues.
| Command | Description |
|---|---|
make init |
Create storage/ and .env from template |
make build |
Build local Docker image |
make test |
Build and run interactively (helper or nabber) |
make up |
Build and start in background via Compose |
make logs |
Tail container logs |
make down |
Stop and remove container |
make clean |
Remove build artifacts and local image |
Override the image name:
make build IMAGE=ghcr.io/paalamugan/oci-capacity-nabber:latest
make up IMAGE=ghcr.io/paalamugan/oci-capacity-nabber:latest| Issue | Fix |
|---|---|
cd: /storage: No such file or directory |
Volume mount failed. On Windows, use Git Bash/WSL or make test (handles path conversion). |
Could not find file: api_key.pem |
Ensure api_key.pem is in storage/ and PRIVATE_KEY_FILE=api_key.pem in .env. |
Operation not permitted on key file |
Normal on Windows bind mounts; the container copies the key to /tmp automatically. |
Out of host capacity |
Expected when OCI has no capacity. Keep the container running to retry. |
| CRLF / script errors on Windows | Scripts strip Windows line endings at build time. Ensure .env uses LF (see .gitattributes). |
exec /tmp/entrypoint.sh: no such file |
Rebuild the image: make build |
make build # Rebuild after editing scripts/
make test # Interactive test run
make clean # Remove artifactsUse and modify freely. Attribution to the original oci-arm-host-capacity project is appreciated.