> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phala.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run a Workload on GCP

> Step-by-step guide to deploy a Docker application as a dstack CVM on GCP with Intel TDX.

# Run a Workload on GCP

Deploy a Docker application as a dstack CVM on GCP with Intel TDX. This page covers the full workflow — from configuration to verification — including how to choose between managed and self-hosted KMS endpoints.

***

## Prerequisites

* A GCP project with Confidential VM quota enabled
  * Intel TDX Confidential VMs are available in select zones (for example `us-central1-a`)
* `gcloud` CLI installed and authenticated
  ```bash theme={"system"}
  gcloud auth login
  gcloud config set project YOUR_PROJECT_ID
  ```
* Linux host for deployment (recommended)
* Docker installed
* `gsutil` available in PATH
* `mtools` (`mcopy`) and `dosfstools` (`mkfs.fat`) installed
* `dstack-cloud` CLI installed
  ```bash theme={"system"}
  curl -fsSL -o ~/.local/bin/dstack-cloud \
    https://raw.githubusercontent.com/Phala-Network/meta-dstack-cloud/main/scripts/bin/dstack-cloud
  chmod +x ~/.local/bin/dstack-cloud
  ```

> Why Linux + mtools + dosfstools? `dstack-cloud deploy` builds a shared FAT image and needs these tools in local environment.

***

## Step 1: Configure `dstack-cloud`

Edit global config:

```bash theme={"system"}
dstack-cloud config-edit
```

`dstack-cloud` uses **JSON** config (`~/.config/dstack-cloud/config.json`). Example:

```json theme={"system"}
{
  "services": {
    "kms_urls": ["https://kms.tdxlab.dstack.org:12001"],
    "gateway_urls": ["https://gateway.tdxlab.dstack.org:12002"],
    "pccs_url": ""
  },
  "image_search_paths": ["/path/to/images"],
  "gcp": {
    "project": "YOUR_PROJECT_ID",
    "zone": "us-central1-a",
    "bucket": "gs://YOUR_BUCKET_NAME"
  }
}
```

Create bucket if needed:

```bash theme={"system"}
gcloud storage buckets create gs://YOUR_BUCKET_NAME --project YOUR_PROJECT_ID --location us-central1
```

### KMS Options

| Option                 | Description                                      | When to Use                          |
| ---------------------- | ------------------------------------------------ | ------------------------------------ |
| **Phala Official KMS** | Use managed KMS endpoints in `services.kms_urls` | Quick start, testing                 |
| **Self-hosted KMS**    | Use your own KMS endpoint in `services.kms_urls` | Production, compliance, full control |

For Self-hosted KMS, point `services.kms_urls` to your deployed KMS URL (see [Run a dstack-kms CVM on GCP](run-kms-on-gcp) for how to set one up).

If you run with key provider `tpm`/`none` (no external KMS), remove `.env` in project and remove `env_file` from `app.json`.

***

## Step 2: Pull the OS Image

For `dstack-cloud-0.6.0`, download both archives:

```bash theme={"system"}
dstack-cloud pull https://github.com/Phala-Network/meta-dstack-cloud/releases/download/v0.6.0-test/dstack-cloud-0.6.0.tar.gz
dstack-cloud pull https://github.com/Phala-Network/meta-dstack-cloud/releases/download/v0.6.0-test/dstack-cloud-0.6.0-uki.tar.gz
```

Verify boot image file exists:

```bash theme={"system"}
ls -lh /path/to/images/dstack-cloud-0.6.0/disk.raw
```

> If `disk.raw` is missing, VM may boot-loop with UEFI `Failed to load image`.

***

## Step 3: Create a Project

```bash theme={"system"}
dstack-cloud new my-gcp-app --os-image dstack-cloud-0.6.0 --instance-name dstack-my-app
cd my-gcp-app
```

***

## Step 4: Configure Project (`app.json`)

Update key fields in `app.json`:

* `gcp_config.project`
* `gcp_config.zone`
* `gcp_config.bucket`
* `gcp_config.instance_name`

Choose key provider mode:

* **External KMS mode (recommended):** `"key_provider": "kms"`
* **No external KMS mode:** `"key_provider": "tpm"` (or `none`)

Gateway options:

* If you use dstack gateway URL routing, keep `gateway_enabled: true`
* If you access service directly via VM public IP + opened port, set `gateway_enabled: false`

***

## Step 5: Define Your Application

Edit `docker-compose.yaml`:

```yaml theme={"system"}
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
```

***

## Step 6: (Optional) Add Environment Variables

If your app needs secrets/config, create `.env`:

```env theme={"system"}
API_KEY=your-api-key
DATABASE_URL=postgres://user:pass@host:5432/db
```

In KMS mode, env values are encrypted client-side and only decrypted inside CVM after attestation.

***

## Step 7: Deploy

```bash theme={"system"}
dstack-cloud deploy --delete
```

`dstack-cloud` will:

1. Prepare shared config files
2. Upload image artifacts to GCS
3. Create a GCP TDX Confidential VM
4. Start VM and run compose workload

First deployment usually takes several minutes.

***

## Step 8: Open Firewall

Open app port(s):

```bash theme={"system"}
dstack-cloud fw allow 8080
```

List firewall rules:

```bash theme={"system"}
dstack-cloud fw list
```

***

## Step 9: Verify

Check status:

```bash theme={"system"}
dstack-cloud status
```

View logs:

```bash theme={"system"}
dstack-cloud logs --follow
```

Access app:

* Direct VM mode (`gateway_enabled=false`):
  ```bash theme={"system"}
  curl http://<EXTERNAL_IP>:8080
  ```
* Gateway mode (`gateway_enabled=true`): use URL printed in `dstack-cloud status`.

***

## Managing Your Deployment

```bash theme={"system"}
dstack-cloud logs
dstack-cloud stop
dstack-cloud start
dstack-cloud remove
```

***

## Common Issues

| Issue                                               | Solution                                                                               |
| --------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `Boot image 'dstack-cloud-0.6.0' not found locally` | Ensure `disk.raw` exists under `<image_search_paths>/dstack-cloud-0.6.0/`              |
| VM RUNNING but serial log shows UEFI load failures  | Wrong boot image source; use official `-uki.tar.gz` image containing `disk.raw`        |
| `gsutil` not found                                  | Install Google Cloud SDK / ensure PATH                                                 |
| `mcopy` not found                                   | Install `mtools`                                                                       |
| `mkfs.fat` not found                                | Install `dosfstools`                                                                   |
| `.env found but KMS is not enabled`                 | Remove `.env` and remove `env_file` from `app.json`, or set key provider back to `kms` |
| App not reachable immediately                       | Wait for compose startup to complete; check `dstack-cloud logs`                        |

***

## Next Steps

* [Run a dstack-kms CVM on GCP](run-kms-on-gcp)
* [Attestation Integration](/dstack-cloud/attestation-integration)
* [Run a Workload on AWS Nitro](run-on-nitro)
