Using Docker for Edge Microgateway

You're viewing Apigee Edge documentation.
Go to the Apigee X documentation.
info

This topic explains how to run Edge Microgateway in a Docker container. The steps covered in this topic assume a basic understanding of Docker, Docker commands, and Edge Microgateway setup and configuration. For more information, refer to the documentation for Docker and Edge Microgateway.

Prerequisites

Before running Edge Microgateway in a Docker container, you must do the following tasks:

  • Configure Edge Microgateway for your Apigee organization/environment:

    edgemicro configure -o your_org -e your_env -u your_username

    For more details on configuration, see Part 1: Configure Edge Microgateway.

  • After performing the configuration steps, locate the configuration file. The default location is here:

    $HOME/.edgemicro/your_org-your_env-config.yaml

    where your_org and your_env are the organization and environment you used when you ran the edgemicro config command. You will need this file when you start Edge Microgateway in a Docker container.

  • Be sure you have the key and secret credentials that were returned when you ran the edgemicro config command. For example:

    The following credentials are required to start edge micro
      key: d9c34e1aff68ed969273c016699eabf48780e4f652242e72fc88a43e21252cb0
      secret: 3bc95a71c86a3c8ce04537fbcb788158731t51dfc6cdec13b7c05aa0bd969430
    
  • Before you start Edge Microgateway in a Docker container, you need to create (or have created) the Apigee Edge entities that are required to make authenticated API proxy calls. These entities include an Edge Microgateway-aware proxy, an API Product, a Developer, and a Developer App. For complete instructions, see Create entities on Apigee Edge.

