title: AWS Lambda Container Image for Ruby Code -- How to test locally with docker run
body: <p>I am migrating a Ruby 2.7 Lambda from zip file deployment to container image deployment.</p>
  <p>When I deploy my container to AWS Lambda, the container behaves as I hope that it would.</p>
  <p>When I attempt to test the same image locally using <code>docker run {my-image-name}</code>, I am encountering 2 issues</p>
  <ol>
  <li>The parameters are not accessible from the event object in the same manner</li>
  <li>The return headers and status code are not honored in the same way as they are handled from Lambda</li>
  </ol>
  <h2>My Questions</h2>
  <ul>
  <li>Do I need to bundle something else into my dockerfile to assist with Lambda simulation?</li>
  <li>Do I need to use a different entrypoint in my dockerfile?</li>
  <li>I found documentation for the &quot;AWS Lambda Runtime Interface Emulator&quot;, but I am unclear if it is designed to assist with the problems I am encountering.</li>
  </ul>
  <p>Here is a simplified version of what I am attempting to test.</p>
  <h2>Dockerfile</h2>
  <pre><code>FROM public.ecr.aws/lambda/ruby:2.7
  
  COPY * ./
  
  RUN bundle install 
  
  CMD [ &quot;lambda_function.LambdaFunctions::Handler.process&quot; ]
  </code></pre>
  <h2>Gemfile</h2>
  <pre><code>source &quot;https://rubygems.org&quot;
  </code></pre>
  <h2>lambda_function.rb</h2>
  <pre><code>
  
  require 'json'
  
  module LambdaFunctions
    class Handler
      def self.process(event:,context:)
        begin
          json = {
            message: 'This is a placeholder for your lambda code',
            event: event
          }.to_json
      
          {
            headers: {
              'Access-Control-Allow-Origin': '*'
            },
            statusCode: 200,
            body: json
          }
        rescue =&gt; e
          {
            headers: {
              'Access-Control-Allow-Origin': '*'
            },
            statusCode: 500,
            body: { error: e.message }.to_json
          }
        end
      end
    end
  end
  
  </code></pre>
  <h2>Running with AWS Lambda</h2>
  <p><em>We have a load balancer making this Lambda available</em></p>
  <pre><code>curl -v https://{my-load-balancer-url}/owners?path=owners
  </code></pre>
  <p>Response - note that the load balancer has converted my GET request to a POST request</p>
  <pre><code>{
      &quot;message&quot;: &quot;This is a placeholder for your lambda code&quot;,
      &quot;event&quot;: {
          &quot;requestContext&quot;: {
              &quot;elb&quot;: {...}
          },
          &quot;httpMethod&quot;: &quot;POST&quot;,
          &quot;path&quot;: &quot;/owners&quot;,
          &quot;queryStringParameters&quot;: {
              &quot;path&quot;: &quot;owners&quot;
          },
          &quot;headers&quot;: {
              &quot;accept&quot;: &quot;*/*&quot;,
              &quot;accept-encoding&quot;: &quot;gzip, deflate, br&quot;,
              &quot;cache-control&quot;: &quot;no-cache&quot;,
              &quot;connection&quot;: &quot;keep-alive&quot;,
              &quot;content-length&quot;: &quot;0&quot;,
              ...
          },
          &quot;body&quot;: &quot;&quot;,
          &quot;isBase64Encoded&quot;: false
      }
  }
  </code></pre>
  <h2>Running in docker</h2>
  <pre><code>docker run --rm --name lsample -p 9000:8080 -d {my-image-name}
  </code></pre>
  <h2>POST request to local docker</h2>
  <pre><code>curl -v http://localhost:9000/2015-03-31/functions/function/invocations -d '{&quot;path&quot;: &quot;owners&quot;}'
  </code></pre>
  <p>Note that the headers are returned as part of the respose</p>
  <p>Response Headers</p>
  <pre><code>&lt; HTTP/1.1 200 OK
  &lt; Date: Fri, 18 Dec 2020 19:06:56 GMT
  &lt; Content-Length: 166
  &lt; Content-Type: text/plain; charset=utf-8
  </code></pre>
  <p>Response Body (formatted)</p>
  <pre><code>{
      &quot;headers&quot;: {
          &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;
      },
      &quot;statusCode&quot;: 200,
      &quot;body&quot;: &quot;{\&quot;message\&quot;:\&quot;This is a placeholder for your lambda code\&quot;,\&quot;event\&quot;:{\&quot;path\&quot;:\&quot;owners\&quot;}}&quot;
  }
  </code></pre>
  <h2>GET request to local docker</h2>
  <pre><code>curl -v http://localhost:9000/2015-03-31/functions/function/invocations?path=owners
  </code></pre>
  <p>No content is returned</p>
  <pre><code>&lt; HTTP/1.1 200 OK
  &lt; Date: Fri, 18 Dec 2020 19:10:08 GMT
  &lt; Content-Length: 0
  </code></pre>