Self-hosted service
uselagoon/lagoon avatar
uselagoon/lagoon

Lagoon: one Kubernetes delivery platform for multi-container applications

Lagoon, the developer-focused application delivery platform

604 stars156 forksTypeScriptApache-2.0

At a glance

What is it?
Lagoon is an Apache-2.0 licensed application delivery platform built for the awkward cases, CMS and LMS style applications with many containers, where teams want the same images locally and in production. Its architecture is two components split across clusters, communicating only over RabbitMQ so that Core never needs admin access to the cluster running Remote.
Who is it for?
Adopt Lagoon when your workload is a multi-container application that has to look identical in local development and in production, and when you want the platform team to keep Kubernetes expertise out of the developer workflow. Do not adopt it for a single small service, since the platform has a large operational surface of its own, and do not plan on Lagoon Core reaching into your build clusters, because that separation is deliberate.
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 TypeScript, according to GitHub's language statistics.

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

Editorial analysis

The problem: many containers, and developers who should not need Kubernetes

Lagoon is described as a system that allows developers to locally develop their code and their services with Docker and run the exact same system in production. The same container images, the same service configurations and the same code. That triple is the product promise, and it is narrower and more concrete than most platform marketing.

The framing in the README is that Lagoon is an application delivery platform, whose primary focus is as a cloud-native tool for the deployment, management, security and operation of many applications, and that it greatly reduces the requirement on developers of those applications to have cloud-native experience or knowledge.

The target workload is stated just as plainly. Lagoon has been designed to handle workloads that have been traditionally more complex to make cloud-native, such as CMS, LMS and other multi-container applications, and to do so with minimal retraining or reworking needed for the developers of those applications.

That is a narrower goal than building a general platform, and it is the right one to read as a scope statement. A CMS is a web server, a PHP runtime, a database, a cache, a cron worker and a queue, and the same six containers have to exist on a laptop and in a cluster. The pain is not in writing Kubernetes manifests, it is in the fact that the developer's machine and the production cluster drift apart.

The project is fully open source, built on open source tools, and built collaboratively with users. The Apache-2.0 licence and the last push on 2026-10-20 say the project is alive, and the lagoon-core releases v2.34.0 on 2026-09-22, v2.33.3 on 2026-09-09 and v2.33.2 on 2026-08-25 show a steady cadence.

Two components, two clusters, one message broker

The architecture is the part of Lagoon worth understanding before anything else, and it is a two-part split with a specific security property.

Lagoon comprises two main components, Lagoon Core and Lagoon Remote. In a full production setting the recommendation is to install them into different Kubernetes clusters, although a single Core installation can serve multiple Remotes and they can also share a cluster.

The security consequence is the interesting part. Lagoon Core does not need administrator-level access to the Kubernetes clusters that are running Lagoon Remote. All inter-cluster communication happens only via RabbitMQ, which is hosted in Lagoon Core and consumed and published back to by Lagoon Remote. That is what allows Remotes to be managed by different teams in different locations, even behind firewalls or inaccessible from the internet.

This is a genuinely different trust model from the usual platform arrangement, where a central control plane holds credentials for every cluster it manages. Here the split means a compromise of Core does not directly grant control of the build clusters, and a Remote can sit inside a network that Core cannot reach.

The implementation languages are mixed by design. Lagoon services are mostly built in Node.js, more recent development occurs in Go, and most of the automation and scripting components are in Bash. The go.mod confirms the Go part is not incidental, with a module path of github.com/uselagoon/lagoon and a go directive of 1.26.1, and a dependency set that includes the machinery library, the remote controller, a RabbitMQ client in go-mq, a GitLab API client, k8s.io/apimachinery and gorilla/mux.

The build tooling at the root is a yarn workspace over node-packages and services directories, with the package.json listing both as workspaces and adding a glow check script. The Go code sits alongside in internal/, which is a monorepo holding two language ecosystems in one repository.

What lives in Core: the API, authentication and the messaging spine

Everything that handles the API, authentication and external communication is installed in Lagoon Core, and the README lists the services with a one-line description of each, which is a good map of the control plane.

The API group is three services. The api service is the GraphQL API that powers Lagoon, api-db is the MariaDB storage for the API, and api-redis is the cache layer for API queries.

