Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b1e45f8
docs: migrate 12-factor tutorials to Canonical Kubernetes
florentianayuwono Sep 15, 2026
d260d33
docs: use Canonical K8s exclusively in web app how-to guides
florentianayuwono Sep 15, 2026
49c61e3
tests: provision Canonical K8s for the tutorial spread suite
florentianayuwono Sep 15, 2026
ce03d36
docs: use a local registry for CK8s tutorials
florentianayuwono Oct 1, 2026
792903f
Merge remote-tracking branch 'origin/main' into docs/migrate-tutorial…
florentianayuwono Oct 1, 2026
9817acc
Merge remote-tracking branch 'origin/main' into docs/migrate-tutorial…
florentianayuwono Oct 12, 2026
7d6e8dd
docs: expose CK8s tutorial ingress via load balancer
florentianayuwono Oct 12, 2026
ff9abce
Apply batched suggestions from code review
florentianayuwono Oct 12, 2026
f2d9a1f
docs: fix Spring Boot curl backtick and add release note
florentianayuwono Oct 12, 2026
a65424d
Merge branch 'main' into docs/migrate-tutorials-ck8s-isd-4330
erinecon Oct 15, 2026
9afaba9
docs: use in-cluster registry and robust load-balancer setup for CK8s…
florentianayuwono Oct 19, 2026
55c58a1
docs: wait for MetalLB controller rollout before setting LB address pool
florentianayuwono Oct 20, 2026
232c06e
Merge branch 'main' into docs/migrate-tutorials-ck8s-isd-4330
erinecon Oct 20, 2026
56b5c9a
docs: target the cilium ingress class in CK8s tutorials
florentianayuwono Oct 20, 2026
37e6caf
docs: fix packed charm filename in 12-factor tutorials
florentianayuwono Oct 20, 2026
80b564b
ci: request combined runner label for docs spread tests
florentianayuwono Oct 20, 2026
e8c8995
ci: use single runner labels for docs spread jobs
florentianayuwono Oct 20, 2026
675e8e1
Apply suggestion from @lengau
lengau Oct 20, 2026
82e57cc
Merge branch 'main' into docs/migrate-tutorials-ck8s-isd-4330
florentianayuwono Oct 20, 2026
27959ef
Update docs/reuse/tutorial/setup_stable.rst
florentianayuwono Oct 21, 2026
afd03d3
Update docs/reuse/tutorial/setup_stable.rst
florentianayuwono Oct 21, 2026
0ff71ae
Update docs/reuse/tutorial/setup_edge.rst
florentianayuwono Oct 21, 2026
be2f426
Update docs/reuse/tutorial/setup_edge.rst
florentianayuwono Oct 21, 2026
66d8b6b
docs: bump tutorial VM to 8 GB RAM and allow "balancer's"
florentianayuwono Oct 21, 2026
dea7bbd
fix: deploy PostgreSQL 16 in the Django tutorial
florentianayuwono Oct 21, 2026
4406204
docs: move tutorial registry manifest into a downloadable file
florentianayuwono Oct 21, 2026
772731a
docs: update Django version in tutorial sample output
florentianayuwono Oct 21, 2026
da18d6f
Merge branch 'main' into docs/migrate-tutorials-ck8s-isd-4330
erinecon Oct 21, 2026
2d3ca94
docs: build the FastAPI tutorial rock on a bare Ubuntu 26.04 base
florentianayuwono Oct 21, 2026
e806fe1
ci: fix docs spread runner labels and clear containerd before k8s boo…
florentianayuwono Oct 21, 2026
05cf1ed
fix: route all paths through the CK8s tutorial ingress
florentianayuwono Oct 22, 2026
8321db9
test: give the tutorial endpoint checks more time after a refresh
florentianayuwono Oct 22, 2026
785a9e9
Merge branch 'main' into docs/migrate-tutorials-ck8s-isd-4330
florentianayuwono Oct 22, 2026
5f8f842
test: wait for the ingress in Express and Spring Boot, use PostgreSQL…
florentianayuwono Oct 22, 2026
5d34c56
Update docs/release-notes/charmcraft-4.5.rst
florentianayuwono Oct 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/spread-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
path: ${{ steps.charmcraft.outputs.snap }}

