Deploying Versions of Your App to App Engine

Region ID

The REGION_ID is an abbreviated code that Google assigns based on the region you select when you create your app. The code does not correspond to a country or province, even though some region IDs may appear similar to commonly used country and province codes. For apps created after February 2020, REGION_ID.r is included in App Engine URLs. For existing apps created before this date, the region ID is optional in the URL.

Learn more about region IDs.

Use the App Engine Admin API to programmatically deploy versions of your apps to your App Engine application through HTTP POST requests.

Before you begin

Before you can send the HTTP deployment request, you must be able to authorize the HTTP request, access the staged files of your app, and have a JSON formatted configuration file. See the following topics to help you with these prerequisites:

Deploying your app to App Engine with the Admin API

To deploy a version of your app to your application in App Engine:

  1. Authorize your HTTP requests, for example obtain an access token.

    Authorizing access to the Admin API can be accomplished with different OAuth flows depending on the needs of your API app. For more information, see Accessing the API.

  2. Send an HTTP POST request using your access token and the Admin API to deploy your version to your App Engine application:

    To deploy a version, you send an HTTP POST request that specifies the JSON configuration file and defines a Version resource of the target service and App Engine application.

    For example, you can use the following HTTP POST request to deploy the version that is specified in the JSON configuration file, to the default service of the MY_PROJECT_ID application:

    POST https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions app.json
    

    Example cURL command:

    curl -X POST -T "app.json" -H "Content-Type: application/json" -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions
    

    Where:

    • [MY_ACCESS_TOKEN] is the access token that you obtained to authorize your HTTP requests.
    • [MY_PROJECT_ID] is the ID of project where you want to deploy the version.

    Example response:

    {
      "metadata": {
        "@type": "type.googleapis.com/google.appengine.v1.OperationMetadataV1",
        "insertTime": "2015-05-29T17:12:44.679Z",
        "method": "google.appengine.v1.Versions.CreateVersion",
        "target": "apps/[MY_PROJECT_ID]/services/default/versions/v1",
        "user": "me@example.com"
      }
      "name": "apps/[MY_PROJECT_ID]/operations/89729825-ef1f-4ffa-b3e3-e2c25eb66a85"
    }
    
  3. Verify that your version was deployed to your App Engine application:

    1. View the status of the actual deployment operation:

      The HTTP POST request that you used in the previous step returned the operation name in the name field, which you use with the GET method of the apps.operations collection to check the status of the deployment operation.

      For example, if the name field of the response is:

      "name": "apps/[MY_PROJECT_ID]/operations/89729825-ef1f-4ffa-b3e3-e2c25eb66a85"
      

      Then you send the following HTTP GET request:

      GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/operations/89729825-ef1f-4ffa-b3e3-e2c25eb66a85
      

      Example cURL command:

      curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/operations/89729825-ef1f-4ffa-b3e3-e2c25eb66a85
      

      Where [MY_ACCESS_TOKEN] is your access token and [MY_PROJECT_ID] is the ID of project where you deployed the version.

      Example response:

      {
        "done": true,
        "metadata": {
          "@type": "type.googleapis.com/google.appengine.v1.OperationMetadataV1",
          "endTime": "2015-05-29T17:13:20.424Z",
          "insertTime": "2015-05-29T17:12:44.679Z",
          "method": "google.appengine.v1.Versions.CreateVersion",
          "target": "apps/[MY_PROJECT_ID]/services/default/versions/v1",
          "user": "me@example.com"
        },
        "name": "apps/[MY_PROJECT_ID]/operations/89729825-ef1f-4ffa-b3e3-e2c25eb66a85",
        "response": {
          "@type": "type.googleapis.com/google.appengine.v1.Version",
          "creationTime": "2015-05-29T17:12:46.000Z",
          "deployer": "me@example.com",
          "id": "v1",
          "name": "apps/[MY_PROJECT_ID]/services/default/versions/v1",
          "runtime": "python27",
          "servingStatus": "SERVING",
          "threadsafe": true,
        }
      }
      

      To learn more about polling long running operations, see the google.longrunning RPC reference.

    2. Verify that the version was created in your App Engine application:

      To view details about the version, you use the GET method of the apps.services.versions collection. You must specify the version that you deployed in the HTTP GET request, for example:

      GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions/v1
      

      Example cURL command:

      curl -H "Authorization: Bearer [MY_ACCESS_TOKEN]" https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions/v1
      

      Where [MY_ACCESS_TOKEN] is your access token and [MY_PROJECT_ID] is the ID of project where you deployed the version.

      Example response:

      {
        "creationTime": "2015-05-29T17:12:46.000Z",
        "deployer": "me@example.com",
        "deployment": {
          "files": {
            "my-python-app.py": {
              "sha1Sum": "7cffbdaa9fcfa46e5e58269bfe336dd815de0566",
              "sourceUrl": "https://storage.googleapis.com/[YOUR_BUCKET_ID]/my-application/logo.jpg",
            },
            "logo.jpg": {
              "sha1Sum": "13f7ea1e24f7cd2de5c66660525f2b509da37c14",
              "sourceUrl": "https://storage.googleapis.com/[YOUR_BUCKET_ID]/my-application/my-python-app.py"
            }
          }
        },
        "handlers": [
          {
            "authFailAction": "AUTH_FAIL_ACTION_REDIRECT",
            "login": "LOGIN_OPTIONAL",
            "script": {
              "scriptPath": "my-python-app.application",
            },
            "securityLevel": "SECURE_OPTIONAL",
            "urlRegex": "/.*"
          }
        ]
        "id": "v1",
        "name": "apps/[MY_PROJECT_ID]/services/default/versions/v1",
        "runtime": "python27",
        "servingStatus": "SERVING",
        "threadsafe": true,
      }
      
      GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions/v1?view=FULL
      
  4. Optional: To launch your browser and view the app at https://VERSION_ID-dot-default-dot-PROJECT_ID.REGION_ID.r.appspot.com, you can run the following command:

    gcloud app browse -v [MY_VERSION_ID]
    
  5. Configure how much traffic the version that you just deployed should receive.

    By default, the initial version that you deploy to your App Engine application is automatically configured to receive 100% of traffic. However, all subsequent versions that you deploy to that same App Engine application must be manually configured, otherwise they receive no traffic.

    For details about how to configure traffic for your versions, see Migrating and Splitting Traffic.

