Self-hosted service
epinio/epinio avatar
epinio/epinio

Epinio: pushing code to Kubernetes without learning Kubernetes

Opinionated platform that runs on Kubernetes, that takes you from App to URL in one step.

615 stars65 forksGoApache-2.0

At a glance

What is it?
Epinio is an opinionated PaaS layer on top of Kubernetes that turns a source tree into a URL, with buildpacks handling the container build and a CLI or web UI doing the rest. It removes the YAML for the common case, at the cost of requiring a cluster with an ingress controller and cert manager before you can install anything.
Who is it for?
Adopt Epinio when your organisation already runs Kubernetes and wants application developers to deploy without writing manifests, and when you can accept an opinionated model built around buildpacks, per application namespaces and an API server that must be reachable. Do not adopt it for a team without a cluster, for workloads outside the buildpack contract, or as a Kubernetes learning tool, since the goal is to hide that layer rather than teach it.
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 received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Epinio names out loud

Epinio describes itself as an opinionated platform that runs on Kubernetes to take you from Code to URL in one step. The README spends most of its opening on the problem rather than the feature list, and that framing is the point.

The argument goes like this. Kubernetes is the standard for container orchestration, and developers may want to use it for its benefits or because their Ops team has chosen it. Either way, working with Kubernetes can be complex depending on the environment. It has a steep learning curve, and doing it right is a full-time job. Developers should spend their time working on their applications, not doing operations.

Epinio's answer is to add the abstractions and tools needed to use Kubernetes as a PaaS. The listed benefits are concrete: no experience with Kubernetes is needed, no steep learning curve, a quick local setup with minimal configuration, and deploying to production the same as deploying in development.

That last one is the strongest claim and also the hardest. The whole design rests on a single abstraction: an application. You point Epinio at source code, it builds a container using Cloud Native Buildpacks, and it runs that container as a deployment with a service and an ingress route in front of it. Nothing about that requires you to understand pods, probes or resource requests, because Epinio writes those parts for you.

The audience is therefore an application developer inside an organisation that has already decided on Kubernetes, and an Ops team that wants to give those developers a safe, opinionated subset of the cluster rather than cluster-admin credentials.

Push code, and the buildpacks do the container

The application flow is the core of the tool. The README lists it under Apps: push code directly without further tools or steps, basic operation of your application once pushed, and Cloud Native Buildpacks building and containerizing the code for you.

That last point is the substantive technical decision. Epinio does not require a Dockerfile. It hands your source to a buildpack, which detects the language and framework, fetches dependencies, and produces an OCI image. The consequence is that the same codebase behaves consistently on a developer laptop and in the cluster, because the build is reproducible rather than dependent on a hand-written image definition that may drift.

The reference examples show the range the buildpack approach is expected to cover. The README links a Rails example application, the Spring PetClinic Java application, and the Paketo Buildpack example apps, which is a useful signal about the framework coverage the project expects people to hit first.

The other half of the feature list is configuration. Epinio supports CRUD operations on configurations, where a configuration can be a database or a SaaS, and it can be an external component or something created with the `epinio configuration` command. Configurations can then be bound to applications.

This is where Epinio departs from a pure application runtime. It has an opinion about the services an application needs, and it manages their lifecycle inside the cluster, which is convenient for a developer and significant extra machinery for an operator.

Installing the platform and the CLI

The order of operations matters. The README says installation requires a Kubernetes cluster, an Ingress Controller and a Cert Manager, as explained in the installation documentation. Once those exist, and leaving out DNS setup, the installation reduces to three Helm commands:

bash
helm repo add epinio https://epinio.github.io/helm-charts
helm repo update

helm install --namespace epinio --create-namespace epinio epinio/epinio \
  --set global.domain=mydomain.example.com

The `global.domain` value is how the platform learns which hostnames to hand out, so it has to be a domain you control and can point at the cluster. The Ingress Controller is what turns those hostnames into routes, and the Cert Manager is what issues the TLS certificates for them. Without all three, the platform has nothing to route to and nothing to serve HTTPS with.

The CLI is a separate installation. It is available by downloading a binary from the release page, or through brew:

bash
brew install epinio

After that, the README points at a QuickStart tutorial that works through creating a namespace and pushing an application. That is the shortest path to a working deployment, and the existence of a dedicated tutorial rather than a longer manual suggests the flow is meant to be driven from the CLI.

The project is developed with a Makefile whose default goal is build, and the version string is injected at link time from `git describe --tags` through a LDFLAGS entry into `github.com/epinio/epinio/internal/version.Version`. The optional VSUFFIX variable exists so developers can tell apart binaries built from the same commit.

Security is a Basic Auth or an OIDC token

Epinio exposes an API, and the README is clear that securing it is a first class concern rather than an afterthought.

The Security feature block lists a TLS secured API server, Basic Authentication to access the API, or an OIDC-based token. The word or matters: the second option is an alternative to the first, so a cluster that already has an identity provider can federate to it, while a smaller installation can fall back on credentials in the API server.

The repository contents reinforce that this is a real identity story rather than a token bolted on. There is a dex-config.yaml at the top level, and the Go dependency list includes go-oidc for OpenID Connect, golang-jwt for JSON web tokens, gorilla/websocket for the web UI channel, and coreos/go-oidc. The presence of a dex-config.yaml alongside the OIDC dependency suggests a Dex-based path for clusters that already run an identity provider.

Two clients are offered: a Web UI and the Epinio CLI. The websocket dependency suggests the UI is a live view over the API rather than a set of static forms, and the CLI is the primary path for the quickstart flow.

For an operator, the security question to answer first is who can push. Because a push produces a running workload inside your cluster, Epinio's access control is effectively deployment access, and Basic Authentication credentials for that role need the same care as any other cluster credential.

The 1.13 staging configuration break

Epinio's README carries a Breaking Changes and Migrations section, and the entry for 1.12 to 1.13 is the most instructive part of the document, because it shows how the project handles configuration that has outgrown its container.

The change: Epinio 1.13 rehomes configurations for the staging workloads to a more standardized format that supports a larger variety of configs. These are no longer configured directly on the Epinio container via ENV variables or through Viper CLI flags, but are read from an in-cluster ConfigMap at staging time.

The variables that stopped working were these:

bash
STAGING_SERVICE_ACCOUNT_NAME
STAGING_RESOURCE_CPU
STAGING_RESOURCE_MEMORY
STAGING_RESOURCE_DISK

The reasoning is worth reading, because it is a common pattern in Kubernetes tooling. The old ENV approach was set by the Helm Chart in the deployment's `env` section, and as capabilities grew it would have become unruly. The new form supports resource requests versus limits, node tolerations and affinity criteria, and it reads the values from chart values into the stage script ConfigMaps, structured the way Kubernetes itself would structure them in the Job YAML.

The resulting ConfigMap content looks like this:

yaml
serviceAccountName: "epinio-server"
ttlSecondsAfterFinished: 300
resources:
  requests:
    cpu: "200m"
    memory: "1Gi"
  # limits:
  #   cpu: ""
  #   memory: ""
storage:
  cache:
    emptyDir: false
    size: 1Gi
    storageClassName: ""
    volumeMode: Filesystem
    accessModes:
    - ReadWriteOnce

The lesson for anyone upgrading is that a release can change where configuration lives even when the user visible commands stay the same, and the `helm-charts` directory in the repository is where the chart side of that change lives.

Where Epinio is the wrong shape

Epinio's first limitation is its prerequisite list. You need a Kubernetes cluster, an Ingress Controller and a Cert Manager before the installation even starts. For a team that does not have a cluster, that is not a small hurdle, it is the whole project, and at that point a simpler managed platform or a plain container registry is the smaller commitment.

The second limitation is the opinionated model itself. Buildpacks mean your application has to fit the buildpack contract, which is comfortable for the frameworks the Paketo examples cover and awkward for anything with unusual system dependencies or a bespoke image pipeline. Epinio's own value proposition is that it hides Kubernetes; the cost is that it also hides the escape hatches. A team that needs custom ingress annotations, sidecars, or a very specific pod spec is fighting the abstraction.

The third is the project boundary. Epinio manages applications and configurations inside a namespace, and it treats a configuration as something that can be a database or a SaaS and be bound to an app. It is not a general deployment platform for arbitrary workloads, and the README does not describe job scheduling, batch processing or one-off task execution. If your workload is not a long-running service, the fit is poor.

