## 1. Project Overview & Quickstart (yogeshojha/LICENSE)

# LICENSE

Open-source repository yogeshojha/LICENSE

### Repository Details
- **Repository:** [yogeshojha/LICENSE](https://github.com/yogeshojha/LICENSE)
- **Primary Language:** Code

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (yogeshojha/docs)

## File: README.md

# OpenFaaS docs repository

This is the source repository for the OpenFaaS documentation site.

For local development:

```shell
# docker run --rm -it -p 8000:8000 -v `pwd`:/docs squidfunk/mkdocs-material
```

## Published page

This page is published through the use of `mkdocs` and is hosted on https://netlify.com/ with a TLS cert from LetsEncrypt.

* https://docs.openfaas.com/

All commits into master (or merged PRs) will appear on the front-page after being rebuilt.

## mkdocs-material markdown extensions

There are several markdown extensions that can be used to create special formatting. Look at the docs [here](https://squidfunk.github.io/mkdocs-material/extensions/admonition/) for all available extensions.

## Adding OpenFaaS Users

The list of OpenFaaS users can be found within [docs/index.md](docs/index.md#users-of-openfaas).  Additions to this list should be made while maintaining the alphabetical ordering.

---

## File: diagrams/README.md

## Source diagrams

These diagrams are in the original vector or binary format such as Gliffy.

gliffy is a Chrome extension for building technical diagrams.

---

## File: docs/cli/build.md

# Build functions

The OpenFaaS CLI supports various options for building a function.  

For details and examples run 

```bash
faas-cli build --help
```

* Build images with Docker

The `faas-cli build` command builds a Docker image into your local Docker library, which can then be used locally or pushed into a remote Docker registry. Each change of your function requires a new `faas-cli build` command to be issued.

* How to do CI/CD

When it comes to continuous integration and delivery you can use the `faas-cli` tool on your build server to build and deploy your code using the built-in commands. 

* Generate a Dockerfile with `--shrinkwrap`

If you are using an alternative container image builder or are automating the `faas-cli` then you can use the `--shrinkwrap` flag which will produce a folder named `./build/function-name` with a Dockerfile. This bundle can be used with any container builder.

## Building multi-arch images for ARM and Raspberry Pi

If you're Raspberry Pi or ARM servers to run your OpenFaaS on Kubernetes or with faasd server, then you will need to use the `publish` command instead which uses emulation and in some templates cross-compilation to build an ARM image from your PC.

> It is important that you do not install Docker or any build tools on your faasd instance. faasd is a server to serve your functions, and should be treated as such.

The technique used for cross-compilation relies on Docker's [buildx](https://docs.docker.com/buildx/working-with-buildx/) extension and [buildkit project](https://docs.docker.com/develop/develop-images/build_enhancements/). This is usually pre-configured with Docker Desktop, and Docker CE when installed on an Ubuntu system.

First install the QEMU utilities which allow for cross-compilation:

```bash
$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
```

The faas-cli attempts to enable Docker's experimental flag for the CLI, but you may need to run the following, if you get an error:

```
export DOCKER_CLI_EXPERIMENTAL=enabled
```

Now run this command on your laptop or workstation, not on the Raspberry Pi:

```bash
faas-cli publish -f stack.yml --platforms linux/arm/v7
```

If you're running a 64-bit ARM OS like Ubuntu, then use:

```bash
faas-cli publish -f stack.yml --platforms linux/arm64
```

You can also add multiple platforms to publish an image which will run on an ARM device, and on a regular Intel host:

```bash
faas-cli publish -f stack.yml --platforms linux/arm/v7,linux/amd64
```

Then deploy the function:

```bash
faas-cli deploy -f stack.yml
```

## 1.0 Apply build options

The OpenFaaS CLI enables functions to be built with different options, e.g. `dev`, `debug`, etc.

By default all templates provide a minimal build as this optimizes function image sizes. Where appropriate, 3rd-party dependencies can be specified via `requirements.txt`. In scenarios where third-party dependencies also require native (e.g. C/C++) modules,
like `libssh` in Ruby and `numpy` or `pandas` in Python, then `--build-option` can be used.

* How to use

The OpenFaaS CLI provides a `--build-option` flag which enables named sets of native modules to be specified for inclusion in the function build.  

There are two ways to achieve this:

```bash
faas-cli build --lang python3 --build-option dev [--build-option debug]
```

or in YAML:

```yaml
    build_options:
    - debug
    - dev
```

Where multiple functions are being built, the YAML configuration is recommended over use of the CLI flag, as the CLI flag applies the `--build-option` to all functions involved in the build activity.

> Currently, of the official templates, Python and Ruby templates include named build options.

* Edit templates to support additional build options

It is possible to amend build options in both official and custom templates.  

> Altering of official templates should be carefully considered in the context of repeatable builds

In order to modify a template to support further build options, edit the `template.yml` using the following pattern:

```yaml
build_options: 
  - name: dev
    packages: # A list of required packages
      - make
      - automake
      - gcc
      #- etc.
  - name: debug
    packages: 
      - mg
      - iw
      #- etc.
```

and if not already present edit `Dockerfile` with:

```dockerfile
# Add the following line
ARG ADDITIONAL_PACKAGE 

# Edit `RUN apk --no-cache add curl \` to the following
RUN apk --no-cache add curl ${ADDITIONAL_PACKAGE} \  

```
## 2.0 Pass ADDITIONAL_PACKAGE through `--build-arg`

There may be scenarios where a single native module need to be added to a build.  A single-package build option could be added as described above.  Alternatively a package could be specified through a `--build-arg`.

```bash
faas-cli build --lang python3 --build-arg ADDITIONAL_PACKAGE=jq
```

In the event a `build-option` is set the effect will be cumulative:

```bash
faas-cli build --lang python3 --build-option dev --build-arg ADDITIONAL_PACKAGE=jq
```

The entries in the template's Dockerfile described in 1.0 above need to be present for this mode of operation.

## 3.0 Pass custom build arguments

You can pass `ARG` values to Docker via the CLI.

```bash
faas-cli build --build-arg ARGNAME1=argvalue1 --build-arg ARGNAME2=argvalue2
``` 

Remeber to add any `ARG` values to the template's Dockerfile:

 ```dockerfile
 ARG ARGNAME1
 ARG ARGNAME2
 ```

 For more information about passing build arguments to Docker, please visit the [Docker documentation](https://docs.docker.com/engine/reference/commandline/build/)

## 4.0 Building with large function sets

Performing a `build` action against a `stack.yml` which contains a large suite of serverless function definitions will result in each of the defined functions being built.  The CLI makes available facilities that assist in this scenario.

The `--parallel` flag aims to reduce total build time by enabling more than one function build action to take place concurrently.  Additionally, there may be situations where building *all* the defined functions is undesirable - for example where only one of the functions has had its code updated.  In this instance the `--filter` and `--regex` flags can be used.

Consider a project with `fn1`, `fn2`, `fn3`, `fn22`, `fn33` functions all defined within a single YAML file.

### 4.1 Using the `--parallel` flag

Parallel enables the user to specify how many concurrent function build actions should be performed.  The default is that functions will be built serially, one after the other.

The following will see all the project functions' build actions performed concurrently:

```bash
faas-cli build --parallel 5
``` 

!!! note
    Remember to add -f if using a non-default yaml file: `faas-cli build --parallel 5 -f projectfile.yml`

Parallel can be combined with either of the `--filter` and `--regex` flags to parallel build a subset of the functions.

### 4.2 Using the `--filter` flag

Filter performs wildcard matching against function names in YAML file so that the build action will only be performed against those that match.

The following filter would build only `fn2` from `stack.yml`:

```bash
faas-cli build --filter "fn2"
``` 
Wildcards can be added using `*`.  The following will result in both `fn2` and `fn22` being built:

```bash
faas-cli build --filter "fn2*"
``` 

### 4.3 Using the `--regex` flag

Regex performs a similar action to `--filter` but allows for more complex patterns to be defined through regular expressions.

The following regex would result in `fn1`, `fn2` & `fn3` being built from the earlier project's `stack.yml`:

```bash
faas-cli build --regex "fn[0-9]$"
```

---

## File: docs/cli/completion.md

# Shell Completion
The OpenFaas CLI has a shell completion feature for Bash and ZSH.

## Bash for Linux
Bash for Linux requires [bash-completion](https://github.com/scop/bash-completion), please follow their installation [here](https://github.com/scop/bash-completion#installation).

Verify if it was installed correctly by executing the following command `type _init_completion`.

You can enabled OpenFaaS completion with two different commands:
```bash
$ echo 'source <(faas-cli completion --shell bash)' >>~/.bashrc
```

Or:
```bash
$ faas-cli completion --shell bash > /etc/bash_completion.d/faas-cli
```

## Bash for MacOS
By default MacOS comes with Bash 3.2, but the completion requires version 4.1+. See this [instructions](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba) to upgrade.

Also, you'll need bash-completion v2. Install with the following commands:
```bash
$ brew install bash-completion@2
```

And add the following to your `~/.bashrc` file:
```bash 
export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
```

You can enabled OpenFaaS completion with two different commands:
```bash
$ echo 'source <(faas-cli completion --shell bash)' >>~/.bashrc
```

Or:
```bash
$ faas-cli completion --shell bash > /etc/bash_completion.d/faas-cli
```

## ZSH
ZSH completion is simpler, just execute the following command:

```bash
source <(faas-cli completion --shell zsh)
```

---

## File: docs/cli/install.md

# Installation

You can install the CLI with a `curl` utility script, `brew` or by downloading the binary from the releases page. Once installed you'll get the `faas-cli` command and `faas` alias.

## Linux or macOS

Utility script with `curl`:

```bash
$ curl -sSL https://cli.openfaas.com | sudo -E sh
```

> The flag `-E` allows for any `http_proxy` environmental variables to be passed through to the installation bash script.

Non-root with curl downloads the binary into your current directory and will then print installation instructions:

```bash
$ curl -sSL https://cli.openfaas.com | sh
```

Via brew:

```bash
$ brew install faas-cli
```

!!! note
    The `brew` release may not run the latest minor release but is updated regularly.

## Windows

In PowerShell:

```powershell
$version = (Invoke-WebRequest "https://api.github.com/repos/openfaas/faas-cli/releases/latest" | ConvertFrom-Json)[0].tag_name
(New-Object System.Net.WebClient).DownloadFile("https://github.com/openfaas/faas-cli/releases/download/$version/faas-cli.exe", "faas-cli.exe")
```

## Environment variable overrides

Several overrides exist which will be used by default if set and no other command-line flag has been set.

* `OPENFAAS_TEMPLATE_URL` - to set the default URL to pull templates from
* `OPENFAAS_PREFIX` - for use with `faas-cli new` - this can act in place of `--prefix`
* `OPENFAAS_URL` - to override the default gateway URL

## Running `faas-cli` with sudo

If you're running the faas-cli with `sudo` we recommend using `sudo -E` to pass through any environmental variables you may have configured such as a `http_proxy`, `https_proxy` or `no_proxy` entry.

## Docker image

The `faas-cli` is also available as a Docker image making it convenient for use in CI jobs such as with a Jenkins pipeline or a task in cron.

https://hub.docker.com/r/openfaas/faas-cli/tags/

There is no "latest" tag, so find the version of the CLI you want to use from the tags page on the Docker Hub. These correspond to the release from GitHub.

> Note: the Docker image cannot be used to perform a build directly, but you can use it to generate a build context which can be used with a container builder such as Docker, buildkit or Kaniko in another part of your build pipeline.

Use-cases for the Docker image:

* Generate the build context without running `docker build`  - `faas-cli --shrinkwrap` 
* Deploy an existing image to a remote server `faas-cli deploy`
* Manage secrets with `faas-cli secret`
* Invoke functions via cron with `faas-cli invoke`
* Check the health of your remote gateway with `faas-cli info`

## Building from source

The [contributing guide](/community/#contribute) has instructions for building from source and for configuring a Golang development environment. 

* **Star/fork** on GitHub: [faas-cli](https://github.com/openfaas/faas-cli)

## Tutorial: learn how to use the CLI

[Morning coffee with the OpenFaaS CLI](https://blog.alexellis.io/quickstart-openfaas-cli/)

---

## File: docs/cli/logs.md

# Function Logs

Via an extensible API, OpenFaaS provides access to function logs via the Gateway API and the CLI. This provides a simple and consistent way to access function logs regardless of your orchestration provider.

The log provider for Kubernetes `faas-netes` fetches records directly from the Kubernetes API, so it will give similar output to `kubectl logs -n openfaas-fn deploy/function`.

The `faas-cli logs NAME` command will stream the logs for the named function.  By default, it will attempt to follow the logs, but you can control the behavior of the stream using these flags

```sh
  -g, --gateway string           Gateway URL starting with http(s):// (default "http://127.0.0.1:8080")
  -h, --help                     help for logs
      --instance                 print the function instance name/id
      --lines int                number of recent log lines file to display. Defaults to -1, unlimited if <=0 (default -1)
      --name                     print the function name
  -n, --namespace string         Namespace of the function
  -o, --output logformat         output logs as (plain|keyvalue|json), JSON includes all available keys
      --since duration           return logs newer than a relative duration like 5s
      --since-time timestamp     include logs since the given timestamp (RFC3339)
  -t, --tail                     tail logs and continue printing new logs until the end of the request, up to 30s (default true)
      --time-format timeformat   string format for the timestamp, any value go time format string is allowed, empty will not print the timestamp (default 2006-01-02T15:04:05Z07:00)
```

## Log structure

The logs for a function will look

```
<RCF8601 Timestamp> <function name> (<container instance>) <msg>
```

where `msg` is the container logs, this typically contains stdout and stderr of the _contianer_.

An example log output for `nodeinfo` from the function store is

```sh
2019-07-21 07:57:14.437219758 +0000 UTC nodeinfo (nodeinfo-867cc95845-p9882) 2019/07/21 07:57:14 Wrote 92 Bytes - Duration: 0.121959 seconds
```

You can also get logs in JSON format:

```bash
$ faas-cli logs trove --format json

{"name":"trove","namespace":"openfaas-fn","instance":"9174","timestamp":"2021-02-12T17:01:03.088068Z","text":"User requested \"Insiders Update: 1st Feb 2020 - Java, KubeCon, Istio, Crossplane and more!\""}
```

## Filter and Search

The CLI writes logs to stdout, so it can easily be chained with any of your favorite CLI tools: `grep`, `sed`, [`fzf`](https://github.com/junegunn/fzf) etc.

For example, when you set the `write_debug` environment variable in the Sentiment Analysis function from the Store, it will print the function output to the logs, we can then search that output using grep.  For example,

```sh
faas-cli store deploy SentimentAnalysis --env write_debug=true
echo "i like code" | faas-cli invoke sentimentanalysis
echo "i like functions" | faas-cli invoke sentimentanalysis
echo "i like containers" | faas-cli invoke sentimentanalysis

faas-cli logs sentimentanalysis | grep sentence_count
2019-07-22 12:44:08.202436478 +0000 UTC sentimentanalysis (sentimentanalysis-7887c5d8c5-5rnb5) {"polarity": 0.0, "sentence_count": 1, "subjectivity": 0.0}
2019-07-22 12:44:10.11422064 +0000 UTC sentimentanalysis (sentimentanalysis-7887c5d8c5-5rnb5) {"polarity": 0.0, "sentence_count": 1, "subjectivity": 0.0}
2019-07-22 12:44:11.882708263 +0000 UTC sentimentanalysis (sentimentanalysis-7887c5d8c5-5rnb5) {"polarity": 0.0, "sentence_count": 1, "subjectivity": 0.0}
```

## Log Retention and History

Log retention and history will be determined by your cluster configuration and the log provider installed. The default configuration in the function provider for Kubernetes streams logs directly from the cluster. This means that you will only see logs from running function containers, and no long term history is not available. If you delete a function, you remove access to its logs.

With faasd, logs are stored in the [journal](https://wiki.archlinux.org/index.php/Systemd/Journal), so the retention period lasts beyond the life of a function, however it may be limited by time or the number of lines.

If you want to retain logs over time, consider using a log aggregator like [Elastic Search](https://www.elastic.co/), [Logz.io](https://logz.io) or [Humio](https://www.humio.com) as an external data-store.

[Grafana Loki](https://grafana.com/oss/loki/) can also provide fast access to logs without much additional overhead on the cluster. A log provider exists to enable "faas-cli" and the OpenFaaS API to query an external data-store, instead of Kubernetes itself.

## Alternative Log Providers

The log system is designed to be extended with alternative providers, this means that logs could instead be supplied by a persistent storage, e.g. Loki or ElasticSearch.  See the [logs provider overview](../architecture/logs-provider.md) for more details about how providers work and available alternatives.

## Structured Logs

Structured logs are a form of machine-readable logs that treats logs as data sets rather than text which allows logs to be more easily searched and analyzed. Typically, these will be in the form of a JSON object on a single line and will allow you to achieve a high level of granular detail.

Introduced in of-watchdog v0.8.2, you can set the `prefix_logs` environment variable to `false`. This will remove the log prefix for all messages received via stdout/stderr, meaning that only the `<msg>` will be sent to the terminal.

---

## File: docs/cli/secrets.md

# Manage secrets

The OpenFaaS CLI allows you to create, update, list and delete secrets using `faas-cli` instead of Docker or Kubernetes command line tools.

The reason behind this is to give you simplicity when you need to use secrets for your functions as well as to provide a layer of abstraction, as it will work for both Kubernetes and [faasd](/deployment/faasd/).

See also: `faas-cli secret --help`

## Create

To create a secret from stdin, you can run:

```bash
faas-cli secret create secret-name
```

Or pipe the value from a file instead:

```
cat 04385e5c413c10ed68afb010ebe8c5dd706aa20a | faas-cli secret create secret-name
cat ~/Downloads/derek.pem | faas-cli secret create secret-name
```

If you want to pass a value then do:

```bash
faas-cli secret create secret-name \
  --from-literal="04385e5c413c10ed68afb010ebe8c5dd706aa20a"
```

To create it from file use:

```bash
faas-cli secret create secret-name \
  --from-file=~/Downloads/derek.pem
```

Target a specific namespace:

```bash
faas-cli secret create \ 
  --namespace staging-fn \
  secret-name \
  --from-literal="04385e5c413c10ed68afb010ebe8c5dd706aa20a"
```

Note: you will need to follow the instructions for [multiple namespaces](/reference/namespaces) for the above command.

You can pass `--gateway` flag if you'd like to create the secret for a specific OpenFaaS instance.

See also: `faas-cli secret create --help`

## Update

From stdin:
```
faas-cli secret update secret-name
```
or
```
cat 04385e5c413c10ed68afb010ebe8c5dd706aa20a | faas-cli secret update secret-name
cat ~/Downloads/derek.pem | faas-cli secret update secret-name
```

From literal:
```
faas-cli secret update secret-name --from-literal="04385e5c413c10ed68afb010ebe8c5dd706aa20a"
```

From file:
```
faas-cli secret update secret-name --from-file=~/Downloads/derek.pem
```

See also: `faas-cli secret update --help`

## List

To list secrets in the default namespace:

```bash
faas-cli secret list
faas-cli secret ls
```

To list secrets in an alternative namespace:

```bash
faas-cli secret ls --namespace staging
```

To list secrets for an OpenFaaS instance use:

```bash
faas-cli secret ls --gateway http://127.0.0.1:8080
```

If you have set `$OPENFAAS_URL` you can use only

```bash
faas-cli secret ls
```

This will output:

```bash
NAME
secret-name1
secret-name2
...
```

See also: `faas-cli secret list --help`

## Delete

You can delete secrets with:
```bash
faas-cli secret remove secret-name
```

or

```bash
faas-cli secret remove secret-name \
  --gateway=http://127.0.0.1:8080
```

See also: `faas-cli secret delete --help`

---

## File: docs/cli/tags.md

# Working with image tags

All OpenFaaS functions are built into immutable Docker images before deployment. You can take advantage of Docker "tags" to organise your versions the CLI can also generate tags based upon Git metadata.

## Option 1 - YAML file

You can define your tag in the stack YAML file. By default this tag is ":latest"

```
image: my-fn
```

or


```
image: my-fn:latest
```

## Option 2 - `--tag` option

The `--tag` option works with the `faas-cli` sub-commands: `build`, `push` and `deploy`.

When using a --tag feature which relies on metadata from a Git commit then the build, push and deploy commands must be run pointing at the same Git commit.

Example usage:

```
faas-cli build --tag=sha|branch|describe
faas-cli push --tag=sha|branch|describe
faas-cli deploy --tag=sha|branch|describe
```

There are currently three formats for "automatic tags".

### 2.1 Use the SHA (`--tag=sha`)

In this example whatever tag is defined in your YAML file (or latest, if not is given) will be suffixed with "-" plus the short Git SHA. A Git repository will be required to use this feature.

Example:

```
image: my-fn:0.2

image: my-other-fn
```

Gives the equivalent:


```
image: my-fn:0.2-cf59cfc

image: my-other-fn:latest-cf59cfc
```

### 2.2 Use the SHA plus the branch (`--tag=branch`)

In this example you will get an output which includes the SHA and the branch name. This is useful for promotion code through enviroments with a continuous delivery tool. If you use one branch per environment in Git then the tool can parse the tag and match it to an environment.


Example:

(on the master branch)

```
image: my-fn:0.2

image: my-fn:latest
```

Gives the equivalent:

```
image: my-fn:0.2-master-cf59cfc

image: my-fn:latest-master-cf59cfc
```

(on the staging branch)

```
image: my-fn:0.2-staging-cf59cfc

image: my-fn:latest-staging-cf59cfc
```

### 2.3 Use the output of `git describe` (`--tag=describe`)

In this example you will get the output of `git describe --tags --always`. This returns a human readable name based on an available git ref. Using `--tags`, means that the output which can be read as `<most-recent-parent-tag>-<number-of-commits-to-that-tag>-g<short-sha>`. Using `--always`, means that if the repo does not use tags, then we will still get the short SHA as output, matching `--tag=sha`

Example:

If you set the image name as

```
image: my-fn:0.2

image: my-fn:latest
```

Then, if you have no tags in the repo, `faas-cli` produces the equivalent:

```
image: my-fn:0.2-b0da13a

image: my-fn:latest-cfb0da13a59cfc
```

If you have just tagged the current commit in the repo, then `faas-cli` produces the equivalent:

```
image: my-fn:0.2-v0.1.0

image: my-fn:latest-v0.1.0
```
Note that the middle value, `<number-of-commits-to-that-tag>` is omitted when it is 0, that is, when you build that tag.

If there have been several commits (e.g. 3) since the most recent tag, then `faas-cli` produces the equivalent:

```
image: my-fn:0.2-v0.1.0-1-gb0da13a

image: my-fn:latest-v0.1.0-3-gb0da13a
```

A word of caution, this can only reference the tags that your local repository knows of, make sure to run `git fetch --tags` to ensure that you have a copy of all remote tags.

---

## File: docs/cli/templates.md

# Create new functions

## Get started

Once you've installed the `faas-cli` you can start creating and deploying functions via the `faas-cli up` command or using the individual commands:

* `faas-cli build` - build an image into the local Docker library
* `faas-cli push` - push that image to a remote container registry
* `faas-cli deploy` - deploy your function into a cluster

The `faas-cli up` command automates all of the above in a single command.

For Raspberry Pi and ARM, you must use the `publish` command instead of `build` and `push`, or `up`.

See the notes here: [Building multi-arch images for ARM and Raspberry Pi](/cli/build/)

## Templates

The OpenFaaS CLI has a template engine built-in which can create new functions in a given programming language. The way this works is by reading a list of templates from the `./template` location in your current working folder.

Before creating a new function make sure you pull in the official OpenFaaS language templates from GitHub via the [templates repository](https://github.com/openfaas/templates).

```bash
$ faas-cli template pull
```

This page shows how to generate functions in the most popular languages and explains how you can manage their dependencies too.

### Classic vs. of-watchdog templates

The *Classic Templates* are held in the [openfaas/templates](https://github.com/openfaas/templates) repository and are based upon the *Classic Watchdog* which uses STDIO to communicate with your function. The of-watchdog uses HTTP to communicate with functions and most of its templates are available in the [openfaas-incubator](https://github.com/openfaas-incubator/) organisation on GitHub and in the store.

How to pick:

* Use the *Classic Watchdog* if you're starting out or following tutorials or guides
* Use the *of-watchdog* if you need more performance or if you need full control of the HTTP response

See also: [watchdog design](/architecture/watchdog/)

### Template store

You can browse templates from the official store or create your own store and add your own templates there.

To see what templates are available type `faas-cli template store list` and you should see the following in the terminal:

```sh
$ faas-cli template store list

NAME                    SOURCE             DESCRIPTION
csharp                  openfaas           Official C# template
dockerfile              openfaas           Official Dockerfile template
...
node10-express          openfaas-incubator NodeJS 10 Express template
ruby-http               openfaas-incubator Ruby 2.4 HTTP template
golang-middleware       openfaas-incubator Golang Middleware template
csharp-httprequest      distantcam         C# HTTP template
...
```

Choose a template and retrieve it locally with the command:

```sh
$ faas-cli template store pull node10-express
```  

Once downloaded, your chosen template and any others stored in the same repository will be available to use:

```sh
$ faas-cli new --list
Languages available as templates:
- node10-express
```

You can add your own store just by specifying the `--url` flag for both commands to pull and list your custom templates store.

The classic templates are held in the [openfaas/templates](https://github.com/openfaas/templates) repository.

#### Go templates

There are several Golang templates available, which are listed below.

| Name | Style        | Watchdog     | Dependencies     |
|:-----|:-------------|:-------------|:-----------------|
| `go` | Function     | classic      | `dep`            |
| `golang-middleware` | Microservice     | of-watchdog      | `dep` or Go modules            |
| `golang-http` | Function     | of-watchdog      | `dep` or Go modules            |

All templates are available via `faas-cli template store list/pull`

#### Go `golang-http` - (of-watchdog template)

[Read the README for golang-http](https://github.com/openfaas-incubator/golang-http-template), this template has a similar-style of API to AWS Lambda.

Golang modules are supported via `--build-arg` using `GO111MODULE=1` or `GO111MODULE=auto`

#### Go `golang-middleware` - (of-watchdog template)

[Read the README for golang-middleware](https://github.com/openfaas-incubator/golang-http-template), this template is ideal for full control over the HTTP request and response and corresponds to a HTTP middleware in Go.

```golang
func Handle(w http.ResponseWriter, r *http.Request) {
}
```

Golang modules are supported via `--build-arg` using `GO111MODULE=1` or `GO111MODULE=auto`

#### Go `go` - (classic template)

To create a new function named `go-fn` in Go type in the following:

```bash
$ faas-cli new go-fn --lang go
```

You will now see two files generate:

```sh
go-fn.yml
./go-fn/
./go-fn/handler.go
```

You can now edit `handler.go` and use the `faas-cli` to `build` and `deploy` your function.

##### Go `go` - dependencies

Dependencies should be managed with a Go vendoring tool such as `dep` or Go modules.

With Go modules:

Set the following `build_arg` in your stack.yml file, or use `faas-cli build/up --build-arg GO111MODULE=on`.

```yaml
functions:
  with_go_modules:
    handler: ./with_go_modules
    lang: go
    build_args:
      GO111MODULE: on
```

If you would like to include sub-modules, you can create a GO_REPLACE.txt file and populate it with the contents of your go.mod. A replace statement is required for use with the classic Go template.


Create your sub-package i.e. `handlers` and run `cd handlers ; go mod init`

Here's handlers/handlers.go:

```golang
package handlers

import (
	"fmt"

	execute "github.com/alexellis/go-execute/pkg/v1"
)

func Handle() {
	ls := execute.ExecTask{
		Command: "exit 1",
		Shell:   true,
	}
	res, err := ls.Execute()
	if err != nil {
		panic(err)
	}

	fmt.Printf("stdout: %q, stderr: %q, exit-code: %d\n", res.Stdout, res.Stderr, res.ExitCode)
}
```

Within your handler.go:

```golang
package function

import (
	"fmt"

	"github.com/alexellis/with-modules/handlers"
)

// Handle a serverless request
func Handle(req []byte) string {

	handlers.Handle()

	return fmt.Sprintf("Hello, Go. You said: %s", string(req))
}
```

GO_REPLACE.txt:

```
replace github.com/alexellis/with-modules/handlers => ./function/handlers
```

Now you can build with `--build-arg GO111MODULE=on` or with a `build_arg` map entry for the function in its stack.yml.

With `dep`:

* Get [dep](https://github.com/golang/dep)

```
$ go get -u github.com/golang/dep/cmd/dep
```

* Initialise the dependencies

```
$ $GOPATH/bin/dep init
```

* Now vendor a library

Make sure you're in the `go-fn` folder, now use `dep ensure -add` and the name of the library you want. In this example we are vendoring the `github.com/cnf/structhash` package for use in our function.

```
$ dep ensure -add github.com/cnf/structhash
```

* Reference the package from function

You can now edit your function and add an import statement in `handler.go` to `github.com/cnf/structhash`.

##### Go `go` - with CGO

First you will need to add the `dev` build option:

```yaml
    build_options:
    - dev
```

This installs `gcc`, `make`, `git` and some other related packages for the build portion of the function's Dockerfile.

You can then enable CGO with a build-arg:

```
faas-cli build --build-arg CGO_ENABLED=1
```

#### Python 3 templates

For production use, serving machine learning models, and high-traffic functions, it's advisable to use the newer templates built with flask and the OpenFaaS of-watchdog.

See the [python-flask-template repo](https://github.com/openfaas-incubator/python-flask-template) for the following templates:

* python27-flask
* python3-flask
* python3-flask-debian
* python3-http
* python3-http-debian

#### Python 3 (classic template)

To create a Python function named `pycon` type in:

```
$ faas-cli new pycon --lang python3
```

You'll see:

```
pycon.yml
pycon/handler.py
pycon/requirements.txt
```

> Note: Python 2.7 is also available with the language template `python`, but the Python community now consider [Python version 2.7 to be deprecated and end-of-life](https://www.python.org/dev/peps/pep-0373/).

##### Python: dependencies

You should edit `pycon/requirements.txt` and add any pip modules you want with each one on a new line, for instance `requests`.

The primary Python template uses Alpine Linux as a runtime environment due to its minimal size, but if you need a Debian environment so that you can compile `numpy` or other modules then read on to the next section.

##### Python: advanced dependencies

If you need to use pip modules that require compilation then you should try the python3-debian template then add your pip modules to the `requirements.txt` file.

```
$ faas-cli template pull
$ faas-cli new numpy-function --lang python3-debian
$ echo "numpy" > ./numpy-function/requirements.txt
$ faas-cli build -f ./numpy-function.yml
...

Step 11/17 : RUN pip install -r requirements.txt
 ---> Running in d0ff430a607e
Collecting numpy (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/6e/dc/92c0f670e7b986829fc92c4c0208edb9d72908149da38ecda50d816ea057/numpy-1.14.2-cp36-cp36m-manylinux1_x86_64.whl (12.2MB)
Installing collected packages: numpy
Successfully installed numpy-1.14.2

...
```

#### Node.js 12 `node12` (of-watchdog template)

There are three Node.js templates which use the newer of-watchdog:

| Name | Style | Runtime | Version | async/await | Supported by nodejs.org |
|:-----|:--------|:--------|:--------|:--------------|:------------------------|
| node8-express            | Function | NodeJS | 8.x | no      | no                      |
| node10-express           | Function | NodeJS | 10.x | no      | no                      |
| node10-express-service   | Micro-service | NodeJS | 10.x | no      | no                      |
| node12                   | Function | NodeJS | 12.x | yes     | yes, LTS version        |

It is recommended that all new users opt for the `node12` template.

For more details on the `event` and `context` objects, see the [README.md](https://github.com/openfaas-incubator/node10-express-template) for the node10-express template, this also applies to `node12`.

##### Node.js 12 `node12` - async/await

```js
"use strict"

module.exports = async (event, context) => {
    const result =             {
        status: "Received input: " + JSON.stringify(event.body),
    };
    return result
}
```

##### Node.js 12 `node12` - adding unit tests

By default, an empty test step is written to package.json inside your function's handler folder, you can override this with your own command or test runner.

For example:

```json
{
  "name": "function",
  "version": "1.0.0",
  "description": "",
  "main": "handler.js",
  "scripts": {
    "test": "mocha test/test.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^7.0.1"
  }
}
```

Then create at least one test file such as: `function-name/test/test.js`:

```js
var chai = require("chai")
var expect = chai.expect;

describe('MyFunction', function() {
  expect("foobar").to.have.lengthOf(3);
})
```

If the tests fail, this will also fail the build of your function and prevent it from passing. The logs will be made available via the logs of `faas-cli build/up`.

##### Node.js 12 `node12` - async/await with error

```js
"use strict"

module.exports = async (event, context) => {
    throw new Error("there was an error created in the function")
}
```

##### Node.js 12 `node12` - without async/await

```js
"use strict"

module.exports = (event, context) => {
    let err;
    const result =             {
        status: "Received input: " + JSON.stringify(event.body),
    };

    context.succeed(result).
    status(201);
}
```

##### Node.js 12 `node12` - Access to the raw body

Set the environment variable `RAW_BODY` to `true` to set the `context.body` to the original request body rather than the default behavior of parsing it as JSON.

This is useful where the original body needs to be passed to the function code without any parsing or processing. For instance, when working with binary data, or verifying the signature of a webhook.

```yaml
  environment:
    RAW_BODY: true
```

The raw body has a default maximum of 100KB to prevent abuse from users. This can be configured manually to deal with larger payloads:

```yaml
  environment:
    RAW_BODY: true
    MAX_RAW_BODY: 512kb
```

##### Node.js 12 `node12` - Set max json request body size

Change the maximum size of a JSON request body by setting the environment variable `MAX_JSON_SIZE`. The default value is `'100kb'`
> Note: the value must be enclosed in quotes `'` `'`

This is useful when the function is expected to receive large amounts of JSON data in a single request. For instance, when working with large data sets and complex object types.

```yaml
  environment:
    MAX_JSON_SIZE: '5mb'
```

#### Node.js (classic template)

Generate a function named `js-fn`:

```bash
$ faas-cli new js-fn --lang node
```

You'll see:

```bash
./js-fn.yml
./js-fn/
./js-fn/handler.js
./js-fn/package.json
```

##### Node.js dependencies

Node.js dependencies are managed with `npm` and the `package.json` file which was generated for you.

To add the `cheerio` module type in:

```
cd js-fn
npm i --save cheerio
```

You can now add a `require('cheerio')` statement into your function and make use of this library.


#### Java

Two Java templates are provided `java11` and `java11-vertx`, both of which use Gradle as the build system. Please note that the `java8` template is deprecated, and should not be used.

> If you need a different version, then please fork the templates repository, or contact sales@openfaas.com to access additional templates via your OpenFaaS Premium Subscription.

Support is made available for external code repositories via the build.gradle file where you specify dependencies to fetch from repositories or JAR files to be added via the build.

* Write a function `java-function`:

```
$ faas-cli new --lang java11 java-function
```

* Write your code in:

./src/main/Handler.java

* Write `junit` tests in:

./src/tests/

* Update gradle config if needed in:

./build.gradle
./settings.gradle

* Working with headers (advanced)

You can view the code for the IRequest and IResponse in [the OpenFaaS templates-sdk](https://github.com/openfaas/templates-sdk/tree/master/java11/model/src/main/java/com/openfaas/model)

You can use `getHeader(k)` on the Request interface to query a header.

To set a header such as content-type you can use `setHeader(k, v)` on the Response interface.

You can also run the following to create a function using Vert.x

```bash
$ faas-cli new --lang java11-vertx java-vertx-function
```

#### CSharp / .NET Core 2.1

You can create functions in .NET Core 2.1 using C# / CSharp.

* Write a function named csharp-function

```
faas-cli new --lang csharp csharp-function
```

Now you can open your current folder in a tool such as Visual Studio Code and add dependencies using the project (csproj) file.

#### Ruby

Create a function called `ruby-function`:

```
$ faas-cli new --lang ruby ruby-function
```

The directory structure is:

```
├── ruby-function
│   ├── Gemfile
│   └── handler.rb
├── ruby-function.yml
```

Your code should be in the handler.rb file

##### Ruby: Adding a Gem (Library)

Open the `Gemfile` in the ruby-function directory

Add the following line

```Gemfile
gem 'httparty'
```

##### Ruby: Using our own Gem

Replace your `handler.rb` code with the following

```ruby
require 'httparty'

class Handler
    def run(req)
        return HTTParty.get("http://api.stackexchange.com/2.2/questions?site=stackoverflow&tagged=#{req}")
    end
end
```

##### Ruby: Building / Deploy / Run

Edit the `ruby-function.yml` and point your image to your dockerhub, for example
`${your_user}/ruby-function`

```
$ faas-cli up -f ruby-function.yml
...
Using bundler 1.16.4
Fetching multi_xml 0.6.0
Installing multi_xml 0.6.0
Fetching httparty 0.16.2
Installing httparty 0.16.2
Bundle complete! 1 Gemfile dependency, 3 gems now installed.
Bundled gems are installed into `/usr/local/bundle`
Post-install message from httparty:
When you HTTParty, you must party hard!
...
```

Now you can invoke the function:

```sh
$ echo 'OpenFaaS' | faas-cli invoke ruby-function
{
   "quota_remaining" : 298,
   "quota_max" : 300,
   "has_more" : false,
   "items" : [
      {
         "title" : "Scaling with GPU usage",
         "creation_date" : 1536315498,
         "answer_count" : 0,
         "view_count" : 10,
         "is_answered" : false,
...
```

#### Ruby HTTP

As an alternative to the `ruby` template, which uses the classic watchdog, we have an alternative where you can set HTTP response headers.

```
faas-cli template store pull ruby-http

faas-cli new --lang ruby-http k8s-get-pods
```

To add support for native dependencies such as kubeclient, you need to add the `dev` package to the `build_options`:

```yaml
version: 1.0
provider:
  name: openfaas
  gateway: http://127.0.0.1:8080
functions:
  k8s-get-pods:
    lang: ruby-http
    handler: ./k8s-get-pods
    image: k8s-get-pods:latest
    build_options:
    - dev
```

Then update your Gemfile:

```
source 'https://rubygems.org'

gem "kubeclient"
```

```
faas-cli build -f k8s-get-pods.yml
```

#### PHP7

To create a PHP7 function named `my-function` type in:

    $ faas-cli new my-function --lang php7

You'll see:

    my-function.yml
    my-function/src/Handler.php
    my-function/composer.json
    my-function/php-extension.sh

Add any dependencies/extensions as described below and implement your functions business logic in `Handler.php`.

#### PHP7 - Composer Dependencies

You should edit `composer.json` and add any required package dependencies, referring to the [Composer Documentation](https://getcomposer.org/doc/) for instructions on using `composer.json`.

##### PHP7 - Private Composer Repositories

Refer to the [PHP7 Template Documentation](https://github.com/openfaas/templates/tree/master/template/php7) for instructions on how to use [Composers](https://getcomposer.org/doc/) `COMPOSER_AUTH` environment variable to configure access to dependencies in private repositories.

##### PHP7 - PHP Extensions

The PHP7 template is based upon the [Docker Library PHP image](https://hub.docker.com/_/php/) and provides the `php-extension.sh` script which exposes the ability to customise extensions installed in a function image.

Refer to the [PHP7 Template Documentation](https://github.com/openfaas/templates/tree/master/template/php7) for instructions on customising installed extensions.

#### Customise a template

It is recommended that you use the official templates as they are provided and if there is a short-coming that you raise a GitHub issue so we can improve the templates for everyone.

All templates are driven by a Dockerfile and can be customised by editing the files found in the ./template folder.

##### Update the Dockerfile

There are several reasons why you may want to update your Dockerfile, just edit `./template/<language_name>/Dockerfile`.

* New base image - some companies prefer to use their own base images for Docker images for compliance, support or licensing reasons

* Add native package - sometimes you may want to add a native package from the Alpine Linux repository or the Debian package repository - just add a step into the Dockerfile

* Try a new version of a base-image - it may be that the project is showing support for Node.js LTS, but you want the cutting-edge version, you can do that too

##### Update a template's configuration

The name of a template is read from a "template.yml" file kept within the template folder: `./template/<language_name>/template.yml`

For `csharp` we have the following:

```
language: csharp
fprocess: dotnet ./root.dll
```

* `language` is the display name used for `faas-cli new --list`.
* `fprocess` provides the process to run for each invocation - i.e. your function

##### Use your own templates

You can use your own Git repository for a custom or forked set of templates. This can be public or private.

See `faas-cli template pull` for more information.

If you want to set up your own default template location, specify the `OPENFAAS_TEMPLATE_URL` environmental variable the following way:

```bash
export OPENFAAS_TEMPLATE_URL=https://raw.githubusercontent.com/user/mytemplate/customtemplates
```

##### Download templates from the template store

> Note: In order to access the template store you need `0.8.1` version of the CLI or higher

Check what templates are available in the template store with the CLI by typing:

```bash
faas-cli template store list
```

Pull the desired template by specifying `NAME` attribute only:

```bash
faas-cli template store pull go
```

or pull the template by mixing the `REPOSITORY` and `NAME` attributes the following way:

```bash
faas-cli template store pull openfaas/go
```

To get more information on specific store use the `describe` verb like:

```bash
faas-cli template store describe openfaas/go
```

or if there is no collision between names use only the name field:

```bash
faas-cli template store describe go
```

If you have your own store with templates, you can set that as your default official store by setting the environmental variable `OPENFAAS_TEMPLATE_STORE_URL` the following way:

```bash
export OPENFAAS_TEMPLATE_STORE_URL=https://raw.githubusercontent.com/user/openfaas-templates/templates.json
```

Now the source of the store is changed to the URL you have specified above.

## ARM / Raspberry Pi

It is possible to migrate to use multi-arch templates with OpenFaaS, feel free to ask the community for direction here.

Otherwise, for ARM and Raspberry Pi you will need to build on the device, and not on your PC or CI server.

---

## File: docs/architecture/autoscaling.md

# Auto-scaling

Auto-scaling in OpenFaaS allows a function to scale up or down depending on demand represented by different metrics.

## Scaling by requests per second

OpenFaaS ships with a single auto-scaling rule defined in the mounted configuration file for AlertManager. AlertManager reads usage (requests per second) metrics from Prometheus in order to know when to fire an alert to the API Gateway.

The API Gateway handles AlertManager alerts through its `/system/alert` route.

The auto-scaling provided by this method can be disabled by either deleting the AlertManager deployment or by scaling the deployment to zero replicas.

The AlertManager rules ([alert.rules](https://github.com/openfaas/faas/blob/master/prometheus/alert.rules.yml)) for Swarm can be viewed here and altered as a configuration map.

All calls made through the gateway whether to a synchronous function `/function/` route or via the asynchronous `/async-function` route count towards this method of auto-scaling.

### Min/max replicas

The minimum (initial) and maximum replica count can be set at deployment time by adding a label to the function.

* `com.openfaas.scale.min` - by default this is set to `1`, which is also the lowest value and unrelated to scale-to-zero

* `com.openfaas.scale.max` - the current default value is `20` for 20 replicas

* `com.openfaas.scale.factor` by default this is set to `20%` and has to be a value between 0-100 (including borders)

* `com.openfaas.scale.zero` - set to `true` for scaling to zero, faas-idler must also be deployed which is part of OpenFaaS PRO

> Note: 
Setting `com.openfaas.scale.min` and `com.openfaas.scale.max` to the same value, allows to disable the auto-scaling functionality of openfaas. 
Setting `com.openfaas.scale.factor=0` also allows to disable the auto-scaling functionality of openfaas.

For each alert fired the auto-scaler will add a number of replicas, which is a defined percentage of the max replicas. This percentage can be set using `com.openfaas.scale.factor`. For example setting `com.openfaas.scale.factor=100` will instantly scale to max replicas. This label enables to define the overall scaling behavior of the function.

> Note: Active alerts can be viewed in the "Alerts" tab of Prometheus which is deployed with OpenFaaS.

## Scaling by CPU and/or memory utilization

When using Kubernetes the built-in [Horizontal Pod Autoscaler (HPA)](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) can be used instead of AlertManager.

* Try the 2019 tutorial: [Kubernetes HPAv2 with OpenFaaS](/tutorials/kubernetes-hpa/).

* Stefan Prodan also wrote a blog post about [HPA with OpenFaaS in 2018](https://stefanprodan.com/2018/kubernetes-scaleway-baremetal-arm-terraform-installer/#horizontal-pod-autoscaling)

> Note: In addition to the above, both of the OpenFaaS watchdogs automatically provide custom metrics that can be used for HPAv2 scaling rules.

## Zero-scale

Scaling from zero is turned on by default, for any function or endpoint, this setting can be toggled on or off. Scaling to zero to recover idle resources is available in OpenFaaS, but is not turned on by default. There are two parts that make up scaling to zero or (zero-scale) in the project.

For a technical overview see the blog post: [Scale to Zero and Back Again with OpenFaaS](https://www.openfaas.com/blog/zero-scale/).

### Scaling up from zero replicas

Scaling up from zero replicas or 0/0 can be toggled through the `scale_from_zero` environment variable for the OpenFaaS Gateway. This is turned on by default on Kubernetes and faasd.

The latency between accepting a request for an unavailable function and serving the request is sometimes called a "Cold Start".

* What if I don't want a "cold start"?

The cold start in OpenFaaS is strictly optional and it is recommended that for time-sensitive operations you avoid one. This can be achieved by not scaling critical functions down to zero replicas, or by invoking them through the asynchronous route which decouples the request time from the caller.

* What exactly happens in a "cold start"?

The "Cold Start" consists of the following: creating a request to schedule a container on a node, finding a suitable node, pulling the Docker image and running the initial checks once the container is up and running. This "running" or "ready" state also has to be synchronised between all nodes in the cluster. The total value can be reduced by pre-pulling images on each node and by setting the Kubernetes Liveness and Readiness Probes to run at a faster cadence.

Instructions for optimizing for a low cold-start are provided in [the helm chart for Kubernetes](https://github.com/openfaas/faas-netes/tree/master/chart/openfaas).

When `scale_from_zero` is enabled a cache is maintained in memory indicating the readiness of each function. If when a request is received a function is not ready, then the HTTP connection is blocked, the function is scaled to min replicas, and as soon as a replica is available the request is proxied through as per normal. You will see this process taking place in the logs of the *gateway* component.

### Scaling down to zero

Scaling down to zero replicas is also called "idling".

There are two approaches available for idling functions:

#### 1) faas-idler

You can use the faas-idler which is available with [OpenFaaS PRO](https://openfaas.com/support). `faas-idler` allows some basic presets to be configured and then monitors the built-in Prometheus metrics on a regular basis to determine if a function should be scaled to zero. Only functions with a label of `com.openfaas.scale.zero=true` are scaled to zero, all others are ignored. Functions are scaled to zero through the OpenFaaS REST API.

If you wish to only observe which functions would have been scaled down - pass the "-read-only" flag, or set this via the helm chart.

#### 2) OpenFaaS REST API

If you want to use your own set of criteria for idling functions then you can make use of the OpenFaaS REST API to decide when to scale functions to zero. You can build and deploy your own custom controller for this task.