Authentication is three more. Keycloak is the main authentication application, keycloak-db is the MariaDB storage for Keycloak, and auth-server generates authentication tokens for Lagoon services. There is also an ssh service, described as providing developers with ssh access to the sites hosted on Lagoon.

Messaging carries the broker, the RabbitMQ message service used to communicate with Lagoon Remote, plus webhooks2tasks, which converts incoming webhooks to API updates, and actions-handler, which manages bulk action processing for builds and tasks.

The webhooks group is where external systems land. The webhook-handler is the external service that Git repositories and registries communicate with, and backup-handler collects and collates information on backups.

Notifications is a single service, logs2notifications, which pushes build notifications to configured notification types.

Two things stand out for anyone evaluating this. First, the API is GraphQL rather than REST, which matters if you plan to script against it. Second, the broker is not optional infrastructure, it is the transport that makes the Core and Remote split possible, and every deployment has to run a RabbitMQ that both sides can reach.

What lives in Remote: the machinery that actually builds and deploys

The services used to provision, deploy and maintain sites hosted by Lagoon on Kubernetes live in Lagoon Remote, and the README is explicit that these services are mostly comprised of third-party tools developed externally to Lagoon itself.

The Docker Host is the service that stores and caches upstream Docker images for use in builds, which is the piece that makes reproducible builds possible when upstream tags move. The Remote Controller handles building and deploying sites onto Lagoon. The Build Deploy Tool computes which services, configuration and settings to provision for Kubernetes, which is the piece that turns a project definition into a set of running workloads.

Three of the entries are optional and each does a specific thing. The Storage Calculator collects the size of storage and databases, Aergia is an optional controller that can idle non-production sites not currently in use to conserve resources, and Dioscuri provides Active/Standby functionality.

The DBaaS Operator is also optional and provisions databases from an underlying managed database, so a project can ask for a database rather than running one itself.

The pattern here is the same one that drives the whole design. Lagoon itself supplies the platform, the API, the authentication and the messaging, and it delegates the Kubernetes-facing mechanics to separate projects. The remote-controller, the build-deploy-tool, the storage-calculator and the aergia-controller all live in their own repositories rather than in the lagoon repository, which is visible in the top level listing of the organisation links.

The UI is separate too. The ui is the main user interface and dashboard for Lagoon, in its own repository, lagoon-ui.

The practical implication for a team is that Lagoon is a composition of projects, not a monolith, and your version compatibility matrix is really a matrix of several other projects. The installation for each half is via a Helm chart, lagoon-core and lagoon-remote, in the separate lagoon-charts repository.

Running Lagoon locally, and the shape of the local stack

The installation note comes first, and it is a useful one: it is not necessary to install Lagoon on your local machine if you are looking to maintain websites hosted on Lagoon.

Lagoon can be installed locally, for evaluation, testing, debugging or development, using Helm charts together with kind, microk8s, k3s or similar. Or into a managed Kubernetes cloud provider of choice. The README names Amazon Elastic Kubernetes Service, Azure Kubernetes Service and Google Kubernetes Engine as the ones it is running on in production, and says the team is confident it will also run on any other managed Kubernetes service.

The local development stack is a docker-compose file, and it is worth reading because it shows the minimum service set the platform needs to run. The api-db service exposes the MariaDB storage, webhook-handler and backup-handler sit behind the broker, and the broker itself is a RabbitMQ container with a named volume for /var/lib/rabbitmq and the management port published alongside the AMQP port.

The image naming is a detail that tells you how the project handles release streams. Every service image is referenced through a set of environment variables, with a repository default of lagoon, a per-service tag variable such as IMAGE_REPO_API_DB_TAG, and a shared IMAGE_REPO_TAG fallback of latest. So a build can be pinned per service or across the board without editing the compose file. The broker service shows the pattern:

yaml
  broker:
    image: ${IMAGE_REPO:-lagoon}/broker:${IMAGE_REPO_BROKER_TAG:-${IMAGE_REPO_TAG:-latest}}
    ports:
      - '15672:15672'
      - '5672:5672'
    hostname: broker
    volumes:
      - broker:/var/lib/rabbitmq

