Skip to content

openteams-ai/terraform-pocketbase-gcp-deploy

Repository files navigation

PocketBase on GCP (Cloud Run + GCS FUSE) Terraform Module

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.

Features

  • πŸš€ 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)

Quick Start

  1. Add this module to your configuration
  2. Provide PocketBase image (built with any required plugins)
  3. (Optional) Provide frontend container image
  4. (Optional) Enable Cloudflare DNS + supply zone ID and base domain
  5. Apply and retrieve output service URLs

Architecture Overview

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.

Module Documentation

The following section contains auto-generated documentation (terraform-docs):

Usage

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"
}

Requirements

Name Version
terraform >= 1.8.0
cloudflare ~> 5.8.4
google ~> 7.0.0
random ~> 3.7.2

Providers

Name Version
cloudflare ~> 5.8.4
google ~> 7.0.0
random ~> 3.7.2

Modules

No modules.

Resources

Name Type
cloudflare_dns_record.pocketbase resource
google_cloud_run_domain_mapping.pocketbase resource
google_cloud_run_v2_service.pocketbase resource
google_cloud_run_v2_service_iam_member.pb_invoker resource
google_project_service.required_apis resource
google_secret_manager_secret.pb_admin_password resource
google_secret_manager_secret.pb_encryption_key resource
google_secret_manager_secret_iam_member.pb_admin_password_access resource
google_secret_manager_secret_iam_member.pb_encryption_key_access resource
google_secret_manager_secret_version.pb_admin_password_v1 resource
google_secret_manager_secret_version.pb_encryption_key_v1 resource
google_service_account.pb resource
google_storage_bucket.pb_backups_bucket resource
google_storage_bucket.pb_litestream_bucket resource
google_storage_bucket.pb_s3_bucket resource
google_storage_bucket_iam_member.pb_backups_bucket_admin resource
google_storage_bucket_iam_member.pb_backups_bucket_admin_existing resource
google_storage_bucket_iam_member.pb_litestream_bucket_admin resource
google_storage_bucket_iam_member.pb_s3_bucket_admin resource
google_storage_bucket_iam_member.pb_s3_bucket_admin_existing resource
random_bytes.pb_encryption_key resource
random_password.pb_admin_password resource
google_storage_bucket.pb_backups_bucket data source
google_storage_bucket.pb_s3_bucket data source

Inputs

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({
cpu = number
memory = string
})
{
"cpu": 1,
"memory": "512Mi"
}
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

Outputs

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

Documentation Maintenance

Content between the terraform-docs markers is auto-generated. Run:

make docs

to refresh after changing inputs/outputs.

Testing

Terratest scaffold is included (validation-focused). Run:

make test

Enhance tests as you adopt this module.

Makefile Highlights

Common targets:

  • make init – init + install hooks
  • make fmt – format
  • make validate – terraform validate
  • make lint – tflint + checks
  • make test – Terratest
  • make docs – regenerate docs

Notes

  • 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 = false and handle IAM bindings externally.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •