Running ESP Locally or on Another Platform

This page explains how to configure and run an instance of the Extensible Service Proxy (ESP) on a local machine or on another cloud provider, such as Amazon Web Services (AWS).

You can run ESP locally on a Linux or macOS computer. Windows is not supported. Hosting a local instance of ESP allows you to:

  • Try out ESP before actually deploying it to a production platform.
  • Verify that security settings are configured and working properly, and that metrics and logs appear in the Endpoints dashboard as expected.

You can deploy your application and ESP on the same host or on different hosts. You can also run ESP on a Linux VM or AWS.

Prerequisites

As a starting point, this page assumes that:

  • You have Docker installed on the host where you will run ESP. See Install Docker for more information.

  • You have deployed an API locally or on a host that is reachable to the host where you will run ESP.

  • You have configured your OpenAPI configuration file and deployed the configuration to Endpoints.

If you need an API for testing with ESP, you can configure and deploy the sample code in the Optional: Using a sample API section. If you have already configured and deployed your Cloud Endpoints API, skip to Getting the service name and configuration ID.

Optional: Using a sample API

This section walks you through configuring and deploying the Python Endpoints Getting Started sample locally. Do the steps in this section only if you do not have an API for testing with ESP.

The Endpoints Getting Started sample is available in other languages. See the Samples page for the GitHub location of the getting-started sample in your preferred language. Follow the instructions in the sample's README.md for running locally, and then follow the instructions in this section to configure Endpoints and to deploy the Endpoints configuration.

Getting required software

If you do not have a Python development environment setup yet, see Setting Up a Python Development Environment for guidance. Make sure that you have the following installed:

Getting the sample code

  1. Clone the sample app repository to your local machine:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples
    

  2. Change to the directory that contains the sample code:

    cd python-docs-samples/endpoints/getting-started
    

Configuring Endpoints

  1. In the sample code directory, open the openapi.yaml configuration file.

    swagger: "2.0"
    info:
      description: "A simple Google Cloud Endpoints API example."
      title: "Endpoints Example"
      version: "1.0.0"
    host: "echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog"

  2. In the host field, replace YOUR-PROJECT-ID with your own Cloud project ID.

  3. Save openapi.yaml.

Deploying the Endpoints configuration

To deploy the Endpoints configuration, you use Google Service Management, an infrastructure service of Google Cloud Platform that manages other APIs and services, including services created using Cloud Endpoints.

  1. Update the Cloud SDK:

    gcloud components update
    
  2. Make sure that Cloud SDK (gcloud) is authorized to access your data and services on Google Cloud Platform:

    gcloud auth login
    

    A new brower tab opens and you are prompted to choose an account.

  3. Set the default project to your project ID:

    gcloud config set project [YOUR-PROJECT-ID]
    

    Replace [YOUR-PROJECT-ID] with the project ID of the Cloud project that you specified in openapi.yaml.

  4. Deploy your configuration:

    gcloud endpoints services deploy openapi.yaml
    

Service Management uses the text that you specified in the host field in the openapi.yaml file to create a new Cloud Endpoints service with the name echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog (if it does not exist), and then configures the service according to your OpenAPI configuration file.

As it is creating and configuring the service, Service Management outputs a great deal of information to the terminal. You can safely ignore the warnings about the paths in openapi.yaml not requiring an API key. On successful completion, you will see a line like the following that displays the service configuration ID and the service name within square brackets:

Service Configuration [2017-02-13r0] uploaded for service [echo-api.endpoints.example-project.cloud.goog]

In the example above, 2017-02-13r0 is the service configuration ID, and echo-api.endpoints.example-project.cloud.goog is the service name.

Starting your local server

  1. Create a virtualenv, activate it, and install the application dependencies.

    virtualenv env
    source env/bin/activate
    pip install -r requirements.txt
    

  2. Start the server:

    python main.py
    

  3. Open another terminal window and use curl to send a request:

    curl -d '{"message":"hello world"}' \
    -H "content-type:application/json" \
    http://localhost:8080/echo
    

    The API echos back the message that you send it, and responds with the following:

    {
      "message": "hello world"
    }
    

