Since the last update, we have added support for the Express framework! Express is a widely used web application framework for Node.js. This new framework supports all the integrations the previous frameworks supported. Canonical’s own web team is already using this framework to easily charm their boilerplateNode.js application.
In this post we will see what changes were made to charm the original application by reviewing the repository. We installed Rockcraft, Charmcraft, and Juju, and we bootstrapped a MicroK8s controller ahead of time.
Charm the boilerplate Node.js application
1- The application code is moved into the app
folder.
2- In app
folder’s parent, the following command is run:
rockcraft init --profile expressjs-framework
This command creates a rockcraft.yaml
file. The Rockcraft file is a recipe file to pack the rock that houses our Express application.
3-The rockcraft.yaml
is modified to adjust auto-generated components to make sure the application is packaged correctly. This application is using Bun to compile the application. 12 Factor tooling does not expect this, so we are modifying the expressjs-framework/install-app
part to pack the application before installing it.
The expressjs-framework/install-app
part is auto-generated and used to install the Node.js application into the rock. You can find its original version when you run rockcraft expand-extensions
.
The original part:
expressjs-framework/install-app:
override-build: |
rm -rf node_modules
craftctl default
npm config set script-shell=bash --location project
cp ${CRAFT_PART_BUILD}/.npmrc ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc/.npmrc
chown -R 584792:584792 ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc
ln -s /lib/node_modules/react-express-poc ${CRAFT_PART_INSTALL}/app
chown -R 584792:584792 ${CRAFT_PART_INSTALL}/app
The updated part:
expressjs-framework/install-app:
build-snaps:
- bun-js
override-build: |
rm -rf node_modules
# We need the dev dependencies to build the app
npm install --include=dev
bun run build
craftctl default
# We need to copy the built files to the install directory
mkdir -p ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc/dist
cp -r dist/. ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc/dist
npm config set script-shell=bash --location project
cp ${CRAFT_PART_BUILD}/.npmrc ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc/.npmrc
chown -R 584792:584792 ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc
ln -s /lib/node_modules/react-express-poc ${CRAFT_PART_INSTALL}/app
chown -R 584792:584792 ${CRAFT_PART_INSTALL}/app
Let’s go through the changes made:
build-snaps:
- bun-js
When building the application, we need the Bun executable. The easiest way to install it is using bun-js
snap. In build-snaps
we can list the snaps we need for building.
The first line installs the dependencies, and the following 2 lines use Bun to build the application.
npm install --include=dev
bun run build
The placement of these lines is very important. The craftctl default
line installs the application globally, so we need to build the application before installing it.
After installing the application, we need to copy the build files into the install directory with the following commands:
mkdir -p ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc/dist
cp -r dist/. ${CRAFT_PART_INSTALL}/lib/node_modules/react-express-poc/dist
These are the only changes required to the rockcraft.yaml
.
Please note that these changes are specific for this application and not required unless you use Bun in the same exact way.
3- Update the package.json
. The 12 Factor Express tooling expects the start
script to be in the package.json
:
"start": "node dist/server/server.js"
This is all we need for the rock to pack successfully.
4- Pack the rock. The Express Framework is still in the experimental stage, so we need to enable it first, then pack the rock.
export ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=True
rockcraft pack
5- After packing the rock, we need to upload it into a local registry.
rockcraft.skopeo --insecure-policy copy --dest-tls-verify=false oci-archive:charmed-nodejs-boilerplate_0.0.4_amd64.rock docker://localhost:32000/charmed-nodejs-boilerplate:0.0.4
6- Create the charm folder and cd
into it.
mkdir charm
cd charm
7- Initiate the charm.
charmcraft init --profile expressjs-framework
8- Pack the charm. The Express Framework is still in the experimental stage, so we need to enable it first, then pack the charm.
export CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=True
charmcraft pack
9- Deploy the application locally. Let’s first create a model to deploy our example application.
juju add-model demo
juju deploy ./charmed-nodejs-boilerplate_amd64.charm demo --resource app-image=localhost:32000/charmed-nodejs-boilerplate:0.0.4
Test time!
By default the port in the 12 Factor Express application is 8080
. We can curl the application to see if it is working:
curl 10.1.25.170:8080
It is working!