See also: 12-Factor app charm
Initialise a charm for a Flask application
Use charmcraft init
and specify the flask-framework
profile:
charmcraft init --profile flask-framework
Charmcraft automatically creates charmcraft.yaml
, requirements.txt
and source code for the charm in your current directory. You will need to check charmcraft.yaml
and README.md
and verify that the charm’s name and description are correct.
See also: Command ‘charmcraft init’
Add a configuration (Flask environment variable)
A charm configuration can be added if your Flask app requires environment variables, for
example, to pass a token for a service. Add the configuration in charmcraft.yaml
:
config:
options:
token:
description: The token for the service.
type: string
A user-defined configuration option will correspond to an environment variable generated by the paas-charm
project to expose the configuration to the Flask workload. In general, a configuration option config-option-name
will be mapped as FLASK_CONFIG_OPTION_NAME
where the option name will be converted to upper case, dashes will be converted to underscores and the FLASK_
prefix will be added. In the example above, the token
configuration will be mapped as the FLASK_TOKEN
environment variable. In addition to the environment variable, the configuration is also available in the Flask variable app.config
without the FLASK_
prefix.
The configuration can be set on the deployed charm using juju config <app name> token=<token>
.
See also: How to add a configuration to a charm, Configuration Handling – Flask Documentation^
Add an integration
A charm integration can be added to your charmed Flask app by providing the integration and endpoint definition in charmcraft.yaml
:
requires:
<endpoint name>:
interface: <endpoint interface name>
optional: false
Here, <endpoint name>
corresponds to the endpoint of the application with which you want the integration, and <endpoint interface name>
is the endpoint schema to which this relation conforms. Both the <endpoint name>
and <endpoint interface name>
must coincide with the structs defined in that particular application’s charm’s charmcraft.yaml
file.
You can provide the integration to your deployed Flask app using juju integrate <Flask charm> <endpoint name>
. After the integration has been established, the connection string and other configuration options will be available as environment variables that you may use to configure your Flask application.
For example, if you wish to integrate your Flask application with PostgreSQL (machine or k8s charm), add the following endpoint definition to charmcraft.yaml
:
requires:
postgresql:
interface: postgresql_client
optional: True
Provide the integration to your deployed Flask app with juju integrate <Flask charm> postgresql
. This integration creates the following environment variables you may use to configure your Flask application:
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
See also: How to add an integration to a charm, Charmcraft extension
flask-framework
(If your workload depends on a database) Migrate the database
If your app depends on a database, it is common to run a database migration
script before app startup which, for example, creates or modifies tables. This
can be done by including the migrate.sh
script in the root of your project. It
will be executed with the same environment variables and context as the flask
app.
If the migration script fails, it will retry upon update-status
. The migration script will run on every unit. The script is
assumed to be idempotent (i.e., can be run multiple times) and that it can be run
on multiple units simultaneously without issue. Handling multiple migration scripts that run concurrently can be achieved by, for example, locking any tables during the migration.
Include extra files in the OCI image
The following files are included in the image by default from the root of the project:
app
app.py
migrate
migrate.sh
migrate.py
static
templates
To change this, the following snippet needs to be added to the rockfile.yaml
:
parts:
flask-framework/install-app:
prime:
- flask/app/.env
- flask/app/app.py
- flask/app/webapp
- flask/app/templates
- flask/app/static
Note the flask/app/
prefix that is required followed by the relative path to
the project root.
Include additional debs in the OCI image
If your app requires debs – for example, to connect to a database – add the
following snipped to the rockfile.yaml
:
parts:
flask-framework/dependencies:
stage-packages:
# list required packages or slices for your flask application below.
- libpq-dev
Update the OCI image
After making a change to your app;
- make sure that any new files will be included in the new OCI image. See Including extra files in the OCI image
- Run
rockcraft pack
to create the new OCI image - Run
rockcraft.skopeo --insecure-policy copy --dest-tls-verify=false oci-archive:<path to rock file> docker://localhost:32000/<rock name>:<rock version>
to upload the OCI image to the registry - Run
juju refresh <app name> --path=<relative path to .charm file> --resource flask-app-image=<localhost:32000/<rock name>:<rock version>>
to deploy the new OCI image