Run a persistent Apus Gateway on a Debian Compute Engine VM. This page covers GCP provisioning, network access, and machine operations; the shared Docker VM runtime page owns container setup, persistence, custom binaries, verification, and updates.

Pricing varies by machine type and region. Use at least 6 GB RAM for a source image build. On a smaller machine, use the official pre-built image described in Docker VM runtime.

What you need

Provision the VM

Initialize gcloud

Install the CLI from
[cloud.google.com/sdk/docs/install](https://cloud.google.com/sdk/docs/install),
then authenticate:

```bash
gcloud init
gcloud auth login
```

You can perform the same steps in the Cloud Console.

Create the project

```bash
gcloud projects create my-apus-project --name="Apus Gateway"
gcloud config set project my-apus-project
gcloud services enable compute.googleapis.com
```

Enable billing in the
[Billing console](https://console.cloud.google.com/billing). Compute Engine
will not start without it.

Choose a machine

| Type          | Specs                   | Notes                                  |
| ------------- | ----------------------- | -------------------------------------- |
| e2-standard-2 | 2 vCPU, 8 GB RAM        | Recommended for source image builds    |
| e2-medium     | 2 vCPU, 4 GB RAM        | Use the official pre-built image       |
| e2-small      | 2 vCPU, 2 GB RAM        | Use the official pre-built image       |

Create a Debian 12 VM:

```bash
gcloud compute instances create apus-gateway \
  --zone=us-central1-a \
  --machine-type=e2-standard-2 \
  --boot-disk-size=20GB \
  --image-family=debian-12 \
  --image-project=debian-cloud
```

Review firewall access

Keep TCP 18789 closed to the public Internet. The SSH tunnel below needs
only SSH access to the VM:

```bash
gcloud compute firewall-rules list \
  --format='table(name,network,direction,sourceRanges.list():label=SOURCE_RANGES,allowed[].map().firewall_rule().list():label=ALLOW)'
```

Restrict SSH source ranges to your administrative network when possible.
If you intentionally expose the Gateway through a reverse proxy or tailnet,
follow [Gateway security](/gateway/security) rather than adding a broad
`0.0.0.0/0` rule for port 18789.

Connect over SSH

```bash
gcloud compute ssh apus-gateway --zone=us-central1-a
```

SSH key propagation can take a minute or two after VM creation. Wait and
retry if the first connection is refused.

Install Docker

On the VM:

```bash
sudo apt-get update
sudo apt-get install -y git curl ca-certificates
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker "$USER"
exit
```

Reconnect so the group change takes effect, then verify the installation:

```bash
gcloud compute ssh apus-gateway --zone=us-central1-a
docker --version
docker compose version
```

Configure the Docker runtime

On the VM, follow Docker VM runtime from Before you begin through Verify and administer the Gateway. The maintained setup script uses these GCP host paths by default:

export APUS_CONFIG_DIR="$HOME/.apus"
export APUS_WORKSPACE_DIR="$HOME/.apus/workspace"
export APUS_AUTH_PROFILE_SECRET_DIR="$HOME/.apus-auth-profile-secrets"

If a source build ends with Killed, ResourceExhausted, or exit code 137, resize the VM before retrying.

Access the Control UI

From your laptop, open an SSH tunnel and leave it running:

gcloud compute ssh apus-gateway --zone=us-central1-a -- -L 18789:127.0.0.1:18789

Open http://127.0.0.1:18789/. Paste the Gateway token from the VM's .env when prompted. To reprint the dashboard URL or approve a browser device, run on the VM:

cd apus
docker compose run --rm apus-cli dashboard --no-open
docker compose run --rm apus-cli devices list
docker compose run --rm apus-cli devices approve <requestId>

Troubleshooting

SSH connection refused

Wait one or two minutes for SSH key propagation, then retry. Check the VM is running and that an ingress firewall rule allows TCP 22 from your current network.

OS Login issues

gcloud compute os-login describe-profile

Ensure your account has Compute OS Login or Compute OS Admin Login permission.

Resize after an out-of-memory build

gcloud compute instances stop apus-gateway --zone=us-central1-a
gcloud compute instances set-machine-type apus-gateway \
  --zone=us-central1-a \
  --machine-type=e2-medium
gcloud compute instances start apus-gateway --zone=us-central1-a

Use a deployment service account

For personal setup, your user account is enough. Automation should use a dedicated service account with the narrowest role that works:

gcloud iam service-accounts create apus-deploy \
  --display-name="Apus Deployment"

gcloud projects add-iam-policy-binding my-apus-project \
  --member="serviceAccount:apus-deploy@my-apus-project.iam.gserviceaccount.com" \
  --role="roles/compute.instanceAdmin.v1"

Avoid the Owner role. See Understanding roles.

Next steps

Related