The fourth is the operational surface Epinio adds. Every Epinio deployment brings a server, an API, an ingress route and TLS handling into the cluster, plus a client that developers must install and configure. The comparison that matters is not against raw Kubernetes, which nobody recommends for application teams, but against a lighter layer such as a static build and ingress configuration. If your applications are simple services with no configuration bindings, Epinio may be more machinery than the problem needs.

One documentation gap is worth naming. The README does not describe backup or restore for the Epinio server itself, nor how to migrate an application between Epinio instances, so treat the platform as recoverable infrastructure only if you have tested that path yourself.

Licence, governance and the release rhythm

Epinio is licensed under the Apache License, Version 2.0, and the README reproduces the licence text with the standard warranty disclaimer. Apache-2.0 permits commercial use, modification and distribution, including patent rights, provided the licence and notice files travel with the distribution.

The copyright line tells you something about the stewardship. It reads Copyright (c) 2020-2024 SUSE, LLC and Copyright (c) 2025-2026 Krumware LLC, so the project moved from SUSE to Krumware partway through its life, and the repository carries a LICENSE_HEADER file plus a CODEOWNERS file, which are the conventions of a corporate-owned Apache project.

The release cadence is fast and visible. Version 1.14.3 shipped on 2026-10-16, preceded by the 1.14.3-rc1 on 2026-10-15 and 1.14.2 on 2026-09-03. The repository is not archived and the last push was on 2026-10-22. The presence of a release candidate immediately before the release, and of acceptance tests in an acceptance/ directory, suggests a project with a real release process rather than an occasional tag.

For contributors, the project uses GitHub Project for issue tracking, publishes a Contribution Guide in the documentation, and keeps developer documentation in the docs folder explaining how to build and run Epinio from a git checkout. The tree also includes a golangci-lint configuration, a codecov configuration and a goreleaser setup, which is the standard toolchain for a Go project that ships binaries for several platforms.

Support is offered through the epinio channel on the Rancher Users Slack workspace and through GitHub Discussions, both listed in the README.

Editorial conclusion

Adopt Epinio when your organisation already runs Kubernetes and wants application developers to deploy without writing manifests, and when you can accept an opinionated model built around buildpacks, per application namespaces and an API server that must be reachable. Do not adopt it for a team without a cluster, for workloads outside the buildpack contract, or as a Kubernetes learning tool, since the goal is to hide that layer rather than teach it. Before installing, confirm you have a cluster with an Ingress Controller and a Cert Manager, decide whether access is via Basic Authentication or an OIDC token, and read the 1.12 to 1.13 migration notes if you run an older release, because the staging workload configuration moved from container environment variables to an in-cluster ConfigMap.

Frequently asked questions

What does Epinio do?

Epinio is an opinionated platform that runs on Kubernetes and takes an application from code to URL in one step, using Cloud Native Buildpacks to build and containerize the source and hiding the Kubernetes manifests from the developer.

What do I need before installing Epinio?

A Kubernetes cluster, an Ingress Controller and a Cert Manager, as the installation documentation explains. DNS setup is also required but is described as separate from the installation itself.

How do I install Epinio and its CLI?

The platform installs with Helm: add the epinio chart repository, update it, then helm install with `--set global.domain=mydomain.example.com`. The CLI is a separate download from the release page or `brew install epinio`.

How does Epinio authenticate API access?

The README lists a TLS secured API server with Basic Authentication to access the API, or an OIDC-based token. The repository includes a dex-config.yaml, and the Go dependencies include go-oidc and golang-jwt.

What changed in Epinio 1.13 compared to 1.12?

Staging workload configuration moved out of the Epinio container's environment variables and Viper CLI flags and into an in-cluster ConfigMap read at staging time, which allows resource requests versus limits, node tolerations and affinity criteria. The old variables were STAGING_SERVICE_ACCOUNT_NAME, STAGING_RESOURCE_CPU, STAGING_RESOURCE_MEMORY and STAGING_RESOURCE_DISK.

Does Epinio require a Dockerfile for my application?

No. The README states that Cloud Native Buildpacks build and containerize your code for you, and it lists Rails, Java and Paketo Buildpack example applications as references.

Official sources

  1. epinio/epinio on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/epinio-epinio.svg)](https://hysenlabs.com/projects/epinio-epinio)

Was this useful?