An open API service indexing awesome lists of open source software.

https://github.com/pardnchiu/go-faas

Run Py/JS/TS functions as serverless endpoints
https://github.com/pardnchiu/go-faas

backend faas golang pardnchiu

Last synced: 5 months ago
JSON representation

Run Py/JS/TS functions as serverless endpoints

Awesome Lists containing this project

README

          

> [!NOTE]
> This README was generated by [Claude Code](https://github.com/pardnchiu/skill-readme-generate), get the ZH version from [here](./README.zh.md).

![cover](./cover.png)

# go-faas

[![pkg](https://pkg.go.dev/badge/github.com/pardnchiu/go-faas.svg)](https://pkg.go.dev/github.com/pardnchiu/go-faas)
[![card](https://goreportcard.com/badge/github.com/pardnchiu/go-faas)](https://goreportcard.com/report/github.com/pardnchiu/go-faas)
[![version](https://img.shields.io/github/v/tag/pardnchiu/go-faas?label=release)](https://github.com/pardnchiu/go-faas/releases)
[![license](https://img.shields.io/github/license/pardnchiu/go-faas)](LICENSE)

> Lightweight Golang FaaS platform providing isolated execution environments for JavaScript, TypeScript, and Python scripts. Uses bubblewrap sandbox with systemd-run resource limits for secure script execution without containers.

## Table of Contents

- [Features](#features)
- [Architecture](#architecture)
- [Installation](#installation)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Script Examples](#script-examples)
- [License](#license)
- [Author](#author)
- [Stars](#stars)

## Features

- **Multi-language Support**: Execute JavaScript, TypeScript, and Python scripts with unified JSON parameter passing and result return
- **Sandbox Isolation**: Uses bubblewrap (bwrap) with Linux namespaces to isolate execution environments and protect the host system
- **Resource Limits**: Control CPU and memory usage via systemd-run to prevent malicious scripts from exhausting system resources
- **Version Management**: Scripts are automatically versioned and stored in Redis; execute specific versions or use the latest
- **Streaming Output**: Support SSE streaming mode for real-time script execution progress and log output

## Architecture

```mermaid
flowchart TD
subgraph HTTP["HTTP Layer"]
A[HTTP Request] --> B{Gin Router}
B -->|POST /upload| C[Upload Handler]
B -->|POST /run/*| D[Run Handler]
B -->|POST /run-now| E[RunNow Handler]
end

subgraph Storage["Storage Layer"]
C --> F[Validate Language/Path]
F --> G[(Redis)]
G -->|meta:hash| H[Path/Language/Latest Version]
G -->|code:hash:ts| I[Script Source Code]
end

subgraph Execution["Execution Layer"]
D --> J[Get Script from Redis]
J --> K[Create Sandbox Command]
E --> K

K --> L[systemd-run]
L -->|CPUQuota| M[CPU Limit]
L -->|MemoryMax| N[Memory Limit]

L --> O[bubblewrap]
O -->|--unshare-all| P[Namespace Isolation]
O -->|--unshare-net| Q[Network Isolation]
O -->|--ro-bind| R[Read-only Mount /usr /lib]
O -->|--cap-drop ALL| S[Drop All Capabilities]
end

subgraph Runtime["Runtime Layer"]
O --> T{Language Detection}
T -->|javascript| U[node wrapper.js]
T -->|typescript| V[tsx wrapper.ts]
T -->|python| W[python3 wrapper.py]

U --> X[stdin: JSON Payload]
V --> X
W --> X
X --> Y[Execute User Script]
Y --> Z[stdout: Result]
end

Z --> AA{Stream Mode?}
AA -->|Yes| AB[SSE Stream Response]
AA -->|No| AC[JSON Response]
```

## Installation

### Requirements

- Go 1.23.0+
- Redis 6.0+
- Linux (requires bubblewrap and systemd)
- Node.js 22+
- Python 3.10+

### System Dependencies

```bash
# Ubuntu / Debian
sudo apt update
sudo apt install -y bubblewrap redis-server nodejs npm python3

# Fedora / RHEL
sudo dnf install -y bubblewrap redis nodejs npm python3

# Arch Linux
sudo pacman -S bubblewrap redis nodejs npm python
```

### Setup

```bash
git clone https://github.com/pardnchiu/go-faas.git
cd go-faas

# Install Go dependencies
go mod download

# Install Node.js dependencies (esbuild for TypeScript compilation)
npm install

# Install tsx (TypeScript executor)
npm install -g tsx
```

### Start Service

```bash
# Ensure Redis is running

# Start FaaS service
go run cmd/api/main.go
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `HTTP_PORT` | `8080` | HTTP service port |
| `MAX_CPUS` | `1` | CPU quota per sandbox (100% = 1 core) |
| `MAX_MEMORY` | `128M` | Memory limit per sandbox |
| `CODE_MAX_SIZE` | `262144` | Maximum code size (bytes) |
| `TIMEOUT_SCRIPT` | `30` | Script execution timeout (seconds) |
| `REDIS_HOST` | `localhost` | Redis host |
| `REDIS_PORT` | `6379` | Redis port |
| `REDIS_PASSWORD` | empty | Redis password |
| `REDIS_DB` | `0` | Redis database number |

## Usage

### Execute Script Immediately

```bash
curl -X POST http://localhost:8080/run-now \
-H "Content-Type: application/json" \
-d '{
"language": "javascript",
"code": "return { sum: event.a + event.b };",
"input": "{\"a\": 10, \"b\": 5}"
}'
```

Response:

```json
{
"data": { "sum": 15 },
"type": "json"
}
```

### Upload and Execute Script

```bash
# Upload script
curl -X POST http://localhost:8080/upload \
-H "Content-Type: application/json" \
-d '{
"path": "math/add",
"language": "javascript",
"code": "return { result: event.a + event.b };"
}'

# Execute saved script
curl -X POST http://localhost:8080/run/math/add \
-H "Content-Type: application/json" \
-d '{ "input": { "a": 10, "b": 5 } }'
```

### Streaming Mode

```bash
curl -X POST http://localhost:8080/run-now \
-H "Content-Type: application/json" \
-d '{
"language": "python",
"code": "import json\nfor i in range(3):\n print(json.dumps({\"progress\": i}))\nreturn {\"done\": True}",
"input": "{}",
"stream": true
}'
```

## API Reference

### POST /upload

Upload and store a script in Redis.

**Request Body:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `path` | string | Yes | Script path identifier |
| `language` | string | Yes | `javascript`, `typescript`, or `python` |
| `code` | string | Yes | Script source code |

**Response:**

```json
{
"path": "math/add",
"language": "javascript",
"version": 1735286400
}
```

### POST /run/{path}

Execute an uploaded script.

**Query Parameters:**

| Parameter | Description |
|-----------|-------------|
| `version` | Specify version timestamp (optional, defaults to latest) |

**Request Body:**

| Field | Type | Description |
|-------|------|-------------|
| `input` | object/string | Input data passed to the script |
| `stream` | boolean | Enable SSE streaming mode |

### POST /run-now

Execute a script immediately without storing.

**Request Body:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `language` | string | Yes | `javascript`, `typescript`, or `python` |
| `code` | string | Yes | Script source code |
| `input` | string | No | JSON formatted input data |
| `stream` | boolean | No | Enable SSE streaming mode |

## Script Examples

All scripts receive input data via the `event` variable.

### JavaScript

```javascript
const result = {
sum: event.a + event.b,
product: event.a * event.b
};
return result;
```

### TypeScript

```typescript
interface Event {
a: number;
b: number;
}

const result = {
sum: event.a + event.b,
product: event.a * event.b
};
return result;
```

### Python

```python
result = {
'sum': event['a'] + event['b'],
'product': event['a'] * event['b']
}
return result
```

## License

This project is licensed under [MIT](LICENSE).

## Author

邱敬幃 Pardn Chiu





## Stars

[![Star](https://api.star-history.com/svg?repos=pardnchiu/go-faas&type=Date)](https://www.star-history.com/#pardnchiu/go-faas&Date)

***

©️ 2025 [邱敬幃 Pardn Chiu](https://linkedin.com/in/pardnchiu)