Deploy a PocketBase instance to Google Cloud Run using a persistent GCS bucket mounted via Cloud Storage FUSE for pb_data, with an optional frontend service and optional Cloudflare-managed custom domains.
- π PocketBase served via Cloud Run (v2)
- πΎ Persistent storage using a GCS bucket (mounted with Cloud Storage FUSE)
- π Optional frontend (e.g. login UI / SPA) Cloud Run service
- π Optional unauthenticated or restricted access toggle
- π Optional Cloudflare DNS CNAME records + Cloud Run domain mappings
- οΏ½ Simple environment variable injection for services
- οΏ½ Minimal attack surface (Litestream, backups, extra buckets removed in this variant)
- Add this module to your configuration
- Provide PocketBase image (built with any required plugins)
- (Optional) Provide frontend container image
- (Optional) Enable Cloudflare DNS + supply zone ID and base domain
- Apply and retrieve output service URLs
PocketBase runs as a single Cloud Run service backed by a GCS bucket mounted using FUSE. Writes go directly to the mounted bucket. A lightweight optional frontend service can be deployed (e.g. SPA or auth UI). If Cloudflare DNS is enabled, the module provisions Cloud Run domain mappings and Cloudflare CNAME records (auth.<base_domain>, app.<base_domain> by default) pointing to ghs.googlehosted.com.
The following section contains auto-generated documentation (terraform-docs):
module "pocketbase_stack" {
source = "github.com/openteams-ai/terraform-pocketbase-gcp-deploy"
project_id = "my-gcp-project"
region = "us-central1"
name_prefix = "myapp-dev"
base_domain = "example.com"
cookie_domain = ".example.com"
pocketbase_image = "us-docker.pkg.dev/myproj/images/pocketbase:fuse"
enable_frontend_service = true
frontend_image = "us-docker.pkg.dev/myproj/images/web:latest"
}| Name | Version |
|---|---|
| terraform | >= 1.8.0 |
| cloudflare | ~> 5.8.4 |
| ~> 7.0.0 | |
| random | ~> 3.7.2 |
| Name | Version |
|---|---|
| cloudflare | ~> 5.8.4 |
| ~> 7.0.0 | |
| random | ~> 3.7.2 |
No modules.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| additional_env | Additional environment variables applied to PocketBase container | map(string) |
{} |
no |
| admin_email | Initial PocketBase admin email to bootstrap (used only on first deploy if container entrypoint supports it) | string |
"[email protected]" |
no |
| allow_unauthenticated | Allow unauthenticated invocation of services (public access) | bool |
true |
no |
| backups_cron | Cron expression for backups (leave empty to disable schedule if backups enabled; compose had no default) | string |
"" |
no |
| backups_cron_max_keep | Max number of backup archives to retain (compose default 5) | string |
"5" |
no |
| backups_s3_bucket | Bucket for PocketBase backups (can be same as s3_bucket) | string |
"" |
no |
| backups_s3_enabled | Enable periodic PocketBase backup uploads to object storage | bool |
false |
no |
| cloudflare_zone_id | Cloudflare Zone ID for the base domain | string |
"" |
no |
| cookie_domain | Cookie domain for PocketBase authentication (e.g. .example.com) | string |
n/a | yes |
| deployment_env | Logical deployment environment identifier (e.g. local, staging, prod) exposed as DEPLOYMENT_ENV | string |
"local" |
no |
| enable_cloudflare_dns | Whether to create Cloudflare DNS records for PocketBase and frontend | bool |
false |
no |
| labels | Optional map of labels applied to supported resources | map(string) |
{} |
no |
| name_prefix | Prefix used for naming resources (e.g. myapp-dev) | string |
n/a | yes |
| pb_auth_subdomain | Subdomain for PocketBase service (auth.example.com) | string |
"auth" |
no |
| pb_base_domain | Domain for PocketBase service (e.g. pb.example.com) | string |
"" |
no |
| pocketbase_image | Container image reference for PocketBase (supports Litestream if baked-in) | string |
n/a | yes |
| pocketbase_resources | Resource settings for the PocketBase Cloud Run container (cpu as number, memory as string like 512Mi / 1Gi) | object({ |
{ |
no |
| project_id | GCP project ID where resources will be deployed | string |
n/a | yes |
| region | Primary region for Cloud Run services and buckets | string |
"us-central1" |
no |
| s3_access_key | S3 access key (consider using a secret manager in production) | string |
"" |
no |
| s3_bucket | Primary S3 bucket name for PocketBase file storage | string |
"" |
no |
| s3_enabled | Enable S3-compatible (or GCS via S3 API) storage for PocketBase (docker-compose default false) | bool |
false |
no |
| s3_endpoint | Custom S3 endpoint (leave empty for AWS). Useful for MinIO or R2. | string |
"" |
no |
| s3_force_path_style | Force path-style addressing for S3 (compose default true) | bool |
true |
no |
| s3_region | Region for S3 bucket | string |
"us-east-1" |
no |
| s3_secret | S3 secret key (consider using a secret manager in production) | string |
"" |
no |
| Name | Description |
|---|---|
| cloudflare_pocketbase_record | Cloudflare record (subdomain) created for PocketBase (if enabled). |
| pb_admin_password | Bootstrap admin password (also stored in Secret Manager; rotate after first login) |
| pocketbase_service_account | Service account email used by PocketBase |
| pocketbase_url | Deployed PocketBase service base URL |
| storage_backups_bucket | Effective backups bucket name (may equal primary) |
| storage_primary_bucket | Effective primary object storage bucket name |
Content between the terraform-docs markers is auto-generated. Run:
make docs
to refresh after changing inputs/outputs.
Terratest scaffold is included (validation-focused). Run:
make test
Enhance tests as you adopt this module.
Common targets:
make initβ init + install hooksmake fmtβ formatmake validateβ terraform validatemake lintβ tflint + checksmake testβ Terratestmake docsβ regenerate docs
- This variant intentionally omits Litestream & backup automation.
- For production-grade backups, consider exporting SQLite periodically or enabling a replication strategy in a fork.
- If you need private-only services, set
allow_unauthenticated = falseand handle IAM bindings externally.