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

Wanted: serverless deno configuration #1456

Closed
ry opened this issue Jan 3, 2019 · 60 comments
Closed

Wanted: serverless deno configuration #1456

ry opened this issue Jan 3, 2019 · 60 comments
Labels

Comments

@ry
Copy link
Member

ry commented Jan 3, 2019

Would like some scripts and documentation on how to deploy to AWS Lambda, Serverless, GCloud functions, Azure Functions, etc.

@pseudo-su
Copy link

pseudo-su commented Jan 5, 2019

I was considering looking into what a lambda custom layer/runtime might look like.

In a serverless context I think #1386 becomes a lot more important. You don't really want to be re-fetching dependencies on every cold start

@kitsonk
Copy link
Contributor

kitsonk commented Jan 5, 2019

I have a docker image I need to dust off and get available.

@ry
Copy link
Member Author

ry commented Jan 5, 2019

This seems to be an updated docker configuration: https://github.com/maxmcd/deno-docker

@maxmcd What's the status of that project? Is it working? Are there any major missing pieces?

@maxmcd
Copy link

maxmcd commented Jan 5, 2019

The repo was originally intended to be a Dockerfile of the deno dev environment. That is now mostly unmaintained and it's just two simple Dockerfiles: jessie, jessie-slim . They auto-build the latest version every day so they're fairly up to date. I haven't run the test suite off of the build, so maybe there are missing pieces.

As for the context of this issue. I tried to get deno running in Lambda when it first switched over to Rust. Had issues getting it to link with the headers available in the Lambda runtime. Maybe recent changes in Deno or Lambda's new layers have made this a non-issue.

@hayd
Copy link
Contributor

hayd commented Jan 5, 2019

