Express framework extension

The expressjs-framework extension includes configuration options customised for an Express application. This document describes all the keys that a user may interact with.

Tip

If you’d like to see the full contents contributed by this extension, see How to manage extensions.

charmcraft.yaml > config > options

You can use the predefined options (run charmcraft expand-extensions for details) but also add your own, as needed.

The predefined configuration options for the expressjs-framework are:

  • app-port: Port in which the application should listen. The ingress will be configured using this port. The environment variable passed to the app is APP_PORT. Default value is 8080.

  • app-secret-key-id: A secret you can use for sessions, protection against cross-site request forgery, or any other thing where you need a random secret shared by all units. The environment variable passed to the app is APP_SECRET_KEY. The secret should contain a single key, value, which maps to the actual application secret key. To create the secret, run the following command: juju add-secret my-app-secret-key value=<secret-string>, grant the application access to the secret and use the output secret ID to configure this option. If this configuration option is not set, the environment variable APP_SECRET_KEY is a 64 byte Base64 encoded random string.

  • metrics-port: Port where the Prometheus metrics will be scraped. The environment variable passed to the app is METRICS_PORT. Default value is 8080.

  • metrics-path: Path where the Prometheus metrics will be scraped. The environment variable passed to the app is METRICS_PATH. Default value is /metrics.

In case you want to add extra configuration options, any option you define will be used to generate environment variables; a user-defined option config-option-name will generate an environment variable named APP_CONFIG_OPTION_NAME where the option name is converted to upper case, dashes are converted to underscores and APP_ is added at the front.

In either case, you will be able to set it in the usual way by running juju config <application> <option>=<value>. For example, if you define an option called token, as below, this will generate a APP_TOKEN environment variable, and a user of your charm can set it by running juju config <application> token=<token>.

charmcraft.yaml
config:
  options:
    token:
      description: The token for the service.
      type: string

In addition to this, you can set the configuration option to be mandatory by setting the optional key to false. This will block the charm and stop services until the configuration is supplied. For example, if your application needs an api-token to function correctly you can set optional, as shown below. This will block the charm and stop the services until the api-token configuration is supplied.

charmcraft.yaml
config:
  options:
    api-token:
      description: The token necessary for the service to run.
      type: string
      optional: false

Note

A configuration with optional: false can’t also have a default key. If it has both, the charm will fail to pack.

Relations

Your charm already has the following peers, provides, and requires relations, as they were automatically supplied by the ExpressJS extension:

peers:
  secret-storage:
    interface: secret-storage
provides:
  metrics-endpoint:
    interface: prometheus_scrape
  grafana-dashboard:
    interface: grafana_dashboard
requires:
  logging:
    interface: loki_push_api
  ingress:
    interface: ingress
    limit: 1

In addition to these relations, in each provides and requires block you may specify further relations, to integrate with the following charms:

Relation

Endpoint definition

Ingress traefik and nginx ingress integrator

Already available in the charm

MySQL machine and Kubernetes charm

requires:
  mysql:
    interface: mysql_client
    optional: True
    limit: 1

PostgreSQL machine and Kubernetes charm

requires:
  postgresql:
    interface: postgresql_client
    optional: True
    limit: 1

MongoDB charm

requires:
  mongodb:
    interface: mongodb_client
    optional: True
    limit: 1

Canonical Observability Stack (COS)

Already available in the charm

Redis charm

requires:
  redis:
    interface: redis
    optional: True
    limit: 1

SAML charm

requires:
  saml:
    interface: saml
    optional: True
    limit: 1

S3 charm

requires:
  s3:
    interface: s3
    optional: True
    limit: 1

RabbitMQ machine and Kubernetes charm

requires:
  rabbitmq:
    interface: rabbitmq
    optional: True
    limit: 1

Tempo charm

requires:
  tracing:
    interface: tracing
    optional: True
    limit: 1

SMTP charm

requires:
  smtp:
    interface: smtp
    optional: True
    limit: 1

OpenFGA charm

requires:
  openfga:
    interface: openfga
    optional: True
    limit: 1

Note

The key optional with value False means that the charm will get blocked and stop the services if the integration is not provided.

To add one of these relations, e.g., PostgreSQL, in the project file, include the appropriate requires block and integrate with juju integrate <expressjs charm> postgresql as usual.

Environment variables

Each relation adds its own environment variables to your ExpressJS app. Some are required, meaning they must be set for the relation to function.

The environment variable APP_BASE_URL provides the Ingress URL for an Ingress relation or the Kubernetes service URL if there is no Ingress relation.

Relation

Environment variables

PostgreSQL

  • POSTGRESQL_DB_CONNECT_STRING

  • POSTGRESQL_DB_SCHEME

  • POSTGRESQL_DB_NETLOC

  • POSTGRESQL_DB_PATH

  • POSTGRESQL_DB_PARAMS

  • POSTGRESQL_DB_QUERY

  • POSTGRESQL_DB_FRAGMENT

  • POSTGRESQL_DB_USERNAME

  • POSTGRESQL_DB_PASSWORD

  • POSTGRESQL_DB_HOSTNAME

  • POSTGRESQL_DB_PORT

  • POSTGRESQL_DB_NAME