The management port and the AMQP port are both published, and the RabbitMQ data directory is a named volume rather than a path on the host.

The Makefile is the other half of the local workflow, and its header explains the design. The main purpose of the Makefile is to provide easier handling of building images and running tests, and it understands the relation of the different images, like nginx-drupal being based on nginx, and builds them in the correct order. It also knows which services in docker-compose.yml depend on which base images.

The individual targets are described in the comments: make build/<imagename> builds an individual image and all of its needed parents, and make build-list gives a list of all buildable images. Make keeps track of each build image with an empty file named after the image in the build folder, so removing that file or running make clean forces a rebuild. The test targets build the needed images, start the needed Lagoon services via docker compose up and then execute the test, with make tests-list listing them and make tests able to run two in parallel with -j2.

The cost of the platform, and what to check before you commit

Lagoon is a large piece of software and the honest way to evaluate it is as infrastructure you will run for years rather than a library you install once.

The first cost is the service count. Core alone brings a GraphQL API with its own MariaDB and Redis, Keycloak with its own database, an auth server, an SSH access service, RabbitMQ, two webhook-related services, a backup handler and a notification service. Remote adds a Docker image cache, a controller, a build deploy tool and a set of optional operators. That is a lot of pods, and each one is something to monitor, upgrade and back up.

The second cost is the language mix. Node.js, Go and Bash in one repository, with a yarn workspace for the JavaScript and a Go module for the newer components, means your team needs to be comfortable in more than one ecosystem if it wants to contribute rather than just operate.

The third is the release cadence. lagoon-core versions arrive every week or two, and the repository keeps both UPGRADES.md and DEPRECATIONS.md, which tells you that upgrades are a documented, non-trivial event. Your Lagoon version is effectively a coordinated version across several upstream projects, and the interesting engineering is in the coordination.

What to check first, then. The requirements page at docs.lagoon.sh/installing-lagoon/requirements/ tells you what the platform needs before you install anything, and the contributing guide at docs.lagoon.sh/contributing is where the development workflow is. Deciding early whether Core and Remote live in separate clusters matters, because the RabbitMQ boundary is easier to design for than to retrofit.

The project has also been through deprecations, which is normal for a platform of this size and worth taking as a signal about upgrade planning rather than a knock.

Editorial conclusion

Adopt Lagoon when your workload is a multi-container application that has to look identical in local development and in production, and when you want the platform team to keep Kubernetes expertise out of the developer workflow. Do not adopt it for a single small service, since the platform has a large operational surface of its own, and do not plan on Lagoon Core reaching into your build clusters, because that separation is deliberate. Before you install, read the requirements page at docs.lagoon.sh, decide whether Core and Remote go in separate clusters, and check the UPGRADES.md and DEPRECATIONS.md files in the repository, since the release cadence of lagoon-core means you will be following breaking changes over time.

Frequently asked questions

What problem does Lagoon solve?

It lets developers build their services locally with Docker and run the exact same system in production, using the same container images, the same service configurations and the same code, with less cloud-native knowledge required from the application developers.

What is the difference between Lagoon Core and Lagoon Remote?

Core holds everything handling the API, authentication and external communication, including the GraphQL API, Keycloak and the RabbitMQ broker. Remote holds the services that provision, deploy and maintain sites on Kubernetes, mostly third-party projects like the Remote Controller and the Build Deploy Tool.

Why is RabbitMQ central to the Lagoon architecture?

All inter-cluster communication happens only via RabbitMQ, hosted in Core and consumed and published back to by Remote. That is what allows Core to avoid administrator-level access to the clusters running Remote, and lets Remotes sit behind firewalls or away from the internet.

Which workloads is Lagoon designed for?

Workloads that have traditionally been more complex to make cloud-native, such as CMS, LMS and other multi-container applications, handled with minimal retraining or reworking for the developers of those applications.

How do you install Lagoon for local development?

Using Helm charts together with kind, microk8s, k3s or similar, or into a managed Kubernetes provider such as EKS, AKS or GKE. The Makefile builds service images in dependency order and provides make up and make logs for running the stack locally.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. uselagoon/lagoon on GitHub
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/uselagoon-lagoon.svg)](https://hysenlabs.com/projects/uselagoon-lagoon)

Was this useful?