Run Edge Micro as a Docker container

  1. Download the Docker image for Edge Microgateway:

    docker pull gcr.io/apigee-microgateway/edgemicro:latest
  2. Before you proceed to the next steps, be sure you have performed all of the steps in the Prerequisites section.

  3. Run the following command to base64-encode the Edge Microgateway configuration file located in $HOME/.edgemicro:

    export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/your_org-your_env-config.yaml`

    where your_org and your_env are the organization and environment you used when you ran the edgemicro config command.

    Remember to place back-ticks (`) around the command. For example:

    export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/docs-test-config.yaml`
  4. Run Edge Microgateway as a container. The command sets several environment variables that are used by the container runtime to start Edge Microgateway:

    chown -R 100:101 ~/.edgemicro/ \
    docker run -P -p 8000:8000 -d --name edgemicro \
    -v /var/tmp:/opt/apigee/logs \
    -e EDGEMICRO_PROCESSES=1 \
    -e EDGEMICRO_ORG=your_org \
    -e EDGEMICRO_ENV=your_env \
    -e EDGEMICRO_KEY=your_key \
    -e EDGEMICRO_SECRET=your_secret \
    -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
    -e "LOG_CONSOLE_OUTPUT_TO_FILE=false" \
    -e SERVICE_NAME=edgemicro \
    --security-opt=no-new-privileges \
    --cap-drop=ALL \
    gcr.io/apigee-microgateway/edgemicro:latest

    Parameters

      <tr>
        <td><code>SERVICE_NAME</code></td>
        <td>If you are on Kubernetes, this parameter is auto-populated. Otherwise,
          you can set it to anything you wish. If you specify nothing, the service
          name is set to <code>default</code>.</td>
      </tr>
      <tr>
        <tr>
        <td><code>DEBUG</code></td>
        <td>Set to <code>*</code> to enable debugging. </td>
      </tr>
      <tr>
        <td><code>HTTP_PROXY</code>
            <code>HTTPS_PROXY</code></td>
        <td>Use when Edge Microgateway is
          running behind a firewall and the gateway cannot communicate with Apigee
          Edge. For more
          information, see <a href="operation-and-configuration-reference-edge-microgateway#settingupedgemicrogatewaybehindacompanyfirewall">Setting up Edge Microgateway behind a company firewall</a>. 
          <p>For example: <code>HTTP_PROXY=http://10.203.0.1:5187/</code></p></td>
      </tr>
      <tr>
        <td><code>NO_PROXY</code></td>
        <td>A comma delimited list of domains that Edge Microgateway should not proxy to. 
          For more information, see <a href="operation-and-configuration-reference-edge-microgateway#settingupedgemicrogatewaybehindacompanyfirewall">Setting up Edge Microgateway behind a company firewall</a>.
          <p>For example: <code>localhost,127.0.0.1,localaddress,.localdomain.com</code></p></td>
      </tr>
      <tr>
      <tr>
        <tr>
        <td><code>NODE_EXTRA_CA_CERTS</code></td>
        <td>(Optional) Use this parameter if you are using a CA that's not trusted
          by default by Node.js. Set the value of this parameter to the path to a
          file containing one or more trusted certificates in PEM format. For
          details, see <a href="#tls_certificates">TLS certificates</a>.</td>
      </tr>
      <tr>
        <td><code>--security-opt</code></td>
        <td>(Optional) Sets desired Docker security options. See <a href="https://docs.docker.com/engine/reference/run/#security-configuration">Security configuration</a> in the Docker documentation.</td>
      </tr>
      <tr>
        <td><code>--cap-drop</code></td>
        <td>(Optional) Sets limits on Linux capabilities permitted in the container. See <a href="https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities">Runtime privilege and Linux capabilities</a> in the Docker documentation.</td>
      </tr>
    </tbody>
    

    Parameter Description
    -P Publish all exposed ports to the host. See also Docker run reference.
    -p Explicitly map a single port or range of ports. See also Docker run reference.
    -d Run in detached mode. See also Docker run reference.
    -v, -- volume Specifies a volume mount. Note that if you configure Edge Microgateway to use TLS in the Docker container, you must expose port 8443 if you mount the log file directory. See also VOLUME [shared filesystems]. See also Using TLS in the Docker Container.
    -w, -- workdir (Optional) Specifies the path to the directory where edgemicro.sock and edgemicro.pid files should be created. You cannot modify the filename root edgemicro. Defaults to the current working directory path.

    Example:

    docker run -P -p 8000:8000 -d -w /tmp --name edgemicro 
    ...
    EDGEMICRO_ORG The name of the Apigee organization you used to configure Edge Microgateway.
    EDGEMICRO_ENV The name of the Apigee environment you used to configure Edge Microgateway.
    EDGEMICRO_PROCESSES The number of processes to start.
    EDGEMICRO_KEY The key returned when you configured Edge Microgateway.
    EDGEMICRO_SECRET The secret returned when you configured Edge Microgateway.
    EDGEMICRO_CONFIG A variable containing the base64-encoded Edge Microgateway configuration file.
    LOG_CONSOLE_OUTPUT_TO_FILE (Boolean) Allows you to specify where log output is sent. See Specifying log file options.

    For example:

    chown -R 100:101 ~/.edgemicro/ 
    docker run -P -p 8000:8000 -d --name edgemicro
    -v /var/tmp:/opt/apigee/logs
    -e EDGEMICRO_PROCESS=1
    -e EDGEMICRO_ORG=docs
    -e EDGEMICRO_ENV=test
    -e EDGEMICRO_KEY=d9c34e1aff68ed969273b016699eabf48780e4f652242e72fc88a23e21252cb0
    -e EDGEMICRO_SECRET=3bc95a71c86a3c8ce04137fbcb788158731t51dfc6cdec13b7c05aa0bd969430
    -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG"
    -e SERVICE_NAME=edgemicro
    --security-opt=no-new-privileges
    --cap-drop=ALL
    gcr.io/apigee-microgateway/edgemicro

    1. To check that the container is running:

      docker ps

      You should see output similar to the following:

      CONTAINER ID    IMAGE         COMMAND                CREATED          STATUS          PORTS                                             NAMES
      8b92e082ea9c    edgemicro    "/tmp/entrypoint.sh"   12 minutes ago   Up 12 minutes    0.0.0.0:8000->8000/tcp, 0.0.0.0:32775->8443/tcp    edgemicro
      

    Specifying log file output options

    The Edge Microgateway configuration parameter to_console lets you choose to send log information to standard output instead of to a log file. If you follow the steps to run Edge Microgateway in a Docker container, the container by default redirects stdout and error output to a file located in the container at the location: ${APIGEE_ROOT}/logs/edgemicro.log.

    To prevent log information from being sent to edgemicro.log, use the LOG_CONSOLE_OUTPUT_TO_FILE variable when you run the container.

    The following table describes the log output behavior when you use LOG_CONSOLE_OUTPUT_TO_FILE with to_console:

    to_console: true

    LOG_CONSOLE_OUTPUT_TO_FILE=false

    • No logs will be sent to the Edge Microgateway log file, as described in Managing log files.
    • Logs will not be sent to the edgemicro.log file.
    to_console: true

    LOG_CONSOLE_OUTPUT_TO_FILE=true

    • No logs will be sent to the Edge Microgateway log file, as described in Managing log files.
    • Logs will be sent to the edgemicro.log file.
    to_console: false

    LOG_CONSOLE_OUTPUT_TO_FILE=true

    • Logs will be sent to the Edge Microgateway log file, as described in Managing log files.
    • Logs will be sent to the edgemicro.log file.

    Testing an API call

    After you start Edge Microgateway in the container, you can make API calls to it. For example, if the basepath of your API is /hello:

    http://localhost:8000/hello

    Sample output:

    {"error":"missing_authorization","error_description":"Missing Authorization header"}
    

    If you see this response, it means that Edge Microgateway successfully handled the API call. However, by default, Edge Microgateway requires an API key for authentication. In the next section, you will test the API with a valid API key.

    Test an API with a valid API key

    In the Edge UI, navigate to the Developer App you created previously. In the Developer App page, show the Consumer Key and copy it. This value is the API key. You'll use this key to make authenticated API calls.

    Call the API with the x-api-key header as follows. The Consumer Key value you copied from the Developer App is the API key. By default, Edge Microgateway expects you to pass the key in a header called x-api-key, like this:

    curl -i http://localhost:8000/hello -H "x-api-key:apikey"

    For example:

    curl -i http://localhost:8000/hello -H "x-api-key:PydUKRDGIXRqF2xh4usn1FLHbhGKVIz"

    If you want to learn more about making authenticated API calls through Edge Microgateway with API keys and OAuth tokens, see Part 4: Secure Edge Microgateway.

    Stopping Edge Microgateway

    Use the following Docker command to stop Edge Microgateway:

    docker stop edgemicro
    

    Restarting Edge Microgateway

    After stopping Edge Microgateway, you can restart it with this Docker command:

    docker start edgemicro
    

    Using TLS in the Docker container

    This section explains how to configure TLS for Edge Microgateway running in a Docker container. You can configure the Edge Microgateway server to use TLS for incoming requests (northbound direction), and you can configure Edge Microgateway to be a TLS client for outgoing requests to target endpoints (southbound direction).

    Where to put certificate files

    The Docker container running Edge Microgateway has a mount point on /opt/apigee/.edgemicro. When you configure Edge Microgateway to use TLS certificates, you can make the certificate files available on that mount point and refer to them in the Edge Microgateway configuration file. This config file is usually located in the $HOME/.edgemicro directory, and is named your_org-your_env-config.yaml. For example:

    ...
    edgemicro:
      ssl:
       key: /opt/apigee/.edgemicro/southbound/tls.key
       cert: /opt/apigee/.edgemicro/southbound/tls.crt
    ...
    

    Using a CA that is not trusted by Node.js

    If you are using a Certificate Authority (CA) that's not trusted by default by Node.js (such as is the case with a self-signed certificate), consider using the parameter NODE_EXTRA_CA_CERTS when you run the container.

    Set this parameter to the path to a file containing one or more trusted certificates in PEM format. To see how this parameter is used, see the examples How to configure northbound TLS and How to configure southbound TLS.

    For example:

    chown -R 100:101 ~/.edgemicro/ \
    docker run -P -p 8443:8443 -d --name edgemicro \
    -v $HOME/.edgemicro:/opt/apigee/.edgemicro \
    -v $HOME/.edgemicro:/opt/apigee/logs \
    -e NODE_EXTRA_CA_CERTS=/opt/apigee/.edgemicro/rootca.pem \
    -e EDGEMICRO_PORT=8443 \
    -e EDGEMICRO_ORG=docs \
    -e EDGEMICRO_ENV=test \
    -e EDGEMICRO_KEY=ac36574905fb54fdae65fc5433e831bec2680efb98220a355f2e917e52973c \
    -e EDGEMICRO_SECRET=aac81dff6c326eaa222d53c15c8841fa78ea863bf4472568c9ce2d80a3bc56 \
    -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
    --link helloworld:helloworld gcr.io/apigee-microgateway/edgemicro
    

    See also Run Edge Micro as a Docker container.

    Turning off TLS validation

    Although not recommended, in some cases you may wish to disable TLS validation for Edge Microgateway running in a container. The capability for disabling TLS is not built into the Edge Microgateway Docker container by default. To accomplish the task, you must create a customized Docker image for Edge Microgateway. Below are general instructions for building the custom image and turning off TLS validation.

    1. Clone or download the Edge Microgateway source repository from https://github.com/apigee-internal/microgateway.

    2. cd to the microgateway/kubernetes/docker/edgemicro directory in the source code directory.

      For example:

      cd $HOME/git/microgateway/kubernetes/docker/edgemicro
      
    3. Open the file entrypoint.sh and modify the code to accept the NODE_TLS_REJECT_UNAUTHORIZED environment variable. Later, when you run the container, you'll specify a value for this variable.

    4. Build the Docker container:

      docker build -t edgemicro .
      
    5. When you run the container, specify specify the option -e NODE_TLS_REJECT_UNAUTHORIZED = 1. For example:

    chown -R 100:101 ~/.edgemicro/ \
    docker run -P -p 8443:8443 -d --name edgemicro \
    -v $HOME/.edgemicro:/opt/apigee/.edgemicro \
    -v $HOME/.edgemicro:/opt/apigee/logs \
    -e NODE_TLS_REJECT_UNAUTHORIZED = 1 \
    -e EDGEMICRO_PORT=8443 \
    -e EDGEMICRO_ORG=docs \
    -e EDGEMICRO_ENV=test \
    -e EDGEMICRO_KEY=ac36574905fb54fdae65fc5433e831bec2680efb98220a355f2e917e52973c \
    -e EDGEMICRO_SECRET=aac81dff6c326eaa222d53c15c8841fa78ea863bf4472568c9ce2d80a3bc56 \
    -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
    --link helloworld:helloworld gcr.io/apigee-microgateway/edgemicro
    

    Example: How to configure northbound TLS

    This section explains how to set up a northbound (incoming) TLS connection on the Edge Microgateway server. Northbound TLS allows clients to use HTTPS when making API calls to Edge Microgateway. The example below uses self-signed certificates.

    1. Intital setup steps

    1. Locate the openssl.cnf file on your system. For example, /etc/ssl/openssl.cnf.
    2. Open the opensssl.cnf file for editing.
    3. Be sure the req_extensions are present in your config file. For example, you should have information similar to the following in your file:

      [ req ]
      ...
      req_extensions          = v3_req
      ...
      
      [ v3_req ]
      extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment
      
    4. Add the following stanza to openssl.cnf to generate the right SNI attributes:

      [ alt_names ]
      DNS.1 = www.example.com
      DNS.2 = example.com
      DNS.3 = localhost
      DNS.4 = localhost.localdomain
      DNS.5 = 127.0.0.1
      DNS.6 = ::1
      DNS.7 = fe80::1
      

      Example opensssl.cnf file:

      [ req ]
      distinguished_name      = req_distinguished_name
      attributes              = req_attributes
      req_extensions          = v3_req
      
      [ v3_req ]
      extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment
      
      [ req_distinguished_name ]
      countryName                     = Country Name (2 letter code)
      countryName_min                 = 2
      countryName_max                 = 2
      stateOrProvinceName             = State or Province Name (full name)
      localityName                    = Locality Name (eg, city)
      0.organizationName              = Organization Name (eg, company)
      organizationalUnitName          = Organizational Unit Name (eg, section)
      commonName                      = Common Name (eg, fully qualified host name)
      commonName_max                  = 64
      emailAddress                    = Email Address
      emailAddress_max                = 64
      
      [ req_attributes ]
      challengePassword               = A challenge password
      challengePassword_min           = 4
      challengePassword_max           = 20
      
      [ alt_names ]
      DNS.1 = www.example.com
      DNS.2 = example.com
      DNS.3 = localhost
      DNS.4 = localhost.localdomain
      DNS.5 = 127.0.0.1
      DNS.6 = ::1
      DNS.7 = fe80::1
      
    5. Follow the steps given in the Prerequisites section to initialize and configure Edge Microgateway, if you haven't already done so. When completed, you should have created an Edge Microgateway-aware proxy, an API Product, a Developer, and a Developer App. In addition, you should have run the edgemicro configure command and received a key and secret.

    2. Generate self-signed certificates

    Next, generate the certificates and keys that you'll need to establish TLS:

    1. cd to the $HOME/.edgemicro directory.
    2. Create the following bash script. You can name it anything you wish. For example: keygen.sh.

      #!/bin/bash
      # generate ca
      openssl genrsa -out rootca.key 2048
      openssl req -x509 -new -nodes -key rootca.key -sha256 -days 1024 -out rootca.pem
      # generate key
      openssl genrsa -out tls.key 2048
      openssl req -new -key tls.key -out tls.csr
      # sign cert
      openssl x509 -req -in tls.csr -CA rootca.pem -CAkey rootca.key -CAcreateserial -out tls.crt -days 1024 -sha256 -extensions 'v3_req' -extfile path/openssl.cnf
      
    3. In the bash file, make sure the path to the openssl.cnf file is correct.

    4. Execute the bash file. You will be prompted for certificate information. Be sure to use localhost for the Common Name.

    5. Check that the following files were created:

      • rootca.key
      • rootca.pem
      • tls.key
      • tls.csr
      • rootca.srl
      • tls.crt

    3. Edit the Edge Microgateway config file

    1. Open the Edge Micro config file in an editor. For example:

      vi $HOME/.edgemicro/myorg-test-config.yaml
      
    2. Edit the edgemicro stanza as follows. Note that you are making changes to the port and ssl attributes:

      edge_config:
      ...
      edgemicro:
        port: 8443
        max_connections: 1000
        config_change_poll_interval: 600
        ssl:
          key: /opt/apigee/.edgemicro/tls.key
          cert: /opt/apigee/.edgemicro/tls.crt
          passphrase: admin123
          rejectUnauthorized: true
          requestCert: false
        logging:
      ...
      
    3. Execute the following command to base64-encode the Edge Microgateway configuration file located in $HOME/.edgemicro:

      export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/your_org-your_env-config.yaml`

      where your_org and your_env are the organization and environment you used when you ran the edgemicro config command.

      Remember to place back-ticks (`) around the command. For example:

      export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/docs-test-config.yaml`

    See also, Run Edge Micro as a Docker container.

    4. Run the container

    1. Execute the following command to run the Docker container with Edge Microgateway:

      chown -R 100:101 ~/.edgemicro/ \
      docker run -P -p 8443:8443 -d --name edgemicro \
      -v path_to_your_edgemicro_dir:/opt/apigee/.edgemicro \
      -v path_to_your_logs_dir:/opt/apigee/logs \
      -e NODE_EXTRA_CA_CERTS=/opt/apigee/.edgemicro/rootca.pem \
      -e EDGEMICRO_PORT=8443 \
      -e EDGEMICRO_ORG=$EDGEMICRO_ORG \
      -e EDGEMICRO_ENV=$EDGEMICRO_ENV \
      -e EDGEMICRO_KEY=$EDGEMICRO_KEY \
      -e EDGEMICRO_SECRET=$EDGEMICRO_SECRET \
      -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
      gcr.io/apigee-microgateway/edgemicro:latest
      
    2. Note the following parameters used in the command; they differ from the basic command described in Run Edge Micro as a Docker container.

      • The port is set to 8443.
      • A volume mount is used to mount the key and cert files.
      • The NODE_EXTRA_CA_CERTS variable is used to add a custom CA (as needed in the case of self-signed certs).

    5. Test the TLS configuration

    1. Execute the following cURL command to test the setup. Substitute your basepath and API key into the command. The following example assumes you are in the directory where rootca.pem is located and that the proxy you created has the basepath /hello:

      curl -v https://localhost:8443/hello --cacert rootca.pem \
      -H "x-api-key: Az82fdnfONVCOOE4NKhajxAboDgA3FAo"
      
    2. The verbose cURL output shows each step of the TLS handshaking. If you see an HTTP 200 response, the configuration succeeded:

      *   Trying ::1...ey:Az82fdnfONVCOOE4NKhajxAboDgA3FAo"
      * TCP_NODELAY set
      * Connected to localhost (::1) port 8443 (#0)
      * ALPN, offering h2
      * ALPN, offering http/1.1
      * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
      * successfully set certificate verify locations:
      *   CAfile: rootca.pem
        CApath: none
      * TLSv1.2 (OUT), TLS handshake, Client hello (1):
      * TLSv1.2 (IN), TLS handshake, Server hello (2):
      * TLSv1.2 (IN), TLS handshake, Certificate (11):
      * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
      * TLSv1.2 (IN), TLS handshake, Server finished (14):
      * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
      * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
      * TLSv1.2 (OUT), TLS handshake, Finished (20):
      * TLSv1.2 (IN), TLS change cipher, Client hello (1):
      * TLSv1.2 (IN), TLS handshake, Finished (20):
      * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
      * ALPN, server accepted to use http/1.1
      * Server certificate:
      *  subject: C=US; ST=CO; L=Boulder; O=Docs; OU=Docs; CN=localhost; emailAddress=docs@apigee.com
      *  start date: Dec 14 22:35:28 2018 GMT
      *  expire date: Oct  3 22:35:28 2021 GMT
      *  common name: localhost (matched)
      *  issuer: C=US; ST=CO; L=Boulder; O=Docs; OU=Docs; CN=localhost; emailAddress=docs@apigee.com
      *  SSL certificate verify ok.
      > GET /hello HTTP/1.1
      > Host: localhost:8443
      > User-Agent: curl/7.54.0
      > Accept: */*
      > x-api-key:Az82fdnfaONVCOE4NKhajxAboDA3FAo
      >
      < HTTP/1.1 200 OK
      < x-powered-by: Apigee
      < access-control-allow-origin: *
      < x-frame-options: ALLOW-FROM RESOURCE-URL
      < x-xss-protection: 1
      < x-content-type-options: nosniff
      < content-type: text/plain; charset=utf-8
      < etag: W/"d-GHB1ZrJKk/wdVTdB/jgBsw"
      < date: Fri, 14 Dec 2018 22:43:13 GMT
      < via: 1.1 google
      < alt-svc: clear
      < x-response-time: 1325
      < Connection: keep-alive
      < Transfer-Encoding: chunked
      <
      * Connection #0 to host localhost left intact
      Hello, Guest!
      

    Example: How to configure southbound TLS

    This section explains how to set up a southbound (outgoing) TLS connection between the Edge Microgateway server and a backend target application. The example below uses self-signed certificates.

    1. Initial setup steps

    1. Locate the openssl.cnf file on your system. For example, /etc/ssl/openssl.cnf.
    2. Open the opensssl.cnf file for editing.
    3. Be sure the req_extensions are present in your config file. For example, you should have information similar to the following in your file:

      [ req ]
      ...
      req_extensions          = v3_req
      ...
      
      [ v3_req ]
      extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment
      
    4. Add the following stanza to openssl.cnf to generate the right SNI attributes:

      [ alt_names ]
      DNS.1 = helloworld
      DNS.2 = localhost
      DNS.3 = localhost.localdomain
      DNS.4 = 127.0.0.1
      DNS.5 = ::1
      DNS.6 = fe80::1
      

      Example opensssl.cnf file:

      [ req ]
      distinguished_name      = req_distinguished_name
      attributes              = req_attributes
      req_extensions          = v3_req
      
      [ v3_req ]
      extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment
      
      [ req_distinguished_name ]
      countryName                     = Country Name (2 letter code)
      countryName_min                 = 2
      countryName_max                 = 2
      stateOrProvinceName             = State or Province Name (full name)
      localityName                    = Locality Name (eg, city)
      0.organizationName              = Organization Name (eg, company)
      organizationalUnitName          = Organizational Unit Name (eg, section)
      commonName                      = Common Name (eg, fully qualified host name)
      commonName_max                  = 64
      emailAddress                    = Email Address
      emailAddress_max                = 64
      
      [ req_attributes ]
      challengePassword               = A challenge password
      challengePassword_min           = 4
      challengePassword_max           = 20
      
      [ alt_names ]
      DNS.1 = helloworld
      DNS.2 = localhost
      DNS.3 = localhost.localdomain
      DNS.4 = 127.0.0.1
      DNS.5 = ::1
      DNS.6 = fe80::1
      
    5. Run the edgemicro configure command:

      edgemicro configure -o your_org -e your_env -u your_username

      For more details on configuration, see Part 1: Configure Edge Microgateway.

    6. Copy the key and secret credentials that were returned from edgemicro configure. You will need these values to run the container. For example:

      The following credentials are required to start edge micro
        key: d9c34e1aff68ed969273c016699eabf48780e4f652242e72fc88a43e21252cb0
        secret: 3bc95a71c86a3c8ce04537fbcb788158731t51dfc6cdec13b7c05aa0bd969430
      

    2. Create a Node.js target application

    1. cd to the .edgemicro directory.

    2. Create the following bash script. You can name it anything you wish. For example: keygen.sh.

      #!/bin/bash
      # generate ca
      openssl genrsa -out rootca.key 2048
      openssl req -x509 -new -nodes -key rootca.key -sha256 -days 1024 -out rootca.pem
      # generate key
      openssl genrsa -out tls.key 2048
      openssl req -new -key tls.key -out tls.csr
      # sign cert
      openssl x509 -req -in tls.csr -CA rootca.pem -CAkey rootca.key -CAcreateserial -out tls.crt -days 1024 -sha256 -extensions 'v3_req' -extfile path/openssl.cnf
      
    3. In the bash file, make sure the path to the openssl.cnf file is correct.

    4. Execute the bash file. You will be prompted for certificate information. Be sure to use hellworld for the Common Name.

    5. Check that the following files were created:

      • rootca.key
      • rootca.pem
      • tls.key
      • tls.csr
      • rootca.srl
      • tls.crt
    6. Create a new file called server.js.

      'use strict';
      
      const express = require('express');
      const https = require('https');
      const fs = require('fs');
      
      const options = {
        key: fs.readFileSync("tls.key"),
        cert: fs.readFileSync("tls.crt")
      };
      
      // Constants
      const PORT = 9443;
      const HOST = '0.0.0.0';
      
      // App
      const app = express();
      app.get('/', (req, res) => {
        res.send('Hello world\n');
      });
      
      https.createServer(options, app).listen(PORT);
      
    7. Create a package.json file in the same directory as server.js. For example:

      {
        "name": "helloworld",
        "version": "1.0.0",
        "description": "",
        "main": "server.js",
        "scripts": {
          "test": "echo \"Error: no test specified\" && exit 1",
          "start": "node server.js"
        },
        "author": "",
        "license": "ISC",
        "dependencies": {
          "express": "^4.16.4",
          "fs": "0.0.1-security",
          "https": "^1.0.0"
        }
      }
      
    8. Run npm install to get the dependencies.

    9. Create a new Dockerfile in the same directory as server.js, where WORKDIR is the path to the root of your Node.js app:

      FROM node:8-alpine
      WORKDIR path-to-your-node-app
      COPY package*.json ./
      
      RUN npm install
      COPY . .
      EXPOSE 9443
      CMD [ "npm", "start" ]
      
    10. Build the Docker image:

      docker build -t helloworld . 
      
    11. Start the sample app:

      docker run -P -p 9443:9443 --name helloworld helloworld
      

    3. Create entities on Apigee Edge

    1. Create an Edge Microgateway-aware proxy with these settings. For more information, see Create an Edge Microgateway-aware API proxy on Edge.

      • Proxy name: edgemicro_local
      • Revision: 1
      • Basepath: /local
      • Target: https://helloworld:9443
    2. Create an API product. For details, see Create a product.

    3. Create a developer. For details, see Create a developer.

    4. Create a Developer app. For details, see Create a developer app

    4. Run the container

    1. Open the Edge Micro config file in an editor. For example:

      vi $HOME/.edgemicro/myorg-test-config.yaml
      
    2. Edit the edgemicro stanza as follows. Note that you are making changes to the port and ssl attributes:

      edge_config:
      ...
      edgemicro:
        port: 8443
        max_connections: 1000
        config_change_poll_interval: 600
        ssl:
          key: /opt/apigee/.edgemicro/tls.key
          cert: /opt/apigee/.edgemicro/tls.crt
          passphrase: admin123
          rejectUnauthorized: true
          requestCert: false
        logging:
      ...
      
    3. Execute the following command to base64-encode the Edge Microgateway configuration file located in $HOME/.edgemicro:

      export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/your_org-your_env-config.yaml`

      where your_org and your_env are the organization and environment you used when you ran the edgemicro config command.

      Remember to place back-ticks (`) around the command. For example:

      export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/docs-test-config.yaml`
    4. Run the following command to start Edge Microgateway in the Docker container.

      chown -R 100:101 ~/.edgemicro/ \
      docker run -P -p 8443:8443 -d --name edgemicro \
      -v path_to_your_edgemicro_dir:/opt/apigee/.edgemicro \
      -v path_to_your_logs_dir:/opt/apigee/logs \
      -e EDGEMICRO_PORT=8443 \
      -e EDGEMICRO_ORG=$EDGEMICRO_ORG \
      -e EDGEMICRO_ENV=$EDGEMICRO_ENV \
      -e EDGEMICRO_KEY=$EDGEMICRO_KEY \
      -e EDGEMICRO_SECRET=$EDGEMICRO_SECRET \
      -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
      --link helloworld:helloworld gcr.io/apigee-microgateway/edgemicro
      

    5. Test the TLS configuration

    1. Execute the following cURL command to test the setup. Substitute your the basepath you used in the microgateway-aware proxy and the API key obtained from the Developer app you created on Apigee Edge. For example:

      curl https://localhost:8443/local -k -H "x-api-key: xxxx" -v
      

      You should see this error:

      ...
      *  subject: C=CA; ST=Ontario; L=Toronto; O=Google Canada; OU=Google Cloud Platform; CN=edgemicro; emailAddress=srinandans@google.com
      *  start date: Dec 10 02:12:22 2018 GMT
      *  expire date: Sep 29 02:12:22 2021 GMT
      *  issuer: C=CA; ST=Ontario; L=Toronto; O=Google Canada; OU=Google Cloud Platform; CN=edgemicro; emailAddress=srinandans@google.com
      *  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
      > GET /local HTTP/1.1
      > Host: localhost:8443
      > User-Agent: curl/7.54.0
      > Accept: */*
      > x-api-key: 9fVC65pFj8LrmlPmVyxFjx4KgAHTxqSd
      >
      < HTTP/1.1 502 Bad Gateway
      < Date: Wed, 12 Dec 2018 05:25:01 GMT
      < Connection: keep-alive
      < Content-Length: 93
      <
      * Connection #0 to host localhost left intact
      {"message":"unable to verify the first certificate","code":"UNABLE_TO_VERIFY_LEAF_SIGNATURE"}
      
    2. Re-run Edge Microgateway, but this time add the NODE_EXTRA_CA_CERTS variable.

      chown -R 100:101 ~/.edgemicro/ \
      docker run -P -p 8443:8443 -d --name edgemicro \
      -v path_to_your_edgemicro_dir:/opt/apigee/.edgemicro \
      -v path_to_your_logs_dir:/opt/apigee/logs \
      -e NODE_EXTRA_CA_CERTS=/opt/apigee/.edgemicro/rootca.pem \
      -e EDGEMICRO_PORT=8443 \
      -e EDGEMICRO_ORG=$EDGEMICRO_ORG \
      -e EDGEMICRO_ENV=$EDGEMICRO_ENV \
      -e EDGEMICRO_KEY=$EDGEMICRO_KEY \
      -e EDGEMICRO_SECRET=$EDGEMICRO_SECRET \
      -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
      --link helloworld:helloworld gcr.io/apigee-microgateway/edgemicro
      
    3. Execute the following cURL command. Substitute your basepath and API key as before. For example:

      curl https://localhost:8443/local -k -H "x-api-key: xxxx" -v
      
    4. Check the output. On success, you will get an HTTP 200 status response:

      ...
      > GET /local HTTP/1.1
      > Host: localhost:8443
      > User-Agent: curl/7.54.0
      > Accept: */*
      > x-api-key: 9fVC65pFj8LrmlPmVyxFjx4KgAHTxqSd
      >
      < HTTP/1.1 200 OK
      < x-powered-by: Express
      < content-type: text/html; charset=utf-8
      < etag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0"
      < date: Wed, 12 Dec 2018 05:49:28 GMT
      < x-response-time: 421
      < Connection: keep-alive
      < Transfer-Encoding: chunked
      <
      Hello world
      

    Adding a custom plugin

    You can add new features and capabilities to the microgateway by writing custom plugins. Custom plugins let you interact programmatically with the requests and responses that flow through the microgateway.

    You have two options for deploying plugins to an Edge Microgateway instance running in a docker container:

    The rest of this section assumes that you are familiar with writing and configuring plugins for a standard Edge Microgateway setup. If not, see Develop custom plugins.

    Option A: Mount the plugins directory on a volume

    (Added in v.2.5.27) The steps for adding plugins through a volume mount are similar to the steps required to add any custom plugin to Edge Microgateway. When you run the Docker container, you can mount the plugins directory on your local system (the volume) on the container mount point, which is /opt/apigee/plugins. You then specify the local volume directory in the Edge Microgateway configuration file.

    The following steps illustrate how to use a Docker mount point to include custom plugins.

    1. Stop Edge Microgateway:

      edgemicro stop
      
    2. Create a directory for you custom plugins. For example, create

      $HOME/edgemicro/custom/plugins
      
    3. Add the custom plugin directory to the Edge Microgateway config file. For example:

        plugins:
          dir: $HOME/edgemicro/custom/plugins
          sequence:
            - oauth
            - response-uppercase
        ````
      
    4. Write and test your plugin, according to the directions in Write a simple plugin. Be sure to place your plugin code in the proper directory structure. For example:

      custom
        |
        |-- plugins
          |
          |- response-uppercase
          |     |- index.js
          |     |- package.json
          |- request-headers
          |     | - index.js
                | - package.json
      
    5. Run the Docker container with a command similar to the following, where you use the -v option to mount the plugins directory on the Docker volume. In the following example command, the plugins directory $HOME/edgemicro/custom/plugins (where the custom plugin is located) is mapped to the container's mount point /opt/apigee/plugins:

      chown -R 100:101 ~/.edgemicro/ \
      docker run -P -p 8000:8000 -d --name edgemicro \
      -v /var/tmp:/opt/apigee/logs \
      -v $HOME/edgemicro/custom/plugins:/opt/apigee/plugins \
      -e EDGEMICRO_PROCESSES=1 \
      -e EDGEMICRO_ORG=jdoe \
      -e EDGEMICRO_ENV=test \
      -e EDGEMICRO_KEY=39c4b561100cd7f258768d1072f3e1d7c17b5f36a18fe89972bb5c9ce7e58fb \
      -e EDGEMICRO_SECRET=f5f9e239a38b4e6cc99c2aa067716a84aebdcff9580a7925fc500e402b1a5fa \
      -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
      -e SERVICE_NAME=edgemicro \
      --security-opt=no-new-privileges \
      --cap-drop=ALL gcr.io/apigee-microgateway/edgemicro:latest
      
    6. Call your API to test the plugin.

    For more information, see VOLUME [shared filesystems].

    Option B: Build the plugins into the container

    In this option, you build the plugins into your container.

    1. Package your plugins

    1. Write and test your plugin, according to the directions in Write a simple plugin.

    2. Place your plugin code in the proper directory structure. Plugin directories must follow a set structure. The following example shows the structure you must follow, where response-uppercase and request-headers are the names of folders containing custom plugin code (these names are examples only, your folder names may differ):

      plugin
        |
        |-- plugins
          |
          |- response-uppercase
          |     |- index.js
          |     |- package.json
          |- request-headers
          |     | - index.js
                | - package.json
      
    3. cd to the plugin folder.

    4. In the plugin folder, zip the entire plugins folder:

      zip -r plugins.zip plugins/

    2. Create a Docker image

    Next, create a Dockerfile to add your plugin code to an Edge Microgateway image.

    1. In the same directory where the zip file is located, create a new file called Dockerfile.
    2. Add the following code to Dockerfile and save the file:

      USER root
      RUN apk update && \
          apk upgrade && \
          apk add zipapk add zip && \
          mkdir /opt/apigee/customplugins && \
          chown apigee:apigee /opt/apigee/customplugins
      COPY plugins.zip /opt/apigee/customplugins
      RUN su - apigee -c "unzip /opt/apigee/customplugins/plugins.zip -d /opt/apigee/customplugins"
      EXPOSE 8000
      EXPOSE 8443
      USER apigee
      ENTRYPOINT ["entrypoint"]
      
    3. Create a new Edge Microgateway Docker image with your plugins:

      docker build -t image-name .
      

      For example:

      docker build -t edgemicroplugins .
      

    3. Update the Edge Microgateway configuration

    Now that the plugins are packaged, you need to add them to the Edge Microgateway configuration file.

    1. Open the Edge Microgateway configuration file in an editor:

      $HOME/.edgemicro/org-env-config.yaml
      

      For example:

      vi $HOME/.edgemicro/myorg-test-config.yaml
    2. Add the plugin directory to the configuration file. In the following example the dir attribute specifies the location of the plugin code (which you specified in the Dockerfile). You must also specify the name of the plugin directory, which in the example below is response-uppercase.

      edgemicro:
        ...
        plugins:
          dir: /opt/apigee/plugins
          sequence:
            - oauth
            - response-uppercase
      

    4. Start the microgateway

    Finally, you must start the microgateway in the container.

    1. Run the following command to base64-encode the Edge Microgateway configuration file located in $HOME/.edgemicro:

      export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/your_org-your_env-config.yaml`

      where your_org and your_env are the organization and environment you used when you ran the edgemicro config command.

      Remember to place back-ticks (`) around the command. For example:

      export EDGEMICRO_CONFIG=`base64 $HOME/.edgemicro/docs-test-config.yaml`
    2. Run Edge Microgateway as a container. The command sets several environment variables that are used by the container runtime to start Edge Microgateway:

      docker run -P -p 8000:8000 -d --name edgemicroplugins \
      -e EDGEMICRO_PLUGIN_DIR=/opt/apigee/customplugins/plugins \
      -e EDGEMICRO_ORG=your_org \
      -e EDGEMICRO_ENV=your_env \
      -e EDGEMICRO_KEY=your_key \
      -e EDGEMICRO_SECRET=your_secret \
      -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
      -e SERVICE_NAME=edgemicroplugins image_name

      For example:

      docker run -P -p 8000:8000 -d --name edgemicroplugins \
      -e EDGEMICRO_PLUGIN_DIR=/opt/apigee/customplugins/plugins \
      -e EDGEMICRO_ORG=docs \
      -e EDGEMICRO_ENV=test \
      -e EDGEMICRO_KEY=d9c34e1aff68ed969273b016699eabf48780e4f652242e72fc88a23e21252cb0 \
      -e EDGEMICRO_SECRET=3bc95a71c86a3c8ce04137fbcb788158731t51dfc6cdec13b7c05aa0bd969430 \
      -e "EDGEMICRO_CONFIG=$EDGEMICRO_CONFIG" \
      -e SERVICE_NAME=edgemicroplugins edgemicroplugins
    3. Call your API to test the plugin:

      Test that the plugin code executes by calling your API and verifying that the output is as expected:

      curl -i http://localhost:8000/hello -H "x-api-key:apikey"

      For example, the response-uppercase plugin might return a response like this:

      curl -i http://localhost:8000/hello -H "x-api-key:PydUKRDGIXRqF2xh4usn1FLHbhGKVIz"
        HELLO, WORLD!