MySQL

  • MYSQL_DB_CONNECT_STRING

  • MYSQL_DB_SCHEME

  • MYSQL_DB_NETLOC

  • MYSQL_DB_PATH

  • MYSQL_DB_PARAMS

  • MYSQL_DB_QUERY

  • MYSQL_DB_FRAGMENT

  • MYSQL_DB_USERNAME

  • MYSQL_DB_PASSWORD

  • MYSQL_DB_HOSTNAME

  • MYSQL_DB_PORT

  • MYSQL_DB_NAME

MongoDB

  • MONGODB_DB_CONNECT_STRING

  • MONGODB_DB_SCHEME

  • MONGODB_DB_NETLOC

  • MONGODB_DB_PATH

  • MONGODB_DB_PARAMS

  • MONGODB_DB_QUERY

  • MONGODB_DB_FRAGMENT

  • MONGODB_DB_USERNAME

  • MONGODB_DB_PASSWORD

  • MONGODB_DB_HOSTNAME

  • MONGODB_DB_PORT

  • MONGODB_DB_NAME

Redis

  • REDIS_DB_CONNECT_STRING

  • REDIS_DB_SCHEME

  • REDIS_DB_NETLOC

  • REDIS_DB_PATH

  • REDIS_DB_PARAMS

  • REDIS_DB_QUERY

  • REDIS_DB_FRAGMENT

  • REDIS_DB_USERNAME

  • REDIS_DB_PASSWORD

  • REDIS_DB_HOSTNAME

  • REDIS_DB_PORT

  • REDIS_DB_NAME

SAML

  • SAML_ENTITY_ID (required)

  • SAML_METADATA_URL (required)

  • SAML_SINGLE_SIGN_ON_REDIRECT_URL (required)

  • SAML_SIGNING_CERTIFICATE (required)

S3

  • S3_ACCESS_KEY (required)

  • S3_SECRET_KEY (required)

  • S3_BUCKET (required)

  • S3_REGION

  • S3_STORAGE_CLASS

  • S3_ENDPOINT

  • S3_PATH

  • S3_API_VERSION

  • S3_URI_STYLE

  • S3_ADDRESSING_STYLE

  • S3_ATTRIBUTES

  • S3_TLS_CA_CHAIN

RabbitMQ

  • RABBITMQ_CONNECT_STRING

  • RABBITMQ_SCHEME

  • RABBITMQ_NETLOC

  • RABBITMQ_PATH

  • RABBITMQ_PARAMS

  • RABBITMQ_QUERY

  • RABBITMQ_FRAGMENT

  • RABBITMQ_USERNAME

  • RABBITMQ_PASSWORD

  • RABBITMQ_HOSTNAME

  • RABBITMQ_PORT

  • RABBITMQ_VHOST

Tracing

  • OTEL_EXPORTER_OTLP_ENDPOINT

  • OTEL_SERVICE_NAME

SMTP

  • SMTP_HOST

  • SMTP_PORT

  • SMTP_USER

  • SMTP_PASSWORD_ID

  • SMTP_AUTH_TYPE

  • SMTP_TRANSPORT_SECURITY

  • SMTP_DOMAIN

OpenFGA

  • FGA_STORE_ID

  • FGA_TOKEN

  • FGA_GRPC_API_URL

  • FGA_HTTP_API_URL

HTTP Proxy

Proxy settings should be set as model configurations. Charms generated using the expressjs-framework extension will make the Juju proxy settings available as the HTTP_PROXY, HTTPS_PROXY and NO_PROXY environment variables. For example, the juju-http-proxy environment variable will be exposed as HTTP_PROXY to the Express service.

Background Tasks

Extra services defined in the file rockcraft.yaml with names ending in -worker or -scheduler will be passed the same environment variables as the main application. If there is more than one unit in the application, the services with the name ending in -worker will run in all units. The services with name ending in -scheduler will only run in one of the units of the application.

Observability

12-Factor charms are designed to be easily observable using the Canonical Observability Stack.

You can easily integrate your charm with Loki, Prometheus and Grafana using Juju.

juju integrate expressjs-k8s grafana
juju integrate expressjs-k8s loki
juju integrate expressjs-k8s prometheus

After integration, you will be able to observe your workload using Grafana dashboards.

In addition to that you can also trace your workload code using Tempo.

To learn about how to deploy Tempo you can read the documentation here.

OpenTelemetry will automatically read the environment variables and configure the OpenTelemetry SDK to use them. See the OpenTelemetry documentation for further information about tracing.

Secrets

Juju secrets can be passed as environment variables to your Express application. The secret ID has to be passed to the application as a config option in the project file of type secret. This config option has to be populated with the secret ID, in the format secret:<secret ID>.

The environment variable name passed to the application will be:

APP_<config option name>_<key inside the secret>

The <config option name> and <key inside the secret> keywords in the environment variable name will have the hyphens replaced by underscores and all the letters capitalised.

See more: Juju | Secret