Fn Project: a self-hosted FaaS platform that treats any Docker container as a function
The container native, cloud agnostic serverless platform.
At a glance
- What is it?
- Fn Project runs functions as ordinary containers on infrastructure you control, with a CLI that handles init, deploy and invoke. Its release history and its dependence on a running container runtime are the two things to weigh before adopting it.
- Who is it for?
- Fn Project fits teams that already run Docker or Podman and want function deployment on their own machines or clusters, without handing execution to a hosted provider. It does not fit anyone who needs a current release cadence: the newest release listed in the repository is 0.3.25 from 2017-07-26, and the last push to master was on 2026-06-08.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Fn Project solves, and who ends up using it
Fn is a Functions-as-a-Service platform you host yourself. The README describes it as "an event-driven, open source, Functions-as-a-Service (FaaS) compute platform that you can run anywhere," and the practical consequence is that the unit of deployment is a container image rather than a language-specific bundle. If your team already builds images, Fn does not ask you to learn a new packaging format or a provider-specific handler signature.
The audience is narrower than the tagline suggests. Fn targets developers who want the invoke-and-scale experience of a hosted FaaS without the hosted part, and operators who are willing to run a server process, a database and a message queue. The README lists public, private and hybrid cloud as deployment targets, plus an import path for Lambda functions. That import story matters for teams with existing Lambda code who want to move execution in-house; it is the clearest example of the cloud-agnostic claim being concrete rather than marketing.
Containers as the execution unit: what the architecture implies
The design decision that shapes everything else is stated plainly: "Native Docker: use any Docker container as your Function." There is no bespoke sandbox and no language shim. A function is an image, and invoking it means the server starts a container from that image and routes a request into it.
The repository layout confirms the shape. The server binary is built from cmd/fnserver, the HTTP surface is described by docs/swagger_v2.yml, and there is a gRPC runner definition under api/agent/grpc. go.mod pulls in github.com/fsouza/go-dockerclient, so the server talks to the container runtime through the Docker API. That is why the prerequisites are a running Docker or Podman daemon rather than a language runtime: Fn cannot start a function without one.
Persistence is pluggable. The Makefile's test-system target runs the system tests three times, against sqlite3, mysql and postgres, and go.mod includes drivers for all three (github.com/ncruces/go-sqlite3, github.com/go-sql-driver/mysql, github.com/lib/pq). The README says fn start brings up "single server mode, using an embedded database and message queue," which is the sqlite path; the other two are for deployments that outgrow a single node. Observability is wired in through OpenCensus with exporters for Jaeger, Zipkin and Prometheus, and the examples directory has a grafana folder.
Installing the Fn CLI and running your first function
The CLI is optional in principle and close to mandatory in practice. On macOS with Homebrew, the README gives a single command:
brew update && brew install fnOn Linux and macOS there is also a shell installer. The README warns that if the script asks for a password, that is because it invokes sudo:
curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | shWindows users are pointed at a separate client guide, and prebuilt binaries are on the CLI releases page. With the CLI in place, start the server:
fn startOn Podman or Rancher Desktop the README recommends a volume instead, because FnServer creates a unix socket file to talk to other Fn containers. The volume is created for you when you pass --iofs-dir to fn start:
fn start --iofs-dir fniofsvolYou should see the server come up in single server mode. From there, scaffold a function, create the app that will hold it, deploy locally and invoke:
fn init --runtime go hello
cd hello
fn create app myapp
fn deploy --app myapp --local
fn invoke myapp helloThe README notes that --local skips the push to a remote container registry, which makes local iteration faster. If the invoke returns output, the loop is working; edit func.go and deploy again to see the change.
Where Fn Project gets in the way
The container-native model is also the main constraint. Every function invocation depends on a working container runtime, so a stopped Docker daemon, a Podman socket that FnServer cannot reach, or a SELinux policy that blocks the socket turns into a total outage rather than a degraded one. The README addresses SELinux directly, stating that most Linux systems have it enabled and that FnServer supports running on SELinux, but it does not document what to do when the socket volume is misconfigured beyond the --iofs-dir flag itself.
The release history is the harder problem. The repository lists 0.3.23, 0.3.24 and 0.3.25, all dated 2017-07-26, as the recent releases. The last push to master was on 2026-06-08, which is recent enough that the code has not been abandoned, but a nine-year gap between the listed releases and that push is a real signal about how the project is versioned and shipped. Anyone whose procurement or upgrade policy keys off tagged releases should treat that as a blocker rather than a detail.
Fn is also the wrong tool for a single long-running service. If your workload is an HTTP API with steady traffic, a container orchestrator and a normal deployment pipeline will be simpler than a FaaS control plane, an app abstraction, and a database to hold the metadata. Fn earns its place when you have many small, independently deployed units and want the platform to handle routing and lifecycle.
How Fn differs from Knative and from hosted Lambda
The closest self-hosted alternative in this space is Knative, which builds on Kubernetes primitives and expects a cluster. The difference is where the abstraction sits. Knative leans on Kubernetes objects, revisions and a service mesh to get scale-to-zero and traffic splitting, so adopting it means adopting Kubernetes operational knowledge. Fn ships its own server binary, its own app and function model, and its own database, with the README noting a single server mode that runs with an embedded database and queue. You can run Fn on one machine without a cluster at all.
Against hosted Lambda, the trade is control versus release cadence and managed operations. Fn's pitch is that you can "import Lambda functions and run them anywhere," which keeps the migration path open, but you take on the database, the queue, upgrades and capacity. The examples directory includes a lambda folder, so the import path is at least represented in the repository rather than only in prose. What Fn does not give you is a vendor's SLA or a rolling runtime update schedule.
Licence, upgrade cost and what maintenance looks like
Fn is licensed under Apache-2.0, which permits commercial use, modification and redistribution provided the licence and notices are preserved. This is a permissive licence, not a copyleft one, so it does not obligate you to publish changes to the server. That is a general statement about Apache-2.0, not legal advice; if you redistribute a modified fnserver, have counsel review the NOTICE requirements.
Upgrade cost is dominated by the absence of a steady release stream. With the newest listed release at 0.3.25 and dated 2017-07-26, there is no published upgrade path to follow. Practically, that means tracking master and building from source: the Makefile's build target runs go build -o fnserver ./cmd/fnserver, and install places the binary in ${GOPATH}/bin. The Dockerfile builds the server with CGO_ENABLED=0 and packages it on a dind base image, exposing port 8080. Anyone running Fn in production should expect to own that build pipeline rather than consume a vendor artifact.
What to check before you commit to Fn Project
Start with the runtime. The README requires Docker 17.10.0-ce or later, or Podman 5.7.0 or later, installed and running. If you are on Podman or Rancher Desktop, plan for the --iofs-dir volume from the beginning, because the unix socket that FnServer uses to reach other Fn containers lives there.
Second, decide on the database. The embedded store is fine for a laptop and probably not for a team. The system tests exercise sqlite3, mysql and postgres, so all three are supported configurations, but the README does not document rollback or migration procedures between them. That gap is worth resolving before you put real state in.
Third, confirm the surface you need. The HTTP API is described by docs/swagger_v2.yml, and there is a separate UI and load balancer in the Fn sub-projects. If your requirements include scale-to-zero, traffic splitting or a managed control plane, Fn as documented here does not provide them, and Knative or a hosted provider will be the shorter route.
Editorial conclusion
Fn Project fits teams that already run Docker or Podman and want function deployment on their own machines or clusters, without handing execution to a hosted provider. It does not fit anyone who needs a current release cadence: the newest release listed in the repository is 0.3.25 from 2017-07-26, and the last push to master was on 2026-06-08. Before committing, verify that fn start works against your container runtime (Podman and Rancher Desktop need --iofs-dir with a volume) and check the operating options page linked from the README for the database and queue settings you would run in production.
Frequently asked questions
What is Fn Project and what does it run?
It is an event-driven, open source Functions-as-a-Service platform that you host yourself. Functions are Docker containers, so any language that can be packaged as an image can be used.
How do I install the Fn CLI?
On macOS with Homebrew, run brew update && brew install fn. On Linux and macOS you can also run the shell installer with curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh, and Windows has a separate client guide.
Why does fn start need --iofs-dir on Podman or Rancher Desktop?
FnServer creates a unix socket file to communicate with other Fn containers, and the README recommends hosting that socket on a volume in those environments. The volume is created automatically when you pass --iofs-dir to fn start.
Which databases can Fn Project use?
The README says fn start uses an embedded database and message queue in single server mode. The Makefile runs system tests against sqlite3, mysql and postgres, and go.mod includes drivers for all three.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/fnproject-fn)