12-Factor Web Development: The Plan for 25.04

As we’re about to head to The Hague for a few weeks of intensive discussions, the following is a preview of what we are planning for the next 6 months. We got a lot of requests for what we should put on our roadmap which we have accommodated to the best of our abilities.

  • We’re planning to add support for the Express for Node.js and for Spring Boot
  • Increase the available integrations by adding support for Kafka, SMTP and Tempo HA
  • Support prometheus service discovery for configuring metrics endpoints
  • A few minor additions such as async workers for Flask and Django, rootless containers and waiting for required configurations before starting an app.

Since the last update we have also made progress on documentation, including releasing FastAPI and Go documentation:

FastAPI:

Go:

There is more documentation for Go for Rockcraft coming soon! We’ve renamed the package which implements the charm logic for all the app charms and it is now called paas-charm. This was done in a backwards compatible way so your existing charms should continue to work.

Background Workers

In the last update, we added support for background workers. As a reminder, any pebble services defined in the rock ending with the -worker or -scheduler postfix will be provided with all the environment variables that the app receives, for example, to connect to redis. The following is a short demo of how these background workers can be utilized. If you would like to follow along, complete the setup instructions in the Hands-on approach portion of the FastAPI tutorial (the same will work on any of the supported frameworks) and create and change into a directory called background-workers. We will just use a hello world application in the main.py file:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")

async def root():

return {"message": "Hello World"}

Create the rockcraft.yaml file using rockcraft init --profile fastapi-framework and add the following services:

services:
  example-scheduler:
    override: merge
    summary: "Example scheduler service"
    command: "python3 -c 'import os;print(os.environ);import time;time.sleep(60)'"
    startup: enabled
  example-worker:
    override: merge
    summary: "Example worker service"
    command: "python3 -c 'import os;print(os.environ);import time;time.sleep(60)'"
    startup: enabled

Add the requirements.txt file with fastapi[standard] and then we can pack the rock and load it into MicroK8s:

ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true rockcraft pack
rockcraft.skopeo --insecure-policy copy \
  --dest-tls-verify=false \
  oci-archive:background-workers_0.1_amd64.rock \
  docker://localhost:32000/background-workers:0.1

Next we need to create the charm:

mkdir charm
cd charm
charmcraft init --profile fastapi-framework --name background-workers

Open charmcraft.yaml and add redis as a required integration to the end of the file:

requires:
  redis:
    interface: redis
    optional: false
    limit: 1

Pack the charm and deploy it with redis:

CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true charmcraft pack
juju add-model background-workers
juju deploy redis-k8s
juju deploy ./background-workers_amd64.charm background-workers \
  --resource app-image=localhost:32000/background-workers:0.1
juju integrate background-workers redis-k8s

We can keep an eye on the deployment progress using juju status --watch 5s and wait for the application to become active. Now we can see the logs of the newly added services using microk8s.kubectl exec pod/background-workers-0 -n background-workers -c app -- pebble logs example-worker and microk8s.kubectl exec pod/background-workers-0 -n background-workers -c app -- pebble logs example-scheduler. The output includes the information required to connect to redis, such as REDIS_K8S_SERVICE_HOST.

To demonstrate the difference between the worker and scheduler, scale up the application to 3 units using juju scale-application background-workers 3. Using microk8s.kubectl exec pod/background-workers-<0,1,2> -n background-workers -c app -- pebble logs example-worker each of the 3 units should have output for the worker service but only 1 of the units should have output for the scheduler service using microk8s.kubectl exec pod/background-workers-<0,1,2> -n background-workers -c app -- pebble logs example-scheduler.

That’s it for this one! We created a demo FastAPI application with 2 background worker services. We demonstrated that the worker services are started and receive all the environment variables on each unit and the scheduler services are only started on 1 unit and also receive all of the environment variables.