Skip to content

Commit

Permalink
Add node20 to store
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
  • Loading branch information
alexellis committed May 16, 2024
1 parent 7297fce commit 7d4b8c1
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ This repository contains the Classic OpenFaaS templates, but many more are avail
| node16 | NodeJS | 16 | Alpine Linux | of-watchdog | [NodeJS template](https://github.com/openfaas/templates/tree/master/template/node16)
| node17 | NodeJS | 17 | Alpine Linux | of-watchdog | [NodeJS template](https://github.com/openfaas/templates/tree/master/template/node17)
| node18 | NodeJS | 18 | Alpine Linux | of-watchdog | [NodeJS template](https://github.com/openfaas/templates/tree/master/template/node18)
| node18 | NodeJS | 20 | Alpine Linux | of-watchdog | [NodeJS template](https://github.com/openfaas/templates/tree/master/template/node20)
| bun-express | Bun | 1.0 | Alpine Linux | of-watchdog | [NodeJS template](https://github.com/openfaas/templates/tree/master/template/bun-express)
| node | NodeJS | 12 | Alpine Linux | classic | [NodeJS template](https://github.com/openfaas/templates/tree/master/template/node)
| node | NodeJS | 20 | Alpine Linux | classic | [NodeJS template](https://github.com/openfaas/templates/tree/master/template/node)
| python3 | Python | 3 | Alpine Linux | classic | [Python 3 template](https://github.com/openfaas/templates/tree/master/template/python3)
| python3-debian | Python | 3 | Debian Linux | classic | [Python 3 Debian template](https://github.com/openfaas/templates/tree/master/template/python3-debian)
| python | Python | 2.7 | Alpine Linux | classic | [Python 2.7 template](https://github.com/openfaas/templates/tree/master/template/python)
Expand Down
2 changes: 1 addition & 1 deletion template/node/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/classic-watchdog:0.2.3 as watchdog
FROM --platform=${TARGETPLATFORM:-linux/amd64} node:12-alpine as ship
FROM --platform=${TARGETPLATFORM:-linux/amd64} node:20-alpine as ship

ARG TARGETPLATFORM
ARG BUILDPLATFORM
Expand Down
1 change: 1 addition & 0 deletions template/node20/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/node_modules
62 changes: 62 additions & 0 deletions template/node20/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
FROM --platform=${TARGETPLATFORM:-linux/amd64} ghcr.io/openfaas/of-watchdog:0.9.15 as watchdog
FROM --platform=${TARGETPLATFORM:-linux/amd64} node:20-alpine as ship

ARG TARGETPLATFORM
ARG BUILDPLATFORM

COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog
RUN chmod +x /usr/bin/fwatchdog

RUN apk --no-cache add curl ca-certificates \
&& addgroup -S app && adduser -S -g app app

# Turn down the verbosity to default level.
ENV NPM_CONFIG_LOGLEVEL warn

RUN chmod 777 /tmp

USER app

RUN mkdir -p /home/app/function

# Entrypoint
WORKDIR /home/app
COPY --chown=app:app package.json ./

# This ordering means the npm installation is cached for the outer function handler.
RUN npm i

# Copy outer function handler
COPY --chown=app:app index.js ./

# COPY function node packages and install, adding this as a separate
# entry allows caching of npm install

WORKDIR /home/app/function
COPY --chown=app:app function/*.json ./

RUN npm i

# COPY function files and folders
COPY --chown=app:app function/ ./

# Run any tests that may be available
RUN npm test

# Set correct permissions to use non root user
WORKDIR /home/app/

ENV cgi_headers="true"
ENV fprocess="node index.js"
ENV mode="http"
ENV upstream_url="http://127.0.0.1:3000"

ENV exec_timeout="10s"
ENV write_timeout="15s"
ENV read_timeout="15s"

ENV prefix_logs="false"

HEALTHCHECK --interval=3s CMD [ -e /tmp/.lock ] || exit 1

CMD ["fwatchdog"]
12 changes: 12 additions & 0 deletions template/node20/function/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'

module.exports = async (event, context) => {
const result = {
'body': JSON.stringify(event.body),
'content-type': event.headers["content-type"]
}

return context
.status(200)
.succeed(result)
}
12 changes: 12 additions & 0 deletions template/node20/function/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "openfaas-function",
"version": "1.0.0",
"description": "OpenFaaS Function",
"main": "handler.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 0"
},
"keywords": [],
"author": "OpenFaaS Ltd",
"license": "MIT"
}
144 changes: 144 additions & 0 deletions template/node20/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright (c) Alex Ellis 2021. All rights reserved.
// Copyright (c) OpenFaaS Author(s) 2021. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

"use strict"

const express = require('express')
const app = express()
const handler = require('./function/handler');
const bodyParser = require('body-parser')

const defaultMaxSize = '100kb' // body-parser default

app.disable('x-powered-by');

const rawLimit = process.env.MAX_RAW_SIZE || defaultMaxSize
const jsonLimit = process.env.MAX_JSON_SIZE || defaultMaxSize

app.use(function addDefaultContentType(req, res, next) {
// When no content-type is given, the body element is set to
// nil, and has been a source of contention for new users.

if(!req.headers['content-type']) {
req.headers['content-type'] = "text/plain"
}
next()
})

if (process.env.RAW_BODY === 'true') {
app.use(bodyParser.raw({ type: '*/*' , limit: rawLimit }))
} else {
app.use(bodyParser.text({ type : "text/*" }));
app.use(bodyParser.json({ limit: jsonLimit}));
app.use(bodyParser.urlencoded({ extended: true }));
}

const isArray = (a) => {
return (!!a) && (a.constructor === Array);
};

const isObject = (a) => {
return (!!a) && (a.constructor === Object);
};

class FunctionEvent {
constructor(req) {
this.body = req.body;
this.headers = req.headers;
this.method = req.method;
this.query = req.query;
this.path = req.path;
}
}

class FunctionContext {
constructor(cb) {
this.statusCode = 200;
this.cb = cb;
this.headerValues = {};
this.cbCalled = 0;
}

status(statusCode) {
if(!statusCode) {
return this.statusCode;
}

this.statusCode = statusCode;
return this;
}

headers(value) {
if(!value) {
return this.headerValues;
}

this.headerValues = value;
return this;
}

succeed(value) {
let err;
this.cbCalled++;
this.cb(err, value);
}

fail(value) {
let message;
if(this.status() == "200") {
this.status(500)
}

this.cbCalled++;
this.cb(value, message);
}
}

const middleware = async (req, res) => {
const cb = (err, functionResult) => {
if (err) {
console.error(err);

return res.status(fnContext.status())
.send(err.toString ? err.toString() : err);
}

if(isArray(functionResult) || isObject(functionResult)) {
res.set(fnContext.headers())
.status(fnContext.status()).send(JSON.stringify(functionResult));
} else {
res.set(fnContext.headers())
.status(fnContext.status())
.send(functionResult);
}
};

const fnEvent = new FunctionEvent(req);
const fnContext = new FunctionContext(cb);

Promise.resolve(handler(fnEvent, fnContext, cb))
.then(res => {
if(!fnContext.cbCalled) {
fnContext.succeed(res);
}
})
.catch(e => {
cb(e);
});
};

app.post('/*', middleware);
app.get('/*', middleware);
app.patch('/*', middleware);
app.put('/*', middleware);
app.delete('/*', middleware);
app.options('/*', middleware);

const port = process.env.http_port || 3000;

app.listen(port, () => {
console.log(`node18 listening on port: ${port}`)
});


16 changes: 16 additions & 0 deletions template/node20/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "openfaas-node18",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no tests specified\" && exit 0"
},
"keywords": [],
"author": "OpenFaaS Ltd",
"license": "MIT",
"dependencies": {
"body-parser": "^1.18.2",
"express": "^4.16.2"
}
}
12 changes: 12 additions & 0 deletions template/node20/template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
language: node20
fprocess: node index.js
welcome_message: |
You have created a new function which uses Node.js 20 and the OpenFaaS
of-watchdog which gives greater control over HTTP responses.
npm i --save can be used to add third-party packages like request or cheerio
npm documentation: https://docs.npmjs.com/
Unit tests are run at build time via "npm run", edit package.json to specify
how you want to execute them.

0 comments on commit 7d4b8c1

Please sign in to comment.