Getting the service name and configuration ID

To start ESP, you need the name and configuration ID of your Cloud Endpoints service. If you don't have the service name and configuration ID readily available, you can use the following procedure to get them.

To get the service name and configuration ID:

  1. Enter the following to display the project IDs for your Cloud projects:
    gcloud projects list
  2. Using the applicable project ID from the previous step, set the default project to the one that your API is in:
    gcloud config set project [YOUR_PROJECT_ID]
  3. Get a list of services in your project:
    gcloud endpoints services list
  4. Using the applicable service name from the previous step, get a list of configuration IDs for the service:
    gcloud endpoints configs list --service=[YOUR_SERVICE_NAME]

Creating a service account

When ESP is running on platforms other than Google Cloud Platform (GCP), such as your local desktop, Kubernetes or AWS, you must create a service account. ESP uses the service account to generate an access token to call services in Google Service Control and Google Service Management.

App Engine and other platforms on GCP have a metadata server that has an access token that ESP can use. But for non-GCP platforms, you have to provide the service account JSON file that contains a private key. ESP generates the access token using the JSON file.

To create a service account:

  1. Open the Service Accounts page in the Cloud Platform Console.

    Open the Service Accounts page

  2. Click Select a project.

  3. Select your project and click Open.

  4. Click Create Service Account.
  5. Enter a service account name.
  6. Click Role and select:

    • Project -> Editor

    or select all of the following roles:

    • Project -> Viewer

    • Service Management -> Service Controller

    • Cloud Trace -> Cloud Trace Agent

  7. Click Furnish a new private key.

  8. For the Key type, use the default type,JSON.

  9. Click Create.

    This creates the service account and downloads its private key to a JSON file. When you start ESP, you specify the full path name of the JSON file in the --service_account_key option.

  10. For simplicity, rename the JSON file to serviceaccount.json and copy it to ~Downloads/ if it was downloaded to a different directory. This way, the full path name matches the name specified in the --service_account_key option in the in the Running ESP in a Docker container section.

Running ESP in a Docker container

The Docker container for ESP can be started using docker run. You can use the following options to run your application and ESP locally:

Linux

sudo docker run \
    --detach \
    --name="esp" \
    --net="host" \
    --volume ~/Downloads:/esp \
    gcr.io/endpoints-release/endpoints-runtime:1 \
    --service  [YOUR_SERVICE_NAME] \
    --version  [YOUR_SERVICE_CONFIG_ID] \
    --http_port  8082 \
    --backend localhost:8080 \
    --service_account_key /esp/serviceaccount.json

Mac OS

The Docker --net="host" option does not work on macOS. Instead, you must do explicit port mapping from the host to container replacing --net="host" with --publish 8082:8082. You also need to replace localhost with the special Mac-only DNS name docker.for.mac.localhost. See Use cases and workarounds in the Docker Documentation for more information.

sudo docker run \
    --detach \
    --name="esp" \
    --publish 8082:8082 \
    --volume ~/Downloads:/esp \
    gcr.io/endpoints-release/endpoints-runtime:1 \
    --service  [YOUR_SERVICE_NAME] \
    --version  [YOUR_SERVICE_CONFIG_ID] \
    --http_port  8082 \
    --backend docker.for.mac.localhost:8080 \
    --service_account_key /esp/serviceaccount.json

To run your application on another platform, you can use the following options:

sudo docker run \
    --detach \
    --name="esp" \
    --net="host" \
    --volume ~/Downloads:/esp \
    gcr.io/endpoints-release/endpoints-runtime:1 \
    --service  [YOUR_SERVICE_NAME] \
    --version  [YOUR_SERVICE_CONFIG_ID] \
    --http_port  8082 \
    --backend [IP_Address]:[PORT] \
    --service_account_key /esp/serviceaccount.json

The following table describes the Docker and ESP options used in the above commands. See Specifying Startup Options for ESP for the complete list of ESP options.

Option Description
--detach
This Docker option starts the container in detached mode, so it runs in the background.
--name="esp"
This Docker option provides an easy-to-access name for the container. For example, to see logs from the container, you could run docker logs esp
--net="host"
This Docker option indicates that the Docker container should use the same network configuration as the host machine, allowing it to make calls to localhost on the host machine. This option does not work to run ESP locally on macOS.
--publish 8082:8082
For macOs when you want to run ESP locally, use this Docker option instead of --net="host" to do explicit port mapping from the host to container.
--volume ~/Downloads:/esp
This Docker option maps your local ~/Downloads directory to the /esp directory in the container. This mapping is used by the --service_account_key argument, explained below.
--service [YOUR_SERVICE_NAME]
This ESP option sets the name of the Endpoints service name. Replace [YOUR_SERVICE_NAME] with the name of your service.
--version [YOUR_SERVICE_CONFIG_ID]
This ESP option sets the name of the Endpoints service configuration ID. Replace [YOUR_SERVICE_CONFIG_ID] with the configuration ID for your service. The --service and --version options provide ESP with the information that it needs to retrieve the API configuration.
--http_port 8082
This ESP option sets ESP to receive requests on port 8082.
--backend
This ESP option sets the address for the HTTP/1.x application backend server. You use one of the following values:
  • localhost:8080 Indicates that your API's backend server receives requests at localhost on port 8080. This value does not work on macOS.
  • docker.for.mac.localhost:8080 Use this value instead of localhost:8080 to run your API locally on macOS.
  • [IP_Address]:[PORT] If your application is running on another platform, specify the IP address and the port.
--service_account_key
 /esp/serviceaccount.json
This ESP option specifies where the private key file is located. The /esp directory matches the mapping from the --volume argument above, and the name of the serviceaccount.json file must match the name of the private key file you downloaded when you created the service account.

Sending requests

To confirm that the service account file is correct and that the ports are mapped correctly, send some requests to your API and make sure that the requests are going through ESP. You can see the ESP logs by running:

sudo docker logs esp

The following examples send requests to the sample API. If you are not using the sample API, we recommend that you run similar tests.

You have configured the Docker container to receive requests on port 8082. If you send a request directly to the server at http://localhost:8080, the requests bypasses ESP. For example:

Request:

    curl -d '{"message":"hello world"}' \
    -H "content-type:application/json" \
    http://localhost:8080/echo

Response:

{
  "message": "hello world"
}

When you send a request to http://localhost:8082 which passes through ESP, and you do not send an API key, ESP rejects the request. For example:

Request:

    curl -d '{"message":"hello world"}' \
    -H "content-type:application/json" \
    http://localhost:8082/echo

Response:

{
 "code": 16,
 "message": "Method doesn't allow unregistered callers (callers without
  established identity). Please use API Key or other form of API consumer
  identity to call this API.",
 "details": [
  {
   "@type": "type.googleapis.com/google.rpc.DebugInfo",
   "stackEntries": [],
   "detail": "service_control"
  }
 ]
}

To test the API with an API Key:

  1. Create an API key in the API credentials page.

    Create an API key

  2. Click Create credentials, then select API key.

  3. Copy the key, then paste it into the following environment variable statement:

    export KEY=AIza...

  4. Send a request with the key:

    curl -d '{"message":"hello world"}' \
    -H "content-type:application/json" \
    http://localhost:8082/echo?key=$KEY
    

    You should see a successful response:

    {
      "message": "hello world"
    }
    

Cleaning up

Shut down and remove the esp Docker container using the docker tool:

sudo docker stop esp
sudo docker rm esp

If you want to clean up the deployed service configuration, see Deleting an API and API Instances.

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

Cloud Endpoints with OpenAPI