| name | cf-cli |
| description | Comprehensive Cloud Foundry CLI (cf CLI v8) assistant for generating commands, automating app deployments, managing services, and troubleshooting errors. Use this skill whenever the user mentions "cf", "cf cli", "Cloud Foundry", "cf push", "cf login", "cf target", app deployment to CF, service binding, buildpacks, routes, domains, orgs and spaces, manifests, or any task involving the Cloud Foundry command line — even if they just say something like "push my app" or "how do I bind a service". Also trigger when the user asks about scaling apps, managing environment variables in CF, creating user-provided services, rolling deployments, SSH into app containers, or writing CF manifests.
|
Cloud Foundry CLI Skill
You are an expert in the Cloud Foundry CLI (v8). Help users construct correct cf commands, write manifests, automate deployments, manage services, and troubleshoot issues. The goal is to save the user from constantly running cf help by giving them precise, runnable commands.
Important: v7 and v6 are no longer maintained. Always use v8 syntax. The v8 CLI is backed by the CC API v3.
Installation
Install from the V8 Installation Guide. Available via package managers (Homebrew, apt, yum, Chocolatey) or binary download.
Verify: cf version
Authentication & Targeting
cf api
Sets the API endpoint for your Cloud Foundry instance.
cf api https://api.example.com
cf api https://api.example.com --skip-ssl-validation
cf api
cf login
Interactive login — prompts for anything not provided:
cf login
cf login -a https://api.example.com
cf login -a https://api.example.com -u user@example.com
cf login -a https://api.example.com --sso
cf login -o my-org -s dev
| Flag | Description |
|---|
-a | API endpoint URL |
-u | Username |
-p | Password (avoid — recorded in shell history) |
-o | Target organization |
-s | Target space |
--sso | SSO via one-time passcode from the login URL |
--sso-passcode <code> | Provide SSO passcode directly |
--origin <origin> | Specify identity provider origin |
--skip-ssl-validation | Skip SSL cert verification |
cf auth
Non-interactive authentication for scripts and CI/CD:
cf auth username password
cf auth username password --origin ldap
cf auth --client-credentials
cf target
Switches org and space context after login:
cf target -o my-org -s dev
cf target -s staging
cf target
cf logout
cf logout
App Lifecycle
cf push (alias: p)
The most important command — deploys an app.
cf push my-app
cf push my-app -p ./build
cf push my-app -f manifest.yml
cf push my-app -b nodejs_buildpack
cf push my-app -i 3 -m 512M -k 1G
cf push my-app --no-start
cf push my-app --no-route
cf push my-app --random-route
cf push my-app --strategy rolling
cf push my-app --docker-image my-registry/my-image:tag
cf push -f manifest.yml --var host=my-host
cf push -f manifest.yml --vars-file vars.yml
Key flags: -b buildpack, -c command, -f manifest, -i instances, -k disk, -m memory, -p path, -s stack, -t timeout, -u health-check-type (port/http/process), -o/--docker-image, --docker-username (password via CF_DOCKER_PASSWORD), --droplet, --endpoint, --no-manifest, --no-route, --no-start, --no-wait, --random-route, --strategy (rolling/null), --task, --var KEY=VALUE, --vars-file PATH.
Push env vars: CF_DOCKER_PASSWORD, CF_STAGING_TIMEOUT=15 (min), CF_STARTUP_TIMEOUT=5 (min).
App Management
cf apps
cf app my-app
cf start my-app
cf stop my-app
cf restart my-app
cf restage my-app
cf delete my-app
cf delete my-app -f
cf delete my-app -r
cf rename my-app new-name
cf scale my-app -i 5
cf scale my-app -m 1G -k 2G
cf scale my-app -i 5 -m 1G
Deployment & Rollback
cf push my-app --strategy rolling
cf cancel-deployment my-app
Logs & Events
cf logs my-app
cf logs my-app --recent
cf events my-app
SSH
cf ssh my-app
cf ssh my-app -i 2
cf ssh my-app -c "cat /app/config.yml"
cf enable-ssh my-app / cf disable-ssh my-app / cf ssh-enabled my-app
Tasks
cf run-task my-app --command "rake db:migrate"
cf run-task my-app -c "rake db:migrate" -m 512M
cf tasks my-app
cf terminate-task my-app TASK_ID
Environment Variables
cf env my-app
cf set-env my-app DATABASE_URL "postgres://..."
cf unset-env my-app DATABASE_URL
cf restage my-app
After set-env or unset-env, you need to restage or restart the app for changes to apply.
Health Checks
cf get-health-check my-app
cf set-health-check my-app http --endpoint /health
cf set-health-check my-app port
cf set-health-check my-app process
Packages & Droplets
cf packages my-app / cf create-package my-app
cf droplets my-app / cf set-droplet my-app GUID
cf download-droplet my-app / cf stage-package my-app --package-guid GUID
Manifests
The manifest (manifest.yml) declares app configuration. CF reads it automatically from the current directory during cf push.
---
applications:
- name: my-app
memory: 512M
disk_quota: 1G
instances: 2
buildpacks:
- nodejs_buildpack
command: node server.js
health-check-type: http
health-check-http-endpoint: /health
timeout: 120
stack: cflinuxfs4
env:
NODE_ENV: production
LOG_LEVEL: info
routes:
- route: my-app.example.com
- route: my-app.example.com/api
services:
- my-database
- my-redis
processes:
- type: web
instances: 2
memory: 512M
- type: worker
instances: 1
memory: 256M
command: node worker.js
health-check-type: process
no-route: true
Variable substitution in manifests:
applications:
- name: ((app-name))
instances: ((instances))
cf push --var app-name=my-app --var instances=3
cf push --vars-file production.yml
Create manifest from running app:
cf create-app-manifest my-app
cf create-app-manifest my-app -p ./out
Services
Marketplace
cf marketplace
cf marketplace -e SERVICE_NAME
cf marketplace -s SERVICE_NAME
Service Instances
cf services
cf service my-db
cf create-service SERVICE PLAN NAME
cf create-service postgres standard my-db
cf create-service postgres standard my-db -c '{"storage":"50gb"}'
cf create-service postgres standard my-db -c config.json
cf create-service postgres standard my-db -t "env:prod,team:api"
cf update-service my-db -p premium
cf update-service my-db -c '{"key":"val"}'
cf upgrade-service my-db
cf delete-service my-db
cf delete-service my-db -f
cf rename-service my-db new-db-name
Binding & Unbinding
cf bind-service my-app my-db
cf bind-service my-app my-db -c '{"role":"admin"}'
cf unbind-service my-app my-db
cf restage my-app
Binding injects credentials into VCAP_SERVICES env var.
Service Keys
Service keys let you get credentials without binding to an app:
cf create-service-key my-db my-key
cf create-service-key my-db my-key -c '{"permissions":"read-only"}'
cf service-keys my-db
cf service-key my-db my-key
cf delete-service-key my-db my-key
User-Provided Services
For external services not in the marketplace:
cf create-user-provided-service my-ext -p "host, port, username, password"
cf cups my-ext -p '{"host":"db.example.com","port":"5432","user":"admin","password":"secret"}'
cf cups my-logger -l syslog://logs.example.com:514
cf cups my-proxy -r https://proxy.example.com
cf update-user-provided-service my-ext -p '{"password":"new-secret"}'
cups is the alias for create-user-provided-service, uups for update-user-provided-service.
Service Sharing & Route Services
cf share-service my-db -s other-space [-o other-org]
cf unshare-service my-db -s other-space
cf bind-route-service example.com my-proxy --hostname my-app
cf unbind-route-service example.com my-proxy --hostname my-app
Routes & Domains
Domains
cf domains
cf create-private-domain my-org apps.internal
cf delete-private-domain apps.internal
cf create-shared-domain shared.example.com
cf delete-shared-domain shared.example.com
cf router-groups
Routes
cf routes
cf route my-app.example.com
cf create-route example.com --hostname my-app
cf create-route apps.internal --hostname backend
cf create-route example.com --hostname my-app --path /api
cf map-route my-app example.com --hostname my-app
cf unmap-route my-app example.com --hostname my-app
cf delete-route example.com --hostname my-app
cf delete-orphaned-routes
cf check-route example.com --hostname my-app
Orgs & Spaces
Organizations
cf orgs
cf org my-org
cf create-org my-org
cf delete-org my-org
cf rename-org my-org new-org
Spaces
cf spaces
cf space dev
cf create-space staging
cf delete-space staging
cf rename-space staging production
cf apply-manifest -f manifest.yml
Space SSH
cf allow-space-ssh SPACE / cf disallow-space-ssh SPACE / cf space-ssh-allowed SPACE
User & Role Management
cf org-users my-org
cf space-users my-org dev
cf set-org-role user@example.com my-org OrgManager
cf unset-org-role user@example.com my-org OrgManager
cf set-space-role user@example.com my-org dev SpaceDeveloper
cf unset-space-role user@example.com my-org dev SpaceDeveloper
Administration
Buildpacks: cf buildpacks (list), cf create-buildpack NAME PATH POSITION, cf update-buildpack NAME -p PATH, cf delete-buildpack NAME.
Network policies: cf network-policies, cf add-network-policy APP DEST --protocol tcp --port 8080, cf remove-network-policy APP DEST --protocol tcp --port 8080.
Security groups: cf security-groups, cf create-security-group NAME rules.json, cf bind-security-group NAME ORG SPACE --lifecycle running, cf bind-running-security-group NAME (global default).
Quotas: cf org-quotas, cf create-org-quota NAME -m 10G -i 100 -r 50 -s 20, cf set-org-quota ORG QUOTA. Space quotas: cf space-quotas, cf create-space-quota NAME -m 5G, cf set-space-quota SPACE QUOTA.
Feature flags: cf feature-flags, cf enable-feature-flag FLAG, cf disable-feature-flag FLAG.
Advanced Commands
cf curl
Direct API calls — invaluable for automation and debugging:
cf curl /v3/apps
cf curl /v3/apps/APP_GUID
cf curl /v3/apps -X POST -d '{"name":"my-app","relationships":{"space":{"data":{"guid":"SPACE_GUID"}}}}'
cf curl "/v3/apps?names=my-app"
cf config
cf config --trace true
cf config --trace /tmp/cf-trace.log
cf config --color false
cf config --locale en-US
cf oauth-token
cf oauth-token
Environment Variables
| Variable | Description |
|---|
CF_HOME | Override ~/.cf config directory location |
CF_TRACE | true to enable API tracing, or a file path for trace logs |
CF_COLOR | false to disable colored output |
CF_DOCKER_PASSWORD | Docker registry password for cf push --docker-image |
CF_STAGING_TIMEOUT | Max minutes to wait for staging (default: 15) |
CF_STARTUP_TIMEOUT | Max minutes to wait for app start (default: 5) |
CF_DIAL_TIMEOUT | Max seconds for API connection (default: 5) |
Plugins
cf plugins
cf install-plugin PLUGIN
cf install-plugin -r CF-Community my-plugin
cf uninstall-plugin my-plugin
cf repo-plugins
cf list-plugin-repos
cf add-plugin-repo CF-Community https://plugins.cloudfoundry.org
cf remove-plugin-repo CF-Community
Plugin code uses import "code.cloudfoundry.org/cli/v9/plugin".
MTA / Multiapps Plugin (cf deploy)
CAP applications and MTA projects are deployed as .mtar archives using the multiapps CF CLI plugin. This provides the cf deploy command (distinct from cf push).
Install the plugin and build tool
Before running mbt build or cf deploy, verify both tools are present. Run these checks and install if missing:
if ! command -v mbt &>/dev/null; then
echo "mbt not found — installing..."
npm install -g mbt
else
echo "mbt $(mbt --version) already installed"
fi
if ! cf plugins | grep -q multiapps; then
echo "multiapps plugin not found — installing..."
cf install-plugin multiapps -f
else
echo "multiapps plugin already installed"
cf plugins | grep multiapps
fi
Build and deploy an MTA
mbt build
cf deploy mta_archives/<app>_1.0.0.mtar
cf deploy mta_archives/<app>_1.0.0.mtar -e config.mtaext
cf mta-ops
cf mta <mta-id>
cf mtas
cf undeploy <mta-id> --delete-services
Troubleshooting cf deploy
| Error | Cause | Fix |
|---|
unknown command 'deploy' | multiapps plugin not installed | cf install-plugin multiapps |
service plan 'extended' not available | AI Core extended plan not entitled or org plan restricted | Check BTP entitlements; extended plan required for CAP with AI Core |
MTA ID already exists | Previous deploy left partial state | cf undeploy <mta-id> then retry |
Build fails with npm errors | Node version mismatch in mta.yaml | Ensure engines.node in package.json matches CF buildpack version |
Troubleshooting
Common Issues
| Symptom | Likely Cause | Fix |
|---|
FAILED - Not logged in | Token expired or not authenticated | Run cf login again |
FAILED - No org/space targeted | Missing target context | Run cf target -o ORG -s SPACE |
| App crashes on push | Bad start command or missing deps | Check cf logs APP --recent for errors |
| Staging fails | Wrong buildpack or missing files | Verify buildpack with -b, check .cfignore |
CF_STAGING_TIMEOUT exceeded | App takes too long to stage | Increase CF_STAGING_TIMEOUT or optimize build |
| SSL cert errors | Self-signed certs | Use --skip-ssl-validation (dev only) or install certs |
| Route already exists | Another app/space owns the route | Use cf routes to find it, or use --random-route |
| Service bind fails | Service not ready or wrong space | Check cf service SERVICE status |
Debugging Steps
- Check logs:
cf logs my-app --recent — always the first thing to try
- Enable tracing:
CF_TRACE=true cf push my-app — see API requests/responses
- Check events:
cf events my-app — see recent crashes, restages, scaling
- SSH in:
cf ssh my-app — inspect the running container
- Check env:
cf env my-app — verify VCAP_SERVICES and user env vars
- API debug:
cf curl /v3/apps/GUID/processes — inspect process-level details
Verifying Command Success
cf push my-app
echo $?
Common Workflows
Deploy a Node.js app with a Postgres service
cf login -a https://api.example.com --sso
cf target -o my-org -s dev
cf create-service postgres standard my-db
cf push my-app -b nodejs_buildpack
cf bind-service my-app my-db
cf restage my-app
Zero-downtime deployment
cf push my-app --strategy rolling
cf cancel-deployment my-app
CI/CD pipeline pattern
cf api https://api.example.com
cf auth "$CF_USERNAME" "$CF_PASSWORD"
cf target -o my-org -s production
cf push my-app -f manifest-prod.yml --strategy rolling --no-wait
Scale based on load
cf scale my-app -i 10
cf scale my-app -m 1G