GCP Cloud Run

Google Cloud Run runs RegScale as a fully managed container on Google Cloud — without operating a Kubernetes cluster. Cloud Run handles ingress, TLS termination, and autoscaling. RegScale connects to an external Cloud SQL for SQL Server database, and uploaded files are stored in a Cloud Storage (GCS) bucket mounted into the container via Cloud Storage FUSE.

📘

Before you begin

Complete the Prerequisites (database, networking) and review the Sizing Guide. After deployment, follow the Post-Deployment Steps.

Architecture

  • RegScale Core Platform — the regscale/regscale container image running as a Cloud Run service, listening on HTTP port 80.
  • Ingress & TLS — Cloud Run provides a managed HTTPS endpoint and terminates TLS, so no container-level certificate is required.
  • SQL Server — an external Cloud SQL for SQL Server instance (SQL Server 2022+; see Prerequisites › Database Configuration). RegScale connects via a connection string.
  • File Storage — a Cloud Storage (GCS) bucket mounted into the container at /app/atlas-files using Cloud Storage FUSE for persistent, uploaded evidence.
  • Secrets — JWT, encryption, and database credentials are stored in Secret Manager and injected as environment variables.

Prerequisites

  1. The Google Cloud CLI (gcloud) and a GCP project, with these APIs enabled:
    gcloud services enable run.googleapis.com sqladmin.googleapis.com \
      secretmanager.googleapis.com storage.googleapis.com \
      artifactregistry.googleapis.com vpcaccess.googleapis.com
    
  2. Access to the RegScale image — Docker Hub (regscale/regscale:x.x.x.x) or Iron Bank (registry1.dso.mil/ironbank/regscale/regscale:x.x.x.x).
  3. An external Cloud SQL for SQL Server instance, SQL Server 2022+ with Full-Text Search enabled.
  4. A region to deploy into (examples use us-central1).

📘

Replace x.x.x.x with the RegScale release you want to deploy. The latest release tags can be found in the RegScale Changelog.

Step 1 — Mirror the Image to Artifact Registry

Cloud Run deploys most reliably from Artifact Registry. Copy the RegScale image from Docker Hub (or Iron Bank) into your project's registry:

gcloud artifacts repositories create regscale \
  --repository-format=docker --location=us-central1

gcloud auth configure-docker us-central1-docker.pkg.dev

docker pull regscale/regscale:x.x.x.x
docker tag regscale/regscale:x.x.x.x \
  us-central1-docker.pkg.dev/<project-id>/regscale/regscale:x.x.x.x
docker push us-central1-docker.pkg.dev/<project-id>/regscale/regscale:x.x.x.x

Step 2 — Create the Cloud Storage Bucket

gcloud storage buckets create gs://<project-id>-regscale-files --location=us-central1

Step 3 — Store Secrets in Secret Manager

Generate strong, unique keys (32-char hex, 32 UTF-8 bytes each):

echo "JWTSecretKey=$(openssl rand -hex 16)"
echo "EncryptionKey=$(openssl rand -hex 16)"

⚠️

Do not use openssl rand -base64 32 for these keys — it produces 44 characters (not 32 bytes) and will fail the legacy AES key-length check.

printf '<yourJWTSecretKey>'  | gcloud secrets create regscale-jwt-secret-key --data-file=-
printf '<yourEncryptionKey>' | gcloud secrets create regscale-encryption-key --data-file=-
printf 'Server=tcp:<cloudsql-private-ip>,1433;Initial Catalog=REGSCALE;Persist Security Info=False;User ID=<db_admin>;Password=<db_password>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;' \
  | gcloud secrets create regscale-sql-conn --data-file=-

Step 4 — Create a Service Account

Create a service account for the Cloud Run service and grant it access to the bucket and secrets:

gcloud iam service-accounts create regscale-run --display-name="RegScale Cloud Run"

SA="regscale-run@<project-id>.iam.gserviceaccount.com"

# Read/write access to the files bucket
gcloud storage buckets add-iam-policy-binding gs://<project-id>-regscale-files \
  --member="serviceAccount:$SA" --role="roles/storage.objectAdmin"

# Access to the secrets
for s in regscale-jwt-secret-key regscale-encryption-key regscale-sql-conn; do
  gcloud secrets add-iam-policy-binding $s \
    --member="serviceAccount:$SA" --role="roles/secretmanager.secretAccessor"
done

Step 5 — Deploy to Cloud Run

Deploy the service, mounting the GCS bucket at /app/atlas-files (matching StoredFilesPath=atlas-files):

gcloud run deploy regscale \
  --image=us-central1-docker.pkg.dev/<project-id>/regscale/regscale:x.x.x.x \
  --region=us-central1 \
  --service-account="$SA" \
  --port=80 \
  --cpu=2 --memory=4Gi \
  --min-instances=1 --max-instances=3 \
  --allow-unauthenticated \
  --add-volume=name=regscale-files,type=cloud-storage,bucket=<project-id>-regscale-files \
  --add-volume-mount=volume=regscale-files,mount-path=/app/atlas-files \
  --set-env-vars=ASPNETCORE_HTTP_PORTS=80,ASPNETCORE_URLS=http://+:80,StoredFilesPath=atlas-files,FileSizeLimit=104857600 \
  --set-secrets=JWTSecretKey=regscale-jwt-secret-key:latest,EncryptionKey=regscale-encryption-key:latest,SQLConn=regscale-sql-conn:latest

Notes:

  • --cpu/--memory (2 vCPU / 4 GB) match the minimum web tier in the Sizing Guide; adjust for your tier.
  • Cloud Run terminates TLS and serves the app over HTTPS; the container only needs to listen on HTTP port 80.
  • --min-instances=1 avoids cold starts. Because files are stored in the shared GCS bucket, multiple instances can run concurrently.

📘

Cloud Storage FUSE presents the bucket as a filesystem but is not a full POSIX file system (eventual consistency, slower for many small files). Validate behavior with your expected file workload.

Step 6 — Connect to Cloud SQL

For private connectivity to your Cloud SQL for SQL Server instance, enable Direct VPC egress (or a Serverless VPC Access connector) on the Cloud Run service and point SQLConn at the instance's private IP:

gcloud run services update regscale \
  --region=us-central1 \
  --network=<vpc-network> --subnet=<subnet>

See the Cloud SQL for SQL Server connection documentation for details.

Step 7 — Access RegScale

Get the service URL:

gcloud run services describe regscale --region=us-central1 --format='value(status.url)'

Browse to the URL and complete the Post-Deployment Steps. To use your own domain with a managed certificate, map a custom domain to the service.

Scaling

  • Adjust --min-instances/--max-instances to control scale. Files live in the shared GCS bucket, so multiple instances can run concurrently.
  • Deploy a new image tag to upgrade — see the Upgrade Guide.