Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Docker Container Image Support #2188

Closed
ian-whitestone opened this issue Dec 14, 2020 · 7 comments
Closed

Add Docker Container Image Support #2188

ian-whitestone opened this issue Dec 14, 2020 · 7 comments

Comments

@ian-whitestone
Copy link

ian-whitestone commented Dec 14, 2020

Earlier this month, AWS announced container image support for AWS Lambda. This means you can now package and deploy lambda functions as container images, instead of using zip files. The container image based approach will solve a lot of headaches caused by the zip file approach, particularly with file sizes (container images can be up to 10GB) and the dependency issues we all know & love.

In an ideal end state, you should be able to call zappa deploy / zappa update / zappa package (etc.) and specify whether you want to use the traditional zip-based approach or new Docker container based approach. If choosing the latter, Zappa would automatically:

  • Build the new docker image for you
    • Not 100% sure how this would work yet. There is a Python library for docker that could be used. Would need to detect the dependencies a user has in their virtual env. and then install them all in the Docker image creation flow.
    • A simpler alternative could involve a user having a Dockerfile that they point Zappa to, and Zappa just executes the build for that.
  • Pushes the docker image to Amazon's Container Registry solution
    • Automatically creates new repository if one does not exist
  • Creates the lambda function with the new Docker image

For a MVP, we should take a BYOI (bring your own image) approach and just get zappa deploy and zappa update to deploy a lambda function using an existing Docker Image that complies with these guidelines.

@ian-whitestone
Copy link
Author

ian-whitestone commented Dec 14, 2020

Initial Exploration

For an MVP, we should take a BYOI (bring your own image) approach and just get zappa deploy and zappa update to deploy a lambda function using an existing Docker Image that complies with these guidelines.

I was able to get a little POC doing this ☝️ :

image

This is the app.py:

import time

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/")
def serve():
    return jsonify(success=True)

@app.route("/time")
def get_current_time():
    return {"time": round(time.time())}

Steps

  1. I prebuilt a Docker image
FROM amazon/aws-lambda-python:3.8
COPY ./ /var/task/

# Install dependencies with poetry
RUN pip install poetry
RUN POETRY_VIRTUALENVS_CREATE=false poetry install --no-root

CMD [ "handler.lambda_handler" ]

The only hack here is you need to have the handler.py (from zappa library) and zappa_settings.py files baked into your docker image. The zappa_settings.py is read in by the handler.py here, and gets generated here in the zip file creation flow.

To get around this, I'm thinking the following may be a simple solution:

  • Refactor handler.py so it looks for zappa_settings.py file, and if that is not there, it looks for all the settings as environment variables.
  • In zappa flows involving docker, zappa will automatically provide all the contents of zappa_settings.py as environment variables that get provided to the Docker image at runtime. That way we don't need to generate any zappa_settings.py during the Docker build step
  • All that's missing now is adding in handler.py in the docker image. I'm thinking this could be solved by having a snippet users can paste in their Dockerfile which either downloads a copy of handler.py to their image, or grabs it from their Python libraries folder (since they will have to have installed zappa as a dependency in their image setup)
  1. I modified the Zappa code to accept -d / --docker-image-uri as a parameter. If this is provided, it skips all the zip compiling steps, and uses the new lambda create_function API to provide the Docker Image URI.

@dmarkey
Copy link

dmarkey commented Dec 22, 2020

This project looks a little dead.

As the workflow is pretty different with docker, maybe worth forking the relevant bits perhaps?

@dmarkey
Copy link

dmarkey commented Dec 23, 2020

Scratch that.. for the use-case I'm describing https://github.com/adamchainz/apig-wsgi seems to suffice.

(I'm thinking more conventional docker build + terraform kinda setup)

ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Dec 29, 2020
* Make the zappa update and zappa deploy commands accept a new docker_image_uri parameter
* Refactor handler.py so it first looks for zappa_settings.py file (current behaviour), and if that is not there, it looks for all the settings as environment variables (new behaviour)

Related Miserlou#2188
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Dec 29, 2020
* Make the zappa update and zappa deploy commands accept a new docker_image_uri parameter
* Refactor handler.py so it first looks for zappa_settings.py file (current behaviour), and if that is not there, it looks for all the settings as environment variables (new behaviour)

Related Miserlou#2188
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Dec 30, 2020
* Make the zappa update and zappa deploy commands accept a new docker_image_uri parameter
* Refactor handler.py so it first looks for zappa_settings.py file (current behaviour), and if that is not there, it looks for all the settings as environment variables (new behaviour)

Related Miserlou#2188
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Dec 30, 2020
Bump boto3/botocore versions
Bump boto3/botocore versions

Related Miserlou#2188
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Dec 30, 2020
Bump boto3/botocore versions
Bump boto3/botocore versions

Related Miserlou#2188
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Jan 2, 2021
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Jan 2, 2021
* Make the zappa deploy command accept a new docker_image_uri parameter
* Add a new CLI command to generate & save the zappa_settings.py file used by handler.py

Related Miserlou#2188
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Jan 2, 2021
* Raise a NotImplementedError for zappa rollback.

Related Miserlou#2188
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Jan 2, 2021
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Jan 2, 2021
ian-whitestone added a commit to ian-whitestone/Zappa that referenced this issue Jan 2, 2021
@siran
Copy link

siran commented Jan 6, 2021

works like a charm: https://github.com/adamchainz/apig-wsgi

@ArtikUA
Copy link

ArtikUA commented Jun 19, 2021

Keep in mind that Lambdas which are created from ECR have very long cold starts: for my project it's 4.5 seconds compared with 1.2 seconds before
Looks like we need a feature like "concurrency" for warmups

@programmingwithalex
Copy link

@ian-whitestone using the -d / --docker-image-uri flag, is there a way to pass in multiple --build-arg flags for the image?

@ian-whitestone
Copy link
Author

Let's move the conversation over to zappa/Zappa#922 (the new repo). I will reply there @alexanderdamiani @ArtikUA !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants