Start here with your SLICE_ID and SLICE_TOKEN. The
overview shows the credentials file and
shell setup. You do not need a service token yet.
A slice is your shared CPU, memory and storage allocation. It can contain several independent applications. Deploying one application does not deploy its neighbours. All persistent volumes count towards combined storage usage, including WordPress files and its database. BudgetHost creates the initial slice and manages its limits.
Inspect your slice#
Run the initial credentials and shell setup
first. Continue in the same shell, using SLICE_BASE, STATE, slice_api and uuid.
slice_api "$SLICE_BASE" > "$STATE/slice.json"
jq .data "$STATE/slice.json"
Inspect existing applications and storage before creating anything. If your
application already exists, set SERVICE_ID to its ID from the inventory and skip
the creation request. Then continue to get a service token.
Do not create a second application or database volume for an existing deployment.
Create an application#
For an empty slice or a new application, keep the request body, key and returned operation ID. Retry with the same key and body after a lost response.
uuid > "$STATE/application.key"
printf '%s\n' '{"type":"application","display_name":"My App"}' > "$STATE/application-request.json"
slice_api -H 'Content-Type: application/json' \
-H "X-Idempotency-Key: $(cat "$STATE/application.key")" \
--data-binary @"$STATE/application-request.json" "$SLICE_BASE/services" \
> "$STATE/application.json"
SERVICE_ID=$(jq -er '.data.service_id' "$STATE/application.json")
Get a service token#
Use your slice token to issue a narrower token for the selected application:
slice_api -X POST "$SLICE_BASE/services/$SERVICE_ID/deployment-tokens" \
> "$STATE/service-token.json"
SERVICE_TOKEN=$(jq -er '.data.token' "$STATE/service-token.json")
jq '.data | del(.token)' "$STATE/service-token.json"
Store the token securely, along with its returned expiry date. This issuance endpoint is not idempotent: repeating it issues another token. If its response is lost, open your application's API tokens in my.budgethost to revoke the inaccessible token before issuing a replacement. You can also create, renew and revoke service tokens in my.budgethost without using this endpoint.
Save the returned credentials in a private directory outside your source tree. This does not print the token or put it in the application source tree:
SERVICE_ENV="$HOME/.config/budgethost/$SERVICE_ID.env"
mkdir -p "$(dirname "$SERVICE_ENV")"
printf 'SERVICE_ID=%q\nSERVICE_TOKEN=%q\n' \
"$SERVICE_ID" "$SERVICE_TOKEN" > "$SERVICE_ENV"
chmod 600 "$SERVICE_ENV"
Continue with application configuration and deployment
in the same shell. Keep SERVICE_ENV for future releases; those releases use the
service token and do not need to create the application or issue another token.
Storage#
Create storage and attach it to a member in the same request:
uuid > "$STATE/storage.key"
jq -n --arg service "$SERVICE_ID" \
'{name:"data",service_id:$service,mount_path:"/data"}' > "$STATE/storage-request.json"
slice_api -H 'Content-Type: application/json' \
-H "X-Idempotency-Key: $(cat "$STATE/storage.key")" \
--data-binary @"$STATE/storage-request.json" "$SLICE_BASE/storage" \
> "$STATE/storage.json"
Alternatively, POST /storage with {"name":"archive"} creates unattached storage.
POST /storage/attach accepts storage_id, service_id, and mount_path to attach
slice-owned storage to a member. It also requires an idempotency key. Inspect slice
inventory first; do not assume that failed requests created nothing. A service token
can create storage only for its own service using its /storage endpoint.
Storage attachment changes desired configuration. Deploy/apply the affected application to use the new mount. Do not put databases or customer files solely in the container's writable layer; replacing the container does not preserve it.
Operations and WordPress#
If you created an application in this session, inspect its returned operation ID:
OPERATION_ID=$(jq -er '.data.operation_id' "$STATE/application.json")
slice_api "$SLICE_BASE/operations/$OPERATION_ID" | jq .data
SLICE_OPERATION_INCOMPLETE means provisioning was interrupted. Inspect the
operation and slice inventory, then open the application in my.budgethost to review its
progress and failure details. Contact support if reconciliation is needed; do not
retry with a new key to bypass the incomplete operation.
To provision WordPress, send {"type":"wordpress","display_name":"My Site"} to
POST /services with a new key. This creates a bundle and its file/database storage.
Deploy the returned main service with POST /services/{serviceId}/apply and another
idempotency key. The 202 response and a succeeded provisioning operation mean runtime
work was queued, not that the website passed health checks. Follow the application
in my.budgethost to see deployment progress, health and any failure details. Confirm it
is healthy before treating the release as complete. Source/image applications use deployment polling described in the
application guide.