I have working dockerfiles for alpine (85mb)+ubuntu(260mb)+debian(150mb), installing from the linux binary rather than build.
I was thinking they could go to deno_install, but I am not sure where to publish them (note: they are each only a few lines each so perhaps it's not critical to publish them).

Edit: Perhaps I should clarify, "working" as in the deno console works and I tried a few things. I haven't run a vigorous test suite. It'd be cool to have some kind of deno test available to do that for the binary...

Edit2: @maxmcd just looked at your repo, would you accept alpine+ubuntu Dockerfiles there?

https://gist.github.com/hayd/ba4412a6c7ae58deb178348a4c6f37a3

@kitsonk
Copy link
Contributor

kitsonk commented Jan 6, 2019

@hayd you got it to work on alpine only? When I tried, there were some core lib requirements, I think from V8 that I couldn't get in alpine, so I had to revert to an ubuntu base.

@hayd
Copy link
Contributor

hayd commented Jan 6, 2019

@kitsonk Ya it works: See gist: https://gist.github.com/hayd/5360b3cd855bc7ba0eea0e20a8413c29
(all three are working, and i put them on dockerhub)

Edit: btw I took the denoland organization dockerhub, but am not using it. At some point in the future, we can move to it / happy to hand it over.

Edit2: See repo: https://github.com/hayd/deno_docker

@horihiro
Copy link

horihiro commented Jan 6, 2019

Hi @hayd
You use frolvlad/alpine-glibc:alpine-3.8 as base container image.

Thank you so much for useful information!

@ry
Copy link
Member Author

ry commented Jan 6, 2019

Beware that https://hub.docker.com/u/denoland is not me...

(Please contact me if you've squatted it)

It has been transferred to me. I will look into deploying to docker hub as part of our release process.

@hayd
Copy link
Contributor

hayd commented Jan 6, 2019

It's me, I said that above. Happy to hand over.

Edit: Sorry, realized I only mentioned this as a later edit. Ooops.

@ry
Copy link
Member Author

ry commented Jan 6, 2019

Ah sorry didn’t see that - thanks

@maxmcd
Copy link

maxmcd commented Jan 6, 2019

@hayd happy to accept alpine & ubuntu images

Is alpine-glibc the way to go here? Node docker images seem to get away with building without swapping out musl.

@hayd
Copy link
Contributor

hayd commented Jan 6, 2019

It was more expedient to use alpine-glibc... 😄

But I suspect musl is preferable, the proof will be in perf testing between the two options. The Dockerfile for node is helpful.
Edit: OTOH openjdk8 (and hence scala etc.) uses alpine-glibc so it can't be terrible.

@kitsonk
Copy link
Contributor

kitsonk commented Jan 6, 2019

There are certainly challenges to alpine without glibc, Deno appears to work fine with musl, at least I got pretty far with it, it was some non-exported symbols that tripped me up and I didn't know enough about how to deal with them. I don't think it was terminal, but I think it would impact the build process for Deno and I didn't have enough experience to work through it.

@hayd
Copy link
Contributor

hayd commented Jan 6, 2019

I had got to this:

$ /bin/deno  # alpine without glibc
Error relocating /bin/deno: __rawmemchr: symbol not found
Error relocating /bin/deno: strtoll_l: symbol not found
Error relocating /bin/deno: strtoull_l: symbol not found
Error relocating /bin/deno: __register_atfork: symbol not found
Error relocating /bin/deno: __res_init: symbol not found
Error relocating /bin/deno: __isnan: symbol not found
Error relocating /bin/deno: __vfprintf_chk: symbol not found
Error relocating /bin/deno: __vsnprintf_chk: symbol not found
Error relocating /bin/deno: __isinf: symbol not found
Error relocating /bin/deno: __isnanf: symbol not found
Error relocating /bin/deno: backtrace: symbol not found
Error relocating /bin/deno: backtrace_symbols: symbol not found

then found gliderlabs/docker-alpine#11 and used glibc :)

I suspect we'd have to not use any prebuilts, e.g. build v8* etc., which are atm fetching from google storage glibc (?) executables IIUC. This has actually come up with the brew repo: they'd prefer to make all the executables rather than fetch any...

* actually prebuild v8 was removed in #1369 ...

@kitsonk
Copy link
Contributor

kitsonk commented Jan 7, 2019

@hayd yup that list of symbols looks really familiar! 😁

@hayd
Copy link
Contributor

hayd commented Jan 7, 2019

This looks promising/terrifying: https://gist.github.com/tylerchr/15a74b05944cfb90729db6a51265b6c9

@kitsonk
Copy link
Contributor

kitsonk commented Jan 7, 2019

I guess Node.js doesn't run into the issue because they don't use GN? That does look a bit horrifying. Good reference though!

@hayd
Copy link
Contributor

hayd commented Jan 9, 2019

To go back to the original issue, at least with aws lambda it looks like they require musl (or at least this announcement suggests that - I'll try and make a musl binary following those instructions above.

I think the ideal would be to use libdeno in such a way you can pass event+context from rust to a typescript function/entrypoint. IIUC in that way you could start deno once (so that deno is not started upon every lambda invocation, only on the first for the underlying vm - this is kinda interesting, see chromeless where you can keep the chrome app running over multiple invocations).

@ry
Copy link
Member Author

ry commented Jan 9, 2019

If we could get "cargo package" working (#1387), then we could release a crate which will contain a prebuilt libdeno. Using that and Lambda's Rust interface seems like an ideal way to deploy.

@hayd
Copy link
Contributor

hayd commented Jan 10, 2019

Annoyingly RE musl it seems like alpine ships with clang 5.0.1 rather than clang 8.0.0 that deno ships with, unclear how to resolve - it could be that there is some flags. I'll try and share where I got to... 🤕

@kdby-io
Copy link

kdby-io commented Jan 22, 2019

Currently, It is not possible to run Deno in AWS Lambda.
Deno may require GLIBC_2.18, but Lambda container does not include it.

Check below
https://github.com/pueue/deno-custom-lambda
https://blog.pueue.com/2019/Failure-building-an-AWS-Lambda-custom-runtime-for-Typescript-with-Deno/

@balupton
Copy link
Contributor

balupton commented Apr 7, 2019

And guides for zeit's now.sh service?

@hayd
Copy link
Contributor

hayd commented Apr 7, 2019

@balupton is zeit just a wrapper around AWS Lambda?

In order to get a binary for Lambda you need to build deno on musl without glibc dep, I had made some progress following this gist but wasn't able to quite get there... though I'm confident it is feasible.

@mhart
Copy link

mhart commented Apr 23, 2019

You could alternatively add glibc 2.18 to your Lambda zip too – /var/task (where your Lambda package unzips to) is included in LD_LIBRARY_PATH. Or package it up as a layer (will need to put in a lib directory so it unpacks at /opt/lib)

@kt3k
Copy link
Member

kt3k commented May 10, 2019

I've posted an article about AWS Lambda version https://dev.to/kt3k/write-aws-lambda-function-in-deno-4b20

The following scripts worked:

The custom runtime (bootstrap):

#!/bin/sh
set -euo pipefail

SCRIPT_DIR=$(cd $(dirname $0); pwd)
HANDLER_NAME=$(echo "$_HANDLER" | cut -d. -f2)
HANDLER_FILE=$(echo "$_HANDLER" | cut -d. -f1)

export DENO_DIR=/tmp/deno_dir

echo "
import { $HANDLER_NAME } from '$LAMBDA_TASK_ROOT/$HANDLER_FILE.ts';
const API_ROOT =
  'http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/';
(async () => {
  while (true) {
    const next = await fetch(API_ROOT + 'next');
    const reqId = next.headers.get('Lambda-Runtime-Aws-Request-Id');
    const res = await $HANDLER_NAME(await next.json());
    await (await fetch(
      API_ROOT + reqId + '/response',
      {
        method: 'POST',
        body: JSON.stringify(res)
      }
    )).blob();
  }
})();
" > /tmp/runtime.ts
$SCRIPT_DIR/deno run --allow-net --allow-read /tmp/runtime.ts

The lambda function (function.ts):

export async function handler(event) {
  return {
    statusCode: 200,
    body: JSON.stringify({
      version: Deno.version,
      build: Deno.build
    })
  };
}

@kt3k
Copy link
Member

kt3k commented May 10, 2019

I skipped error handling, lambda context handling, etc in the above work. These need to be addressed in later versions.

AWS Lambda supports Lambda Layer, which is a kind of shared resources among lambdas. If we (deno community) maintain the shared deno lambda runtime as a public layer, the users can use it as the base deno runtime and can create lambda functions based on it. I think that's very convenient for new deno users (because creating custom runtime is not so easy).

@ry
Copy link
Member Author

ry commented May 10, 2019

Very nice @kt3k - we got to get that glibc issue solved.

I’m happy to have the runtime in deno_std

@jerrygreen
Copy link

jerrygreen commented Jun 6, 2019

@kt3k great article, great work!

If we will be able to run scripts with Deno out of the box, using AWS Lambda - this will be a total win

@hayd
Copy link
Contributor

hayd commented Nov 3, 2019

^Can confirm the example works on AWS Lambda (with some minor modifications):

Edit: posted in deno_docker: https://github.com/hayd/deno_docker/tree/master/aws-lambda

@hayd
Copy link
Contributor

hayd commented Nov 5, 2019

I published the binary as a release: https://github.com/hayd/deno_docker/releases/tag/v0.23.0
Also, includes a zip layer and zip example function. To try out in the AWS console:

  1. create a layer and upload deno-lambda-layer.zip. Note its ARN.
  2. create a lambda function from scratch with runtime "provide your own bootstrap".
  3. add a layer "Provide a layer version ARN" use the ARN above.
  4. upload deno-lambda-example.zip as function code ("Code entry type": "upload a .zip").
  5. "Save". "Test".

I'll try and write this up soon.

Note: There's now error handling and context, near feature complete.


I've moved the code to here:
https://github.com/hayd/deno_lambda
https://github.com/hayd/deno_lambda/releases

@hayd
Copy link
Contributor

hayd commented Dec 4, 2019

I've added a serverless example to the deno-lambda repo:
https://github.com/hayd/deno-lambda/tree/master/example

It's a port of the Building a REST API in Node.js with AWS Lambda, API Gateway, DynamoDB, and Serverless Framework blogpost by Shekhar Gulat to deno. It uses (a patched version of) @chiefbiiko's dynamodb library to read/write to a dynamodb table.

Deploy in one step with serverless deploy (including the dynamodb table creation).
Note: compilation is done prior to upload: there's no init/runtime compilation (see serverless.yml).

@brianleroux
Copy link

@hayd you're a 🌟 for packaging that runtime thank you! I've added to the AWS SAR (Serverless Application Repository) and feel this should probably be an official thing from the Deno project eventually. In the meantime, it does make getting started with Deno on Lambda ridiculously simple.

I've created two sample apps to demo:

(You can see it running here https://a9gmmkcppj.execute-api.us-east-1.amazonaws.com)

Will be blogging and documenting more soon. If anyone has any questions don't hesitate to ask! Also! Noticing that Deno wants a fair bit of memory so defaulting anywhere around 1gb makes it happiest/fastest coldstart.

@hayd
Copy link
Contributor

hayd commented Dec 19, 2019

@brianleroux nice! Would it be possible to share the template to create/publish the application (layer)? I think it would make a lot of sense to add this to the deno-lambda CI (and then maybe in future that repo can move somewhere more official / we'll be able to use the same code).
I hadn't seen SAR before - that seems like a really nice way to publish (hides the complexity of publishing/managing the Deno layer yourself).

I'm not sure if I've seen this high memory issue - does init time out in this case? what happens? Is it pre-compiled (e.g.)? 1Gb seems relatively high.

@brianleroux
Copy link

Sent a PR! denoland/deno-lambda#17

Def a nicer way to manage the runtime and should be pretty easy to get it all automated. 👍

Memory: didn't know that precompile hack and gonna try it out thx!

@brianleroux
Copy link

Draft of the blog post announcing the capability in Architect if anyone here is interested https://blog.begin.com/deno-runtime-support-for-architect-805fcbaa82c3

@hayd
Copy link
Contributor

hayd commented Jan 13, 2020

If anyone is interested here is a deno-lambda issue tracking all features, any feedback would be very helpful: denoland/deno-lambda#20

RE closing this issue, has anyone tried using GCloud or Azure? It reads like these ought to be more straightforward... 🤷‍♂

@aadamsx
Copy link

aadamsx commented Jan 26, 2020

I make heavy use of Azure Functions these days but I don't think Deno will work in this enviornment. I could use Azure Apps and deploy inside a container, but I have yet to get a Docker container working under Deno for some reason.

@mrgrain
Copy link

mrgrain commented Jan 27, 2020

Hey @aadamsx Could you follow this tutorial to create a custom runtime for Azure Functions?

https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-function-linux-custom-image?tabs=portal%2Cbash&pivots=programming-language-csharp

@enzojs
Copy link

enzojs commented Feb 17, 2020

Found this package that lets you deploy with one click https://github.com/hayd/deno-lambda

@jerrygreen
Copy link

@JoseRMorales huh, thx... And this one looks particularly cool (haven't tried it yet though):

https://github.com/lucacasonato/now-deno

// now.json
{
  "functions": {
    "api/**/*.{j,t}s": {
      "runtime": "[email protected]"
    }
  }
}
// api/hello.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'https://deno.land/x/lambda/mod.ts';

export async function handler(
  event: APIGatewayProxyEvent,
  context: Context
): Promise<APIGatewayProxyResult> {
  return {
    statusCode: 200,
    body: `Welcome to deno ${Deno.version.deno} 🦕`,
    headers: {
      'content-type': 'text/html; charset=utf-8',
    },
  };
}

@enzojs
Copy link

enzojs commented Feb 17, 2020

Thanks @jerrygreen was looking for an example with now!

@hayd
Copy link
Contributor

hayd commented Feb 17, 2020

Currently building the binary for amazonlinux is kinda arduous. If anyone can get the musl build working #3711 that would be incredibly helpful for deno-lambda - it feels close.

@kesor
Copy link

kesor commented May 9, 2020

cc/@hayd

If anyone is interested, I have compiled DENO with V8 in Alpine Linux Docker container - without glibc, but completely using the Alpine muslc library.

https://gist.github.com/kesor/68df53a5d76784a235ca6b0e7efed4d9

Enjoy!

@mhoeger
Copy link

mhoeger commented May 15, 2020

cc: @anthonychu

@hayd
Copy link
Contributor

hayd commented May 15, 2020

Azure Functions: https://github.com/anthonychu/azure-functions-deno-worker

GCloud functions is the only remaining.

... and adding something about these in the documentation.

@brianleroux
Copy link

Cloudrun! https://medium.com/google-cloud/deno-on-cloud-run-89ae64d1664d

@hayd
Copy link
Contributor

hayd commented May 15, 2020

Is Cloud Run third party? It looks like it's Google: https://cloud.google.com/run
Edit : that was in reply to a deleted comment.

I think the conclusion here is to add (or at least start) a "deploy" section to the manual.

@brianleroux
Copy link

Agree! Would appreciate if we put Begin.com in (tho its really more CI/CD to AWS) …also arc.codes for 'native' deployment to AWS!

@hayd
Copy link
Contributor

hayd commented May 16, 2020

I will write something up and submit a PR, likely on Sunday.

@mathiasrw
Copy link

@hayd How did you go with your writing?

@stale
Copy link

stale bot commented Jan 27, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jan 27, 2021
@TooTallNate
Copy link

Shameless plug for running Deno serverless functions with Vercel: https://github.com/TooTallNate/vercel-deno

@stale stale bot removed the stale label Jan 27, 2021
@stale
Copy link

stale bot commented Mar 28, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Mar 28, 2021
@stale stale bot closed this as completed Apr 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests