Google Cloud for Office & PDF File API
- 8 minutes to read
Use .NET and Google Cloud CLI to create a Blazor application with Office and PDF File API components and deploy this application to Google Cloud Run.
Prerequisites
- A Google Cloud account with an active subscription.
- A Cloud Billing account.
- The latest version of Google Cloud CLI.
Create a Blazor App with DevExpress Office & PDF File API Components
Create a Blazor Web App:
dotnet new blazor -o dxofficefileapiapp cd dxofficefileapiappInstall the following DevExpress NuGet packages:
dotnet add package DevExpress.Document.Processor dotnet add package DevExpress.Docs.Pdf dotnet add package DevExpress.Docs.Presentation dotnet add package DevExpress.Docs.BarCode dotnet add package DevExpress.Drawing.SkiaAdd Razor components that use Office & PDF File API to generate/process documents or barcodes. Refer to the following help topics for implementation examples:
Run the application locally to confirm that each component works as expected:
dotnet run
Initialize the Google Cloud CLI
In the application directory, run the following command to log in to your Google Cloud account:
cd dxofficefileapiapp gcloud initFor additional information, see Initialize the gcloud CLI.
Create and Configure a Google Cloud Project
Create a project and set it as active:
gcloud projects create <PROJECT_ID> gcloud config set project <PROJECT_ID><PROJECT_ID>is a globally unique project identifier (lowercase letters, numbers, and hyphens). Make sure that you keep the PROJECT_ID value for future use.Link the project to your billing account.
Refer to the following articles for additional information:
Enable required APIs:
gcloud services enable run.googleapis.com cloudbuild.googleapis.com secretmanager.googleapis.com artifactregistry.googleapis.comFor additional information, see Enable and disable services.
Find the Compute Engine default service account:
gcloud iam service-accounts listCopy the email in the format
<PROJECT_NUMBER>-compute@developer.gserviceaccount.com. Use it as<SERVICE_ACCOUNT_EMAIL>in the next step.Grant the required roles to the service account:
gcloud projects add-iam-policy-binding <PROJECT_ID> --member="serviceAccount:<SERVICE_ACCOUNT_EMAIL>" --role="roles/run.builder" gcloud projects add-iam-policy-binding <PROJECT_ID> --member="serviceAccount:<SERVICE_ACCOUNT_EMAIL>" --role="roles/storage.objectViewer" gcloud projects add-iam-policy-binding <PROJECT_ID> --member="serviceAccount:<SERVICE_ACCOUNT_EMAIL>" --role="roles/artifactregistry.writer" gcloud projects add-iam-policy-binding <PROJECT_ID> --member="serviceAccount:<SERVICE_ACCOUNT_EMAIL>" --role="roles/secretmanager.secretAccessor"Create a NuGet.config file in the project root.
This file overrides NuGet package sources because Cloud Build does not have access to your system-level NuGet config:
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <clear /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> </packageSources> <fallbackPackageFolders> <clear /> </fallbackPackageFolders> </configuration>DevExpress packages are available on nuget.org. This single source is sufficient to restore DevExpress packages in the cloud.
Create a Dockerfile
The application requires a Dockerfile to build a container image that Cloud Build can deploy to Cloud Run. If your project template did not create a Dockerfile, add one as described in Dockerize an Office & PDF File API Application. Update the generated Dockerfile as follows.
Add native dependencies that the Office & PDF File API cross-platform renderer requires:
RUN apt-get update RUN apt-get install -y libc6 libicu-dev libfontconfig1Remove the
USER $APP_UIDinstruction. Google Cloud Build cannot access the non-root user that this instruction requires:# USER $APP_UIDConfigure the application to listen on the port that Cloud Run assigns through the
PORTenvironment variable (8080by default):ENV ASPNETCORE_HTTP_PORTS=8080 EXPOSE 8080 EXPOSE 8081Update
COPY,RUN dotnet restore,WORKDIR, andRUN dotnet buildinstructions in the build stage to reference your project file:COPY ["dxofficefileapiapp.csproj", "dxofficefileapiapp/"] RUN dotnet restore "dxofficefileapiapp/dxofficefileapiapp.csproj" COPY ["./", "dxofficefileapiapp/"] WORKDIR "/src/dxofficefileapiapp" RUN dotnet build "dxofficefileapiapp.csproj" -c $BUILD_CONFIGURATION -o /app/buildThe resulting Dockerfile looks as follows:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base WORKDIR /app ENV ASPNETCORE_URLS=http://0.0.0.0:8080 EXPOSE 8080 # Install native dependencies and libraries required for the Skia renderer and fonts RUN apt-get update RUN apt-get install -y libc6 libicu-dev libfontconfig1 # This stage is used to build the service project FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["dxofficefileapiapp.csproj", "dxofficefileapiapp/"] RUN dotnet restore "dxofficefileapiapp/dxofficefileapiapp.csproj" COPY ["./", "dxofficefileapiapp/"] WORKDIR "/src/dxofficefileapiapp" RUN dotnet build "dxofficefileapiapp.csproj" -c $BUILD_CONFIGURATION -o /app/build # This stage publishes the service project so it can be copied to the final stage FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "./dxofficefileapiapp.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false # This stage is used in production FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "dxofficefileapiapp.dll"]
Pass the DevExpress License Key to the Build Pipeline
Google Cloud Build runs in a remote environment that does not have access to your local DevExpress installation. Use the Google Secret Manager to securely pass your license key to the Docker build.
You can find your DevExpress license key file in the following default locations:
- Windows:
%APPDATA%\DevExpress\DevExpress_License.txt - Linux/macOS:
~/.config/DevExpress/DevExpress_License.txt
If you do not have a local license file, refer to the following article for instructions on how to obtain your DevExpress license key: Set Up Your DevExpress License Key
Create a secret (
DEVEXPRESS_LICENSE):gcloud secrets create DEVEXPRESS_LICENSE --replication-policy="automatic"Add the license key to the secret. Choose one of the following approaches:
Upload your local license file.
gcloud secrets versions add DEVEXPRESS_LICENSE --data-file="$env:APPDATA/DevExpress/DevExpress_License.txt"Note
The PowerShell command requires PowerShell 7+ (
pwsh) on Linux and macOS. Use the Bash command instead, or update--data-fileif your license file is stored elsewhere.Pass the license key value directly instead of uploading a file. Store key content in an environment variable and pipe it to
gcloudthrough standard input:$env:DEVEXPRESS_LICENSE = Get-Content "$env:APPDATA/DevExpress/DevExpress_License.txt" -Raw $env:DEVEXPRESS_LICENSE | gcloud secrets versions add DEVEXPRESS_LICENSE --data-file=-
Create a build configuration file (cloudbuild.yaml) in the project root.
This file defines the Cloud Build steps that retrieve the secret and pass it to the Docker build:
steps: - name: gcr.io/cloud-builders/gcloud entrypoint: bash args: - -c - | gcloud secrets versions access latest \ --secret=DEVEXPRESS_LICENSE > DevExpress_License.txt - name: 'gcr.io/cloud-builders/docker' env: - 'DOCKER_BUILDKIT=1' args: - build - --secret=id=DEVEXPRESS_LICENSE,src=DevExpress_License.txt - -t - <IMAGE_PATH> - . images: - <IMAGE_PATH>Refer to the Prepare a Docker Image section below for guidance on how to set
<IMAGE_PATH>to the full path of your Docker image in Artifact Registry.Update the Dockerfile to read the secret and copy the license file during the build stage.
Replace the
dotnet buildline in the generated Dockerfile with the following:# RUN dotnet build "dxofficefileapiapp.csproj" -c Release -o /app/build # Pass the license key as a secret and copy it before building RUN --mount=type=secret,id=DEVEXPRESS_LICENSE \ mkdir -p $HOME/.config/DevExpress && \ cp /run/secrets/DEVEXPRESS_LICENSE $HOME/.config/DevExpress/DevExpress_License.txt && \ dotnet build "dxofficefileapiapp.csproj" -c Release -o /app/build
Prepare a Docker Image
Create a .gcloudignore file in the project root. Filter files sent to the Cloud Build. Exclude build artifacts, IDE files, and secrets:
bin/ obj/ **/bin/ **/obj/ *.user *.suo .vscode/ .vs/ secrets.* appsettings.*.json !appsettings.json .nuget/ packages/ node_modules/ *.bakCreate an Artifact Registry repository:
gcloud artifacts repositories create <REPOSITORY_NAME> --repository-format=docker --location=<LOCATION> --description="Docker images"<REPOSITORY_NAME>— Artifact Registry repository name.<LOCATION>— Google Cloud region (for example,us-central1oreurope-west1). Use the same region in subsequent steps.
Authenticate Docker with the Artifact Registry:
gcloud auth configure-docker <LOCATION>-docker.pkg.devSet the image path. In cloudbuild.yaml, replace
<IMAGE_PATH>with the following:<LOCATION>-docker.pkg.dev/<PROJECT_ID>/<REPOSITORY_NAME>/<IMAGE_NAME>Use the Cloud Build to build and push the Docker image:
gcloud builds submit --config cloudbuild.yaml
Deploy to Google Cloud Run
Deploy the built image to Cloud Run:
gcloud run deploy <SERVICE_NAME> \ --image=<IMAGE_PATH> \ --platform=managed \ --region=<LOCATION> \ --allow-unauthenticatedNote
--allow-unauthenticatedmakes the service publicly accessible and is used here for demonstration purposes only.<SERVICE_NAME>— Cloud Run service name displayed in the Cloud Run console.<LOCATION>— Cloud Run region (should match the Artifact Registry region).<IMAGE_PATH>— Full Docker image path from Artifact Registry (same as used incloudbuild.yaml).
After successful deployment, the Google Cloud console displays the public URL of your service.
Environment Variables and Configuration
The following table lists environment variables and configuration values used in this walkthrough:
| Name | Where it is used | Description |
|---|---|---|
PORT |
Cloud Run container | Port on which Cloud Run expects the application to listen. Cloud Run sets this value automatically (8080 by default); the Dockerfile maps it to ASPNETCORE_URLS. |
ASPNETCORE_URLS |
Dockerfile | Configures the Blazor app’s Kestrel server to listen on http://0.0.0.0:$PORT so that the container accepts requests from Cloud Run. |
DEVEXPRESS_LICENSE |
Google Secret Manager, cloudbuild.yaml, Dockerfile |
A secret that stores the contents of your local DevExpress_License.txt file. Cloud Build retrieves this secret at build time and the Dockerfile copies it to $HOME/.config/DevExpress/DevExpress_License.txt so that DevExpress components are licensed during the build. |
<PROJECT_ID> |
gcloud commands |
Globally unique identifier of your Google Cloud project. |
<SERVICE_ACCOUNT_EMAIL> |
IAM role bindings | Compute Engine default service account used by Cloud Build to build and push the Docker image. |
<LOCATION> |
Artifact Registry, Cloud Run | The Google Cloud region used for the Artifact Registry repository and the Cloud Run service (for example, us-central1). |
<REPOSITORY_NAME> / <IMAGE_NAME> / <IMAGE_PATH> |
Artifact Registry, cloudbuild.yaml, Cloud Run |
Identify the Docker image built by Cloud Build and deployed to Cloud Run. |
<SERVICE_NAME> |
gcloud run deploy |
Name of the deployed Cloud Run service. |
Note
Do not commit NuGet.config, cloudbuild.yaml secrets, or license files to source control. Use the Google Secret Manager or a similar secret store for sensitive values, and add secrets and local configuration files to .gcloudignore and .gitignore.
See Also
- Dockerize an Office & PDF File API Application
- Office & PDF File API Cloud Support Troubleshooting Guide
- Amazon ECS (Linux Container) Using AWS Fargate - Office & PDF File API Web App Deployment
- Amazon Lambda Function for Office & PDF File API
- Azure App Service Container for an Office & PDF File API Application
- Azure Functions App for Office & PDF File API