5. Opinionated nature of the 12-factor tooling

The native 12-factor framework support in Rockcraft and Charmcraft provides a streamlined approach to setting up a rock and charm for a web app, but this support contains strong and weak opinions about the project structure, the Ubuntu base, framework versions, and configurations. This document describes the various ways in which the 12-factor tooling is opinionated.

Note

There are several components of 12-factor app rocks and charms that can be configured or customized by the user. See Supported customizable features and capabilities for a complete list.

5.1. Project structure

For Rockcraft to successfully initialize the rock for a web app, it inspects the directory where rockcraft init is run to search for specific files and global variables depending upon the selected framework. The following sub-sections detail the requirements for each of the supported frameworks.

5.1.1. Django

The project must be set up with the structure project-name/project_name/project_name, where project-name specifies the name of the Django project. The rock must be initialized in the project-name directory.

There must be a project-name/requirements.txt file where Django is declared as a dependency. There must also be a project-name/project_name/project_name/wsgi.py file in the project.

When rockcraft init is run, Rockcraft searches for these two files and expects to find a global variable named application in the wsgi.py file.

The initialization will fail if Rockcraft does not find the requirements.txt file, the wsgi.py file, or the global variable application.

5.1.2. Express

The Express app must reside in a dedicated app directory containing a package.json file. The package.json file must contain a scripts key, and this key must contain a start script which defines how the server is run. Furthermore, the name key in the file must be defined and set to the app name.

The rock must be initialized outside of the app directory. When rockcraft init is run, Rockcraft searches for the app/package.json file and expects to find both the scripts: start and name keys.

The initialization will fail if Rockcraft does not find the file and both keys.

5.1.3. FastAPI

The FastAPI project must contain a requirements.txt file where fastapi is listed as a dependency. The rock must be initialized in the same directory as the requirements.txt file.

There must also be an ASGI app in the FastAPI project with the global variable app. Rockcraft will search for different names and locations for this file:

Possible project file name

Possible project file locations

app.py

Same directory as requirements.txt file, /app, or /src

main.py

Same directory as requirements.txt file, /app, or /src

__init__.py

/app or /src directories

When rockcraft init is run, Rockcraft searches for the project file in the root directory, in the app directory, or in the src directory. Rockcraft expects to find the global variable app defined in the project file.

The initialization will fail if Rockcraft does not find a project file or the global variable app.

5.1.4. Flask

The Flask project must contain a requirements.txt file where Flask is listed as a dependency. In the same directory, there must also be an WSGI app declared in an app.py file with the path app:app. The name of the Flask object must be set to app.

The rock must be initialized in the same directory as the requirements.txt and app.py files.

When rockcraft init is run, Rockcraft searches for these files in the root directory. Rockcraft expects to find the app:app path in app.py and to find the name of the Flask object to be app.

The initialization will fail if Rockcraft does not find both files, if the app:app path is missing, or if the name of the Flask object is not app.

5.1.5. Go

The Go project must contain a go.mod file. The rock must be initialized in the same directory as this file.

When rockcraft init is run, Rockcraft searches for this file. The initialization will fail if Rockcraft does not find the file.

When rockcraft pack is run, Rockcraft builds a binary with the same name as the Go project. You can override the binary name by updating the services parameter of the app’s rockcraft.yaml file to pass a different name.

5.1.6. Spring Boot

The Spring Boot project must contain either a pom.xml or build.gradle file. The rock must be initialized in the same directory as this file. The project must not contain both files, otherwise the rock initialization will fail.

If you define the Spring Boot project using a pom.xml file, Rockcraft will install the Maven plugin and check whether an mvnw executable file exists in the same directory. If the executable file doesn’t exist, Rockcraft will create the file.

If you use a build.gradle file, Rockcraft will install the Gradle plugin and check whether an gradlew executable file exists in the same directory. If the executable file doesn’t exist, Rockcraft will create the file.

The mvnw or gradlew file must be executable, or the rock initialization will fail. The project must not contain both executable files, otherwise the rock initialization will fail.

When rockcraft init is run, Rockcraft searches for either of these files and their corresponding executable files. The initialization will fail if Rockcraft does not find either file and its corresponding executable file, or if it finds both files or both executable files.

5.2. Minimum supported versions of the frameworks

Not all versions of the web app frameworks are supported. Check with us on the Matrix channel if you have questions about supported web app framework versions for the 12-factor tooling.