spread-select:
runs-on: [spread-installed]
runs-on: spread-enabled
outputs:
systems: ${{ steps.select.outputs.systems }}
steps:
Expand Down
1 change: 1 addition & 0 deletions docs/.custom_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Autotools
backend
backends
backported
balancer('s)?
Bazel
boolean
bugfix(es)?
Expand Down
2 changes: 1 addition & 1 deletion docs/howto/code/custom-action-clearsession/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ execute: |
django-app-image=localhost:32000/django-hello-world:0.1

# Deploy + integrate with postgres
juju deploy postgresql-k8s --trust --channel 14/edge
juju deploy postgresql-k8s --trust --channel 16/stable
juju integrate django-hello-world postgresql-k8s

# Check that django-hello-world and postgres are active idle
Expand Down
21 changes: 4 additions & 17 deletions docs/howto/manage-web-app-charms/integrate-web-app-charm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -194,24 +194,11 @@ COS relies on the Traefik ingress to expose, for example, Grafana.
Traefik requires a load balancer to be enabled with an IP range. Provide the
IP range and enable the load balancer with:

.. tab-set::

.. tab-item:: MicroK8s
:sync: microk8s

.. code-block:: bash

IPADDR=$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc')
microk8s enable metallb:$IPADDR-$IPADDR

.. tab-item:: Canonical K8s
:sync: canonical-k8s

.. code-block:: bash
.. code-block:: bash

IPADDR=$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc')
sudo k8s set load-balancer.l2-mode=true load-balancer.cidrs=$IPADDR-$IPADDR
sudo k8s enable load-balancer
IPADDR=$(ip -4 -j route get 2.2.2.2 | jq -r '.[] | .prefsrc')
sudo k8s set load-balancer.l2-mode=true load-balancer.cidrs=$IPADDR-$IPADDR
sudo k8s enable load-balancer


Deploy and integrate observability to the 12-factor app with:
Expand Down
11 changes: 11 additions & 0 deletions docs/release-notes/charmcraft-4.5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ Minor init profile improvements
- Charms created with the 12-factor framework profiles targeting Ubuntu 26.04 now default
to ``charm-user: non-root``.

Documentation improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~

Charmcraft 4.5 includes the following documentation changes:

- The 12-factor app :ref:`tutorials <tutorial>` now use Canonical Kubernetes
instead of MicroK8s, including a local OCI registry and load-balancer-backed
ingress.




Feature deprecations
--------------------
Expand Down
44 changes: 44 additions & 0 deletions docs/reuse/tutorial/registry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Namespace
metadata:
name: container-registry
- apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
namespace: container-registry
spec:
replicas: 1
selector:
matchLabels:
app: registry
template:
metadata:
labels:
app: registry
spec:
containers:
- name: registry
image: registry:2.8.3
ports:
- containerPort: 5000
readinessProbe:
httpGet:
path: /v2/
port: 5000
- apiVersion: v1
kind: Service
metadata:
name: registry
namespace: container-registry
spec:
type: NodePort
selector:
app: registry
ports:
- port: 5000
targetPort: 5000
nodePort: 32000
80 changes: 56 additions & 24 deletions docs/reuse/tutorial/setup_edge.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ from the 26.04 blueprint:

.. code-block:: text

multipass launch --cpus 4 --disk 50G --memory 4G --name charm-dev 26.04
multipass launch --cpus 4 --disk 50G --memory 8G --name charm-dev 26.04

Once the VM is up, open a shell into it:

Expand Down Expand Up @@ -35,8 +35,8 @@ In order to create the charm, you'll need to install Charmcraft:

sudo snap install charmcraft --channel latest/edge --classic

Install LXD, MicroK8s, and Juju
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Install LXD and Canonical Kubernetes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

LXD will be required for building the rock.
Make sure it is installed:
Expand All @@ -53,48 +53,80 @@ Initialize LXD:

lxd init --auto

MicroK8s is required to deploy the |12FactorApp| application on Kubernetes.
Let's install MicroK8s using the ``1.34-strict/stable`` channel, add the current
user to the group, and activate the changes:
Canonical Kubernetes is required to deploy the |12FactorApp| application on
Kubernetes. Let's install Canonical Kubernetes using the
``1.34-classic/stable`` channel and bootstrap the cluster:

.. code-block:: text

sudo snap install microk8s --channel 1.34-strict/stable
sudo adduser $USER snap_microk8s
newgrp snap_microk8s
sudo snap install k8s --classic --channel 1.34-classic/stable
sudo k8s bootstrap

Several MicroK8s addons are required for deployment. We need
``hostpath-storage`` so Juju can provide storage volumes,
``registry`` to host the OCI image for our app, and ``ingress``
so that we can expose and access the app.
Canonical Kubernetes needs local storage so Juju can provide storage volumes,
and ingress so that we can expose and access the app.

Enable the necessary MicroK8s addons:
Enable the necessary features:

.. code-block:: bash

sudo microk8s enable hostpath-storage
sudo microk8s enable registry
sudo microk8s enable ingress
sudo k8s enable local-storage
sudo k8s enable ingress

Check the status of MicroK8s:
Canonical Kubernetes exposes ingress through a load-balancer service. Enable
the built-in load balancer, wait for the MetalLB controller (which hosts the
load balancer's validating webhook) to roll out, then point its address pool
Comment thread
florentianayuwono marked this conversation as resolved.
Resolved
at the VM's own IP so the ingress is assigned a reachable address:

.. code-block:: bash

sudo microk8s status --wait-ready
sudo k8s enable load-balancer
sudo k8s kubectl rollout status deployment/metallb-controller \
-n metallb-system --timeout=5m
INGRESS_IP=$(ip -4 route get 2.2.2.2 | grep -oP 'src \K[0-9.]+')
sudo k8s set load-balancer.l2-mode=true load-balancer.cidrs="$INGRESS_IP/32"

If successful, the terminal will output ``microk8s is running``
along with a list of enabled and disabled add-ons.
Check the status of Canonical Kubernetes:

.. code-block:: bash

sudo k8s status --wait-ready
Comment thread
florentianayuwono marked this conversation as resolved.
Resolved

If successful, the terminal will output ``status: ready``
along with a list of enabled and disabled features.

Set up a local registry
Comment thread
florentianayuwono marked this conversation as resolved.
Resolved
~~~~~~~~~~~~~~~~~~~~~~~~~

Canonical Kubernetes pulls application images from an OCI registry. Deploy a
small registry inside the cluster, exposed on the node at ``localhost:32000``:

.. code-block:: bash

curl --fail --location --output registry.yaml \
https://raw.githubusercontent.com/canonical/charmcraft/main/docs/reuse/tutorial/registry.yaml
sudo k8s kubectl apply -f registry.yaml

Wait for the registry to become available:

.. code-block:: bash

sudo k8s kubectl rollout status deployment/registry \
-n container-registry --timeout=5m

Install Juju
~~~~~~~~~~~~

Juju is required to deploy the |12FactorApp| application.
Comment thread
florentianayuwono marked this conversation as resolved.
Resolved
We'll install Juju using the ``3.6/stable`` channel. Since the snap is
sandboxed, we'll also manually create a directory to contain
its files. Once Juju is ready, we initialize it by bootstrapping a
development controller:
its files. Canonical Kubernetes isn't automatically registered as a Juju
cloud, so let's add it before bootstrapping a development controller:

.. code-block:: text

sudo snap install juju --channel 3.6/stable
mkdir -p ~/.local/share
juju bootstrap microk8s dev-controller
sudo k8s config | juju add-k8s k8s-cloud --client
juju bootstrap k8s-cloud dev-controller

It could take a few minutes to download the images.
80 changes: 56 additions & 24 deletions docs/reuse/tutorial/setup_stable.rst
Comment thread
erinecon marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ from the 24.04 blueprint:

.. code-block:: text

multipass launch --cpus 4 --disk 50G --memory 4G --name charm-dev 24.04
multipass launch --cpus 4 --disk 50G --memory 8G --name charm-dev 24.04

Once the VM is up, open a shell into it:

Expand All @@ -30,8 +30,8 @@ In order to create the charm, you'll need to install Charmcraft:

sudo snap install charmcraft --channel latest/stable --classic

Install LXD, MicroK8s, and Juju
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Install LXD and Canonical Kubernetes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

LXD will be required for building the rock.
Make sure it is installed:
Expand All @@ -48,49 +48,81 @@ Initialize LXD:

lxd init --auto

MicroK8s is required to deploy the |12FactorApp| application on Kubernetes.
Let's install MicroK8s using the ``1.34-strict/stable`` channel, add the current
user to the group, and activate the changes:
Canonical Kubernetes is required to deploy the |12FactorApp| application on
Kubernetes. Let's install Canonical Kubernetes using the
``1.34-classic/stable`` channel and bootstrap the cluster:

.. code-block:: text

sudo snap install microk8s --channel 1.34-strict/stable
sudo adduser $USER snap_microk8s
newgrp snap_microk8s
sudo snap install k8s --classic --channel 1.34-classic/stable
sudo k8s bootstrap


Several MicroK8s addons are required for deployment. We need
``hostpath-storage`` so Juju can provide storage volumes,
``registry`` to host the OCI image for our app, and ``ingress``
so that we can expose and access the app.
Canonical Kubernetes needs local storage so Juju can provide storage volumes,
and ingress so that we can expose and access the app.

Enable the necessary MicroK8s addons:
Enable the necessary features:

.. code-block:: bash

sudo microk8s enable hostpath-storage
sudo microk8s enable registry
sudo microk8s enable ingress
sudo k8s enable local-storage
sudo k8s enable ingress

Check the status of MicroK8s:
Canonical Kubernetes exposes ingress through a load-balancer service. Enable
the built-in load balancer, wait for the MetalLB controller (which hosts the
load balancer's validating webhook) to roll out, then point its address pool
at the VM's own IP so the ingress is assigned a reachable address:

.. code-block:: bash

sudo microk8s status --wait-ready
sudo k8s enable load-balancer
sudo k8s kubectl rollout status deployment/metallb-controller \
-n metallb-system --timeout=5m
INGRESS_IP=$(ip -4 route get 2.2.2.2 | grep -oP 'src \K[0-9.]+')
sudo k8s set load-balancer.l2-mode=true load-balancer.cidrs="$INGRESS_IP/32"

If successful, the terminal will output ``microk8s is running``
along with a list of enabled and disabled add-ons.
Check the status of Canonical Kubernetes:

.. code-block:: bash

sudo k8s status --wait-ready

If successful, the terminal will output ``status: ready``
along with a list of enabled and disabled features.

Set up a local registry
~~~~~~~~~~~~~~~~~~~~~~~~~

Canonical Kubernetes pulls application images from an OCI registry. Deploy a
small registry inside the cluster, exposed on the node at ``localhost:32000``:

.. code-block:: bash

curl --fail --location --output registry.yaml \
https://raw.githubusercontent.com/canonical/charmcraft/main/docs/reuse/tutorial/registry.yaml
sudo k8s kubectl apply -f registry.yaml

Wait for the registry to become available:

.. code-block:: bash

sudo k8s kubectl rollout status deployment/registry \
-n container-registry --timeout=5m

Install Juju
~~~~~~~~~~~~

Juju is required to deploy the |12FactorApp| application.
Comment thread
florentianayuwono marked this conversation as resolved.
Resolved
We'll install Juju using the ``3.6/stable`` channel. Since the snap is
sandboxed, we'll also manually create a directory to contain
its files. Once Juju is ready, we initialize it by bootstrapping a
development controller:
its files. Canonical Kubernetes isn't automatically registered as a Juju
cloud, so let's add it before bootstrapping a development controller:

.. code-block:: text

sudo snap install juju --channel 3.6/stable
mkdir -p ~/.local/share
juju bootstrap microk8s dev-controller
sudo k8s config | juju add-k8s k8s-cloud --client
juju bootstrap k8s-cloud dev-controller

It could take a few minutes to download the images.
Loading
Loading