-
Notifications
You must be signed in to change notification settings - Fork 0
Infrastructure
The GCP services the DocAI OCR API relies on, how each is configured, and how they interact.
Everything runs on a single Compute Engine VM with Docker; there is no Kubernetes, no
managed autoscaler, and (by default) no load balancer or TLS. Provisioning is scripted in
deploy/gcp/ (01-provision.sh … 04-run.sh).
See also: Architecture · OCR Plugin · Job Manager.
flowchart TB
Client([Client / curl])
subgraph GCP["GCP project"]
subgraph VM["Compute Engine VM (c4-standard-4, Ubuntu 24.04)"]
Docker["Docker container<br/>ocrapi (FastAPI, port 8000)"]
Data[("/data/jobs<br/>data disk 50 GB")]
end
DocAI["Document AI<br/>Document OCR processor"]
GCS["Cloud Storage<br/>PROJECT-ocrapi-batch<br/>(legacy batch scratch)"]
AR["Artifact Registry<br/>docker repo 'ocrapi'"]
Log["Cloud Logging"]
Mon["Cloud Monitoring"]
SA["Service account<br/>ocrapi-sa@PROJECT.iam"]
end
Drive["Google Drive API<br/>Shared Drive folder"]
Client -->|"HTTPS :8000 (TLS)"| Docker
Docker --> Data
Docker -->|processDocument| DocAI
Docker -.->|batch path, unused| GCS
Docker -->|resumable upload| Drive
Docker -->|pull image| AR
Docker --> Log
Docker --> Mon
VM -. "attached identity<br/>ADC + OAuth scopes" .- SA
SA -->|IAM roles| DocAI
SA -->|IAM roles| GCS
SA -->|IAM roles| AR
SA -->|"shared as Content Manager<br/>(not IAM)"| Drive
The whole app runs as one Docker container on a single GCE instance managed by systemd
(ocrapi.service).
| Setting | Default | Notes |
|---|---|---|
| Machine type | c4-standard-4 |
CPU is rarely the bottleneck; Document AI quota is |
| Image | ubuntu-2404-lts-amd64 |
|
| Boot disk | 50 GB hyperdisk-balanced
|
|
| Data disk | 50 GB hyperdisk-balanced, mounted at /data
|
Holds JOBS_DIR (/data/jobs), bind-mounted into the container |
| Network tag | ocrapi |
Firewall rules target this tag |
| OS Login | enabled | SSH via gcloud compute ssh
|
The container is served over HTTPS on 0.0.0.0:8000, with TLS terminated in-process by
uvicorn (--ssl-keyfile / --ssl-certfile) — no reverse proxy. A long-lived self-signed
certificate is generated once by 02-vm-setup.sh and stored on the data disk at /data/tls
(bind-mounted read-only into the container); this keeps client trust stable across container
restarts and image redeploys. PDF uploads and OCR responses are therefore encrypted in transit.
Clients trust /data/tls/cert.pem (--cacert) or use curl -k. The cert's SANs pin the VM's
internal and external IPs — reserve a static IP or regenerate the cert if the external IP
changes. See deploy/gcp/README.md for cert distribution and rotation.
Two firewall rules (INGRESS, on the ocrapi tag):
-
ocrapi-allow-http—tcp:8000(now carrying HTTPS), sourceAPP_SOURCE_CIDR(defaults to0.0.0.0/0; tighten to your intranet range) -
ocrapi-allow-ssh—tcp:22, sourceALLOWED_SSH_CIDR
The core OCR service. A Document OCR processor performs online processDocument calls on
whole PDFs (sync) or per chunk (async). Retries with exponential backoff handle transient
errors and RESOURCE_EXHAUSTED. See OCR Plugin for the client.
Config (.env) |
Purpose |
|---|---|
GCP_PROJECT_ID |
Project containing the processor |
GCP_LOCATION (us) |
Processor location; also derives the API endpoint {location}-documentai.googleapis.com
|
GCP_PROCESSOR_ID |
The Document OCR processor ID |
-
API:
documentai.googleapis.com(enabled by01-provision.sh). -
IAM: service account needs
roles/documentai.apiUseron the project. -
Quota: online
processDocumentpages/min (~120 sustained by default) is the real throughput ceiling. Readdeploy/gcp/QUOTA.mdbefore raising concurrency.
Optional destination for finished searchable PDFs. Uploads use the Drive v3 resumable upload
REST API with google.auth.transport.requests.AuthorizedSession — one session per upload so
jobs finishing together can upload in parallel.
-
API:
drive.googleapis.com(enabled by01-provision.sh). - Access is NOT granted via IAM. Share the target folder with the service account email as Content Manager. The folder must live in a Shared Drive (service accounts have no personal My Drive quota).
-
OAuth scopes: the VM must carry
cloud-platformandhttps://www.googleapis.com/auth/drive.cloud-platformalone covers Document AI/GCS but not Drive — a missing Drive scope yields403 insufficient authentication scopes. -
Config:
DRIVE_SHARED_FOLDER_ID— default Shared Drive folder when a request omitsfolder_id. Use the full folder ID (typically 33 chars); a truncated ID causes404 File not found.
A regional bucket gs://PROJECT-ocrapi-batch is provisioned for the Document AI batch code
path (batch_process_from_gcs). The current async job pipeline does not use it — it is kept
for future/optional batch OCR only.
| Config / setting | Value |
|---|---|
GCS_BUCKET |
Bucket name (required by config even though unused by jobs) |
| Access control | Uniform bucket-level access |
| Lifecycle | 1-day delete rule (scratch objects auto-expire) |
| IAM |
roles/storage.objectAdmin on the bucket for the service account |
BATCH_TIMEOUT_SECONDS (1800) |
Batch LRO polling timeout |
BATCH_POLL_INTERVAL_SECONDS (10) |
Batch LRO poll interval |
A Docker-format repository named ocrapi in the deploy region holds the app image.
03-build-and-push.sh builds linux/amd64 and pushes; 04-run.sh pins a tag and starts the
service. The service account has roles/artifactregistry.reader to pull on the VM.
The container writes application logs to Cloud Logging and metrics to Cloud Monitoring.
The service account has roles/logging.logWriter and roles/monitoring.metricWriter. On the VM,
tail logs with journalctl -u ocrapi.service -f.
One service account, ocrapi-sa@PROJECT.iam.gserviceaccount.com, is the single identity for
everything. On the VM it is used via Application Default Credentials (no JSON key in the
container). Locally, point GOOGLE_APPLICATION_CREDENTIALS at a key file instead.
| Access | How it is granted |
|---|---|
| Document AI |
roles/documentai.apiUser (IAM, project) |
| Cloud Storage batch bucket |
roles/storage.objectAdmin (IAM, bucket) |
| Artifact Registry pull |
roles/artifactregistry.reader (IAM, project) |
| Cloud Logging / Monitoring |
roles/logging.logWriter, roles/monitoring.metricWriter (IAM, project) |
| Google Drive | Not IAM — folder shared with the SA as Content Manager, plus the Drive OAuth scope on the VM |
01-provision.sh enables: compute, documentai, drive, artifactregistry, iam,
logging, monitoring, and storage.
| Environment | How credentials are obtained |
|---|---|
| Local dev | JSON key file via GOOGLE_APPLICATION_CREDENTIALS
|
| GCE production | Attached VM service account via Application Default Credentials (no key file) |
Job folders under /data/jobs are not auto-deleted by the app. A systemd timer
(ocrapi-cleanup.timer → ocrapi-cleanup.service → ocrapi-cleanup.sh) prunes old job folders
daily and 10 minutes after boot (RETENTION_DAYS, default 7). Watch disk with
df -h /data and du -sh /data/jobs.