How to upgrade¶
When updating your project, you may need to rebuild and redeploy both rocks and charms. This guide explains how to safely upgrade your deployment.
Repack your rock¶
If you update any files in your project (for instance, requirements.txt, rockcraft.yaml,
or application source code), you must repack the rock using rockcraft pack.
rockcraft pack
This command creates a new .rock file in the current directory. Before packing, make sure
to bump the version field in your rockcraft.yaml to properly track versions of your rock
and help avoid Kubernetes caching an old version of the image.
Push the rock to the registry¶
Once repacked, upload the new rock using an updated tag in your container registry:
sudo rockcraft.skopeo copy \
--insecure-policy \
oci-archive:myapp_0.2_amd64.rock \
docker-daemon:myapp:0.2
Refresh the deployed application¶
Once your new rock is available in the registry, refresh your Juju application to use it.
Use the juju refresh command and specify the new rock as a resource:
juju refresh myapp --resource app-image=localhost:32000/myapp:0.2
If your charm was deployed from a local path, you also need to provide the charm path when refreshing the application:
juju refresh myapp --resource app-image=localhost:32000/myapp:0.1 \
--path ./<charm file>.charm
Upgrading the charm itself¶
If you’ve made changes to the charm source code, you need to repack the charm:
charmcraft pack
This generates a .charm file in the current directory. Its name depends on the
charm name, base and architecture. You can then refresh it in Juju:
juju refresh myapp --path ./<charm file>.charm
We pin major versions of paas-charm and do not introduce breaking changes in
minor or patch releases. To upgrade to a new version of the paas-charm
library, repack the charm using charmcraft pack.
Upgrade to paas-charm 2.0¶
paas-charm 2.0 is a major release with backwards-incompatible changes.
See the 2.0 release notes for the full list.
paas-charm 2.0 requires charms and rocks built for Ubuntu 26.04 LTS. A
Charmcraft project that retains an Ubuntu 22.04 LTS or Ubuntu 24.04 LTS base
continues to use and pin paas-charm 1.x; repacking such a project is not a
supported upgrade path to paas-charm 2.0.
The paas-charm 2.0 charm contract (the peers relation, the secret-typed
app-secret-key option, and the --base option of charmcraft init) is generated
by the latest/edge channel of the Charmcraft snap. Charmcraft 4.4.2 (latest/stable) doesn’t accept
charmcraft init --base, and for Ubuntu 26.04 LTS it still generates the earlier
contract, with the secret-storage relation and flask-secret-key options.
Before refreshing a deployment, manually migrate and rebuild every rock and charm:
Move every rock to the Ubuntu 26.04 LTS build base¶
Set base: ubuntu@26.04. For a chiselled rock, set base: bare and
build-base: ubuntu@26.04 instead. Follow the
Rockcraft Ubuntu 26.04 LTS migration guide
and the
Rockcraft extension reference,
including any required part-name and package changes.
Extension-generated Rockcraft part names use / as their separator on
lower bases and . when the effective build base is Ubuntu 26.04 LTS.
For a bare rock, build-base determines the separator. Preserve the newly
generated names and update custom parts overrides, after references,
selectors, scripts, patches, CI assertions, and other configuration that
names generated extension parts. For example,
flask-framework/dependencies becomes
flask-framework.dependencies, and
django-framework/dependencies becomes
django-framework.dependencies. Not every generated part exists for
every framework, so compare overrides with the expanded Ubuntu 26.04 LTS
project rather than changing names blindly.
On Ubuntu 26.04 LTS, entries in the prime key of the
install-app part must start with app. For example, update
flask/app/app.py to app/app.py. Rockcraft rejects the previous
framework-prefixed form when packing. See the
Rockcraft Flask extension reference
for the prime format.
Flask and Django rocks have an additional layout change: the application
root is now /app and gunicorn.conf.py is under
/var/lib/gunicorn. Access and error logs continue to use stdout and
stderr. All Ubuntu 26.04 LTS framework rocks also provide /app-data as a
writable directory owned by the _daemon_ workload user.
Generate the migrated Ubuntu 26.04 LTS charm project¶
Choose the framework profile that matches the existing charm. In the commands
below, replace <FRAMEWORK> with django, expressjs, fastapi,
flask, go, or spring-boot.
From the directory that contains the existing charm project, create a new
charm-26-04 directory and initialize the Ubuntu 26.04 LTS profile there:
mkdir charm-26-04
cd charm-26-04
CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=1 \
charmcraft init --profile <FRAMEWORK>-framework --base ubuntu@26.04
Do not run this command in the existing charm directory. charmcraft init
does not overwrite existing files, so it cannot safely update an initialized
project in place.
Move application-specific work into the generated project¶
Use charm-26-04 as the migration destination. Copy the existing charm’s
application and charm source code and tests into the corresponding generated
locations. Carry only the manual customizations from old generated or
initialized files into their new counterparts; do not replace generated
files wholesale with the old versions.
Preserve relevant application-specific metadata, configuration, actions,
relations, resources, charm libraries, dependencies, and custom parts.
Preserve the charm-owned paas-config.yaml when present.
Keep the generated Ubuntu 26.04 LTS contract, including:
base: ubuntu@26.04and the generated platform definitions;the
uvcharm part and generatedpyproject.tomlproject structure;the
appworkload container andapp-imageOCI resource;the
peerspeer relation with thepeersinterface;one
app-secret-keyoption of typesecret, with noapp-secret-key-idoption;the generated
paas-charm>=2.0.dev1,<3dependency and generatedcharmlibsinterface dependencies for OAuth, OpenFGA, and tracing, which replace the corresponding Charmhub-fetched libraries;a Valkey relation instead of the obsolete Redis relation.
For Flask, the lower-base flask-app workload container and
flask-app-image resource become app and app-image. For Django,
django-app and django-app-image likewise become app and
app-image. The resource-name change is separate from the workload
container rename. Keep the generated declarations and update
juju deploy --resource, juju refresh --resource, CI/CD, Terraform,
scripts, bundles, overlays, and other automation that refers to the old
names. When refreshing an existing deployment, supply the image using
--resource app-image=<image> if Juju requires the renamed resource.
Charmcraft generates the charm part as parts.charm on both contracts,
so the Rockcraft /-to-. extension-part separator change does not
apply to that generated charm part. Keep the new profile’s parts.charm
definition instead of copying a lower-base override unchanged.
Add the existing charm’s application-specific Python dependencies to the
generated pyproject.toml.
charmcraft init doesn’t create a uv.lock file, and
charmcraft pack fails without one. Generate the lock file from
charm-26-04 and commit it with the project. Regenerate it after any
dependency change:
uv lock
When carrying over custom relation handling or application code, replace
obsolete Redis integration with the generated valkey relation. The library no longer
provides the REDIS_DB_* environment variables; use the VALKEY_DB_* variables.
For more details about the generated contract and dependency migration, see the Charmcraft framework extension reference and Migrate your 12-factor charm to use the uv plugin.
Reconfigure the application secret key¶
The application secret key is now stored in a Juju application-owned secret. On upgrade a fresh key is generated, so existing sessions signed with the previous key are invalidated. Applications that use this key for session signing may sign out existing users.
To keep user-provided secret material, store it in a Juju secret and set the
app-secret-key option to the secret ID:
juju add-secret my-app-secret-key value=<secret-string>
juju grant-secret my-app-secret-key myapp
juju config myapp app-secret-key=secret:<secret id>
Update relation endpoints¶
The secret-storage peer relation is renamed to peers. Update any
tooling that references the old endpoint or interface name.
Build and refresh all artifacts¶
Ubuntu 26.04 LTS framework support currently requires the tooling enablement variables when packing:
ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=1 rockcraft pack
CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=1 charmcraft pack
juju refresh myapp --path ./myapp_amd64.charm --base ubuntu@26.04 \
--resource app-image=<registry>/<rock name>:<version>
Pass --base ubuntu@26.04 explicitly so that Juju selects the charm built for that base. For more details on changing bases, see
Change to the Ubuntu 26.04 LTS base.
After the refresh completes, verify the application with juju status and
confirm that the workload is active and the ingress and observability relations
are healthy.