Deploying additional versions and services

The steps for deploying subsequent versions of your app, including creating additional services, are almost identical to the deployment steps covered in this task. If you want to replace the current version that is running in your App Engine application or if you want to add additional services, you can deploy new versions after making a few modifications to your configuration files.

See the following examples for how to deploy additional versions to your App Engine application. Remember, after deploying your versions, you need to configure their traffic.

Example: Deploying additional versions

If an old or faulty version is running in App Engine, you can replace that version by deploying another version to your App Engine application and then routing traffic to that version. For example, after modifying the source code of your app, you can change the value of version in the app.yaml file, create a new app.json file, and then deploy a v2 version of your app with another HTTP POST request:

Example of updated app.yaml file:

  service: default
  version: v2
  runtime: python27
  threadsafe: true
  handlers:
  - url: /.*
    script: my-python-app.application

Example of the HTTP POST request for version v2:

  POST https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/versions app.json

After taking the steps to ensure the version was successfully deployed, you can send an HTTP PATCH request to route all traffic to the new version, for example:

  PATCH https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/default/?updateMask=split {"split": { "allocations": { "v2": "1" } } }

For information about routing traffic, see Migrating and Splitting Traffic.

Example: Deploying multiple services

If you have a v1 version running in your App Engine application and want to deploy an additional service, for example backend, you perform the same deployment steps.

For example, to deploy the v1 version that creates the backend service:

  1. Create the new code and source files for the backend service.
  2. Stage the application resources for your backend service in a Cloud Storage bucket.
  3. Create the backend/app.json configuration file.
  4. Use HTTP requests to deploy the v1 version of the backend service to your App Engine application:

    Example HTTP POST request:

    POST https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services/backend/versions backend/app.json
    

    Example HTTP GET request to verify that the v1 version in the backend service was created:

    GET https://appengine.googleapis.com/v1/apps/[MY_PROJECT_ID]/services
    

    Example response:

    {
      "services": [
        {
          "name": "apps/[MY_PROJECT_ID]/services/default",
          "id": "default",
          "split": {
            "allocations": {
              "v2": 1
            }
          }
        },
        {
          "name": "apps/[MY_PROJECT_ID]/services/backend",
          "id": "backend",
          "split": {
            "allocations": {
              "v1": 1
            }
          }
        }
      ]
    }
    

What's next