Setup
Install
Section titled “Install”pnpm add https://pkg.alchemy.run/alchemy/pr:2930:51c662a https://pkg.alchemy.run/@alchemy.run/gcp/pr:2930:51c662a effect @effect/platform-bun @effect/platform-nodebun add https://pkg.alchemy.run/alchemy/pr:2930:51c662a https://pkg.alchemy.run/@alchemy.run/gcp/pr:2930:51c662a effect @effect/platform-bun @effect/platform-nodenpm install https://pkg.alchemy.run/alchemy/pr:2930:51c662a https://pkg.alchemy.run/@alchemy.run/gcp/pr:2930:51c662a effect @effect/platform-bun @effect/platform-nodeyarn add https://pkg.alchemy.run/alchemy/pr:2930:51c662a https://pkg.alchemy.run/@alchemy.run/gcp/pr:2930:51c662a effect @effect/platform-bun @effect/platform-nodeWhat you need
Section titled “What you need”- Node.js 24.11.1+ or Bun.
- A GCP project and its id.
- Credentials with enough IAM to create what you deploy: your own
Google account through
gcloud, or a service-account key. A working starting point is Cloud Run Admin, Storage Admin, Pub/Sub Admin, Service Account Admin (Alchemy creates analch-*service account for each runtime), and Project IAM Admin (it grants roles to that account). Add the admin role for anything else you declare — Firestore, BigQuery, Secret Manager. - Docker running locally.
GCP.Function,GCP.Run.Service,GCP.Run.Job, andGCP.Run.WorkerPoolbundle your code and build a container image before pushing it to Artifact Registry. - The APIs enabled on the project for whatever you use:
run.googleapis.com,artifactregistry.googleapis.com,iam.googleapis.com,cloudresourcemanager.googleapis.com, plus the service-specific ones (firestore.googleapis.com,secretmanager.googleapis.com,pubsub.googleapis.com,bigquery.googleapis.com,redis.googleapis.com).
gcloud services enable run.googleapis.com artifactregistry.googleapis.com \ iam.googleapis.com cloudresourcemanager.googleapis.comCredentials
Section titled “Credentials”Run alchemy profile edit --add GCP and choose gcloud login, then pick
a gcloud configuration. Alchemy signs in to it with gcloud auth login if
it has no login yet, and deploys as its account into its project and
compute/region. It never activates the configuration, so each Alchemy
profile can use a different Google account while your gcloud stays as it is.
alchemy profile edit --add GCP# when the login expires or is revoked:alchemy profile refresh --provider GCPThe profile names the configuration and nothing else, so no token is copied into it:
// ~/.alchemy/profiles/<name>/gcp.json{ "method": "gcloud", "configuration": "work" }To set it up without prompts, create the configuration with gcloud first:
gcloud config configurations create work --no-activategcloud auth login --configuration=workgcloud config set project my-project --configuration=workalchemy profile edit --add GCP --method gcloud --set configuration=workA project or region in the profile overrides the configuration’s.
This needs the Google Cloud CLI. Creating projects without an organization or folder also needs it: Google only lets user accounts do that.
To deploy as a service account instead, choose Service account JSON and point at the key file. Alchemy stores the path in the profile.
Environment variables need no profile. When a token or key file is set,
Alchemy uses it instead of the profile, and in CI (CI=true) the
environment is the only source:
GOOGLE_PROJECT_ID— project id (GOOGLE_CLOUD_PROJECTis accepted as an alias).GOOGLE_APPLICATION_CREDENTIALS— path to the key file.
Or GOOGLE_ACCESS_TOKEN plus GOOGLE_PROJECT_ID for a short-lived
token. On GKE with Workload Identity, neither is needed — the metadata
server is the last link in the chain.
See Profiles for how credentials are stored and switched.
Register the provider
Section titled “Register the provider”import * as Alchemy from "alchemy";import * as GCP from "@alchemy.run/gcp";import * as Effect from "effect/Effect";
export default Alchemy.Stack( "App", { providers: GCP.providers(), state: GCP.state() }, Effect.gen(function* () { return {}; }),);GCP.providers() merges next to any other cloud’s providers, so a
single stack can span GCP and Cloudflare or AWS.
Choose a region
Section titled “Choose a region”Regional resources created without a location / region prop land in
the default region. It comes with the credential (the profile’s
region, which alchemy profile asks for), else us-central1. To pin
a stack to a region regardless of the credential, provide
GCP.Region(...):
export default Alchemy.Stack( "App", { providers: GCP.providers().pipe( Layer.provideMerge(GCP.Region("europe-west1")), ), state: GCP.state(), }, program,);A resource that should live elsewhere takes an explicit location.
Changing the stack region never moves a deployed resource: its recorded
location wins.
Requests for regional resources that Google only serves from a regional
endpoint (Secret Manager, Parameter Manager) go to
{service}.{region}.rep.googleapis.com automatically. For data
residency, send every regional request to its regional endpoint:
GCP.providers().pipe( Layer.provideMerge(GCP.RegionalEndpoints("prefer")),);Cleaning up
Section titled “Cleaning up”alchemy destroy removes what a stack created, including the per-host
service accounts and their role grants. For a test project that has
drifted, pnpm nuke:gcp deletes Alchemy-managed resources across the
whole project — including every service account stamped
alchemy-host. Do not point it at a project you care about.