1---
2title: Setup
3description: Connect alchemy to Google Cloud — project, service-account key, the APIs to enable, and Docker.
4---
5
6## What you need
7
8- **A GCP project** and its id.
9- **A service-account key** with enough IAM to create what you deploy.
10 A working starting point is Cloud Run Admin, Storage Admin, Pub/Sub
11 Admin, Service Account Admin (Alchemy mints a per-host `alch-*`
12 runtime account), and Project IAM Admin (it grants roles to that
13 account). Add the admin role for anything else you declare —
14 Firestore, BigQuery, Secret Manager.
15- **Docker running locally.** `GCP.Function`, `GCP.Run.Service`,
16 `GCP.Run.Job`, and `GCP.Run.WorkerPool` bundle your code and build a
17 container image before pushing it to Artifact Registry.
18- **The APIs enabled** on the project for whatever you use:
19 `run.googleapis.com`, `artifactregistry.googleapis.com`,
20 `iam.googleapis.com`, `cloudresourcemanager.googleapis.com`, plus the
21 service-specific ones (`firestore.googleapis.com`,
22 `secretmanager.googleapis.com`, `pubsub.googleapis.com`,
23 `bigquery.googleapis.com`, `redis.googleapis.com`).
24
25```sh
26gcloud services enable run.googleapis.com artifactregistry.googleapis.com \
27 iam.googleapis.com cloudresourcemanager.googleapis.com
28```
29
30## Credentials
31
32Run `alchemy profile edit --add GCP`, choose **Service account JSON**,
33and point at the key file. Alchemy stores it under
34`~/.alchemy/credentials/<profile>/`.
35
36In CI (`CI=true`), Alchemy skips profiles and reads the environment:
37
38- `GOOGLE_PROJECT_ID` — project id (`GOOGLE_CLOUD_PROJECT` is accepted
39 as an alias).
40- `GOOGLE_APPLICATION_CREDENTIALS` — path to the key file.
41
42Or `GOOGLE_ACCESS_TOKEN` plus `GOOGLE_PROJECT_ID` for a short-lived
43token. On GKE with Workload Identity, neither is needed — the metadata
44server is the last link in the chain.
45
46See [Profiles](/environments/profiles) for how credentials are stored
47and switched.
48
49## Register the provider
50
51```typescript
52// alchemy.run.ts
53import * as Alchemy from "alchemy";
54import * as GCP from "alchemy/GCP";
55import * as Effect from "effect/Effect";
56
57export default Alchemy.Stack(
58 "App",
59 { providers: GCP.providers(), state: Alchemy.localState() },
60 Effect.gen(function* () {
61 return {};
62 }),
63);
64```
65
66`GCP.providers()` merges next to any other cloud's providers, so a
67single stack can span GCP and Cloudflare or AWS.
68
69## Choose a region
70
71Regional resources created without a `location` / `region` prop land in
72the default region. It comes with the credential (the profile's
73`region`, which `alchemy profile` asks for), else `us-central1`. To pin
74a stack to a region regardless of the credential, provide
75`GCP.Region(...)`:
76
77```typescript
78export default Alchemy.Stack(
79 "App",
80 {
81 providers: GCP.providers().pipe(
82 Layer.provideMerge(GCP.Region("europe-west1")),
83 ),
84 state: Alchemy.localState(),
85 },
86 program,
87);
88```
89
90A resource that should live elsewhere takes an explicit `location`.
91Changing the stack region never moves a deployed resource: its recorded
92location wins.
93
94Requests for regional resources that Google only serves from a regional
95endpoint (Secret Manager, Parameter Manager) go to
96`{service}.{region}.rep.googleapis.com` automatically. For data
97residency, send every regional request to its regional endpoint:
98
99```typescript
100GCP.providers().pipe(
101 Layer.provideMerge(GCP.RegionalEndpoints("prefer")),
102);
103```
104
105## Cleaning up
106
107`alchemy destroy` removes what a stack created, including the per-host
108service accounts and their role grants. For a test project that has
109drifted, `pnpm nuke:gcp` deletes Alchemy-managed resources across the
110whole project — including every service account stamped
111`alchemy-host`. Do not point it at a project you care about.
112
113## Next steps
114
115- [GCP overview](/gcp) — hosts, resources, and bindings.
116- [Serve an API on Cloud Run](/gcp/guides/cloud-run-api) — the first
117 thing to build.