How to manage applications
See also: Application
This document shows how to manage applications with Juju.
Contents:
- Deploy an application
- View details about an application
- Manage an application’s public availability over the network
- Trust an application with a credential
- Configure an application
- Manage machine constraints for an application
- Scale an application
- Change space bindings for an application
- Upgrade an application
- Manage application integrations
- Remove an application
Deploy an application
To deploy an application from a charm on Charmhub / your local filesystem, use the deploy
command followed by the name of the charm / the path to the local .charm
file that delivers the application and, optionally, a custom application name:
juju deploy <charm | path/to/charm> <custom application name>
Example: Deploy MySQL from Charmhub using the `mysql` charm
juju deploy mysql
Example: Deploy an application from a local charm
juju deploy ./mini_ubuntu-20.04-amd64.charm
Example: Deploy an application from a local charm with a resource
If your charm’s metadata.yaml
specifies a resource, you must also explicitly pass the resource. For example:
juju deploy ./demo-api-charm_ubuntu-22.04-amd64.charm --resource \
demo-server-image=ghcr.io/beliaev-maksim/api_demo_server:0.0.9
Depending on the cloud substrate that your controller is running on, the above command will allocate a machine (physical, virtual, LXD container) or a Kubernetes pod and then proceed to deploy and configure the application.
Depending on your use case, you may alternatively opt to provision a set of machines in advance via the juju add-machine
command.
In this case, when running the above juju deploy
command, Juju will detect that the model contains machines with no applications assigned to them and automatically deploy the application to one of those machines instead of spinning up a new machine.
The command also allows you to add another argument to specify a custom name (alias) for your deployed application. You can also take advantage of the rich set of flags to specify a charm channel or revision, a machine base (e.g., , a machine constraint (e.g., availability zone), the number of application units you want (clusterised, a space binding, a placement directive (e.g., to depoy to a LXD container), a specific storage instance, a specific machine, etc., and even to trust the application with the current credential – in case the application requires access to the backing cloud in order to fulfil its purpose (e.g., storage-related tasks).
See more:
juju deploy
View details about an application
To view more information about a deployed application, run the show-application
command followed by the application name or alias:
juju show-application <application name or alias >
By specifying various flags you can also specify a model, or an output format or file.
See more:
juju show-application
Manage an application’s public availability over the network
Expose an application. By default, once an application is deployed, it is only reachable by other applications in the same Juju model. However, if the particular deployment use case requires for the application to be reachable by Internet traffic (e.g. a web server, Wordpress installation etc.), Juju needs to tweak the backing cloud’s firewall rules to allow Internet traffic to reach the application. This is done with the juju expose
command.
After running a juju expose
command, any ports opened by the application’s charmed operator will become accessible by any public or private IP address.
Assuming the wordpress
application has been deployed (and a relation has been made to the deployed database mariadb
), the following command can be used to expose the application outside the Juju model:
juju expose wordpress
When running juju status
, its output will not only indicate whether an application is exposed or not, but also the public address that can be used to access each exposed application:
App Version Status Scale Charm Rev Exposed Message
mariadb 10.1.36 active 1 mariadb 7 no
wordpress active 1 wordpress 5 yes exposed
Unit Workload Agent Machine Public address Ports Message
mariadb/0* active idle 1 54.147.127.19 ready
wordpress/0* active idle 0 54.224.246.234 80/tcp
The command also has flags that allow you to expose just specific endpoints of the application, or to make the application available to only specific CIDRs or spaces. For example:
juju expose percona-cluster --endpoints db-admin --to-cidrs 10.0.0.0/24
See more:
juju expose
Inspect exposure.
To view details of how the application has been exposed, run the show-application
command. Sample session:
$ juju show-application percona-cluster
percona-cluster:
...
exposed: true
exposed-endpoints:
"":
expose-to-cidrs:
- 0.0.0.0/0
- ::/0
db-admin:
expose-to-cidrs:
- 192.168.0.0/24
- 192.168.1.0/24
...
See more:
juju show-application
Unexpose an application. The juju unexpose
command can be used to undo the firewall changes and once again only allow the application to be accessed by applications in the same Juju model:
juju unexpose wordpress
You can again choose to unexpose just certain endpoints of the application. For example, running juju unexpose percona-cluster --endpoints db-admin
will block access to any port ranges opened for the db-admin
endpoint but still allow access to ports opened for all other endpoints:
juju unexpose percona-cluster --endpoints db-admin
See more:
juju unexpose
Trust an application with a credential
Some applications may require access to the backing cloud in order to fulfil their purpose (e.g., storage-related tasks). In such cases, the remote credential associated with the current model would need to be shared with the application. When the Juju administrator allows this to occur the application is said to be trusted. An application can be trusted during deployment or after deployment.
Trust an application during deployment. To trust an application during deployment, run the deploy
command with the --trust
flag. E.g., below we trust
juju deploy --trust ...
See more:
juju deploy --trust
Trust an application after deployment. To trust an application after deployment, use the trust
command:
juju trust <application>
By specifying various flags, you can also use this command to remove trust from an application, or to give an application deployed on a Kubernetes model access to the full Kubernetes cluster, etc.
See more:
juju trust
Configure an application
See also: Application configuration
Most charms ship with a sensible default configuration out of the box. However, for some use cases, it may be desirable or necessary to override the default application configuration options.
Get values. The way to view the existing configuration for an application depends on whether the application has been deployed or not.
-
To view the configuration options of an application that you have not yet deployed,
- if its charm is on Charmhub, inspect its Configurations page; for example: Charmhub | Deploy Mediawiki using Charmhub - The Open Operator Collection.
- if its charm is local on your machine, inspect its
config.yaml
file.
-
To view the configuration values for a deployed application, run the
config
command followed by the name of the application. For example:
juju config mediawiki
Expand to view a sample output
application: mediawiki
charm: mediawiki
settings:
admins:
description: Admin users to create, user:pass
is_default: true
type: string
value: ""
debug:
description: turn on debugging features of mediawiki
is_default: true
type: boolean
value: false
logo:
description: URL to fetch logo from
is_default: true
type: string
value: ""
name:
description: The name, or Title of the Wiki
is_default: true
type: string
value: Please set name of wiki
server_address:
description: The server url to set "$wgServer". Useful for reverse proxies
is_default: true
type: string
value: ""
skin:
description: skin for the Wiki
is_default: true
type: string
value: vector
use_suffix:
description: If we should put '/mediawiki' suffix on the url
is_default: true
type: boolean
value: true
See more:
juju config
Set values. You can set configuration values for an application during deployment or later.
- To set configuration values for an application during deployment, run the
deploy
command with the--config
flag followed by the relevant key=value pair. For example, themediawiki
charm allows users to configure thename
of the deployed application; below, we set it tomy media wiki
:
juju deploy mediawiki --config name='my media wiki'
To pass multiple values, you can repeat the flag or store the values into a config file and pass that as an argument.
See more:
juju deploy -- config
- To set configuration values for an application post deployment, run the
config
command followed by the name of the application and the relevant (list of space-separated) key=value pair(s). For example, themediawiki
charm provides aname
and askin
configuration key; below we set both:
juju config mediawiki name='Juju Wiki' skin=monoblock
By exploring various options you can also use this command to pass the pairs from a YAML file or to reset the keys to their default values.
See more:
juju config
Manage machine constraints for an application
See also: Constraint
Set values. You can set machine constraint values for an application during deployment or later.
- To set machine constraints for an application during deployment, run the
deploy
command with the--constraints
flag followed by the relevant key-value pair or a quotes-enclosed list of key-value pairs. For example, to deploy MySQL on a machine that has at least 6 GiB of memory and 2 CPUs:
juju deploy mysql --constraints "mem=6G cores=2"
Expand to see more examples
Assuming a LXD cloud, to deploy PostgreSQL with a specific amount of CPUs and memory, you can use a combination of the instance-type
and mem
constraints, as below – instance-type=c5.large
maps to 2 CPUs and 4 GiB, but mem
overrides the latter, such that the result is a machine with 2 CPUs and 3.5 GiB of memory.
juju deploy postgresql --constraints "instance-type=c5.large mem=3.5G"
To deploy Zookeeper to a new LXD container (on a new machine) limited to 5 GiB of memory and 2 CPUs, execute:
juju deploy zookeeper --constraints "mem=5G cores=2" --to lxd
To deploy two units of Redis across two AWS availability zones, run:
juju deploy redis -n 2 --constraints zones=us-east-1a,us-east-1d
See more:
juju deploy --constraints
If you want to use the image-id
constraint with juju deploy
:
You must also use the --base
flag of the command. The base specified via --base
will be used to determine the charm revision deployed on the machine created with the image-id
constraint.
See more:
juju deploy --base
- To set machine constraints for an application after deployment, run the
set-constraints
command followed by the desired ("-enclosed list of) key-value pair(s), as below. This will affect any future units you may add to the application.
juju set-constraints mariadb cores=2
Pro tip: To reset a constraint key to its default value, run the command with the value part empty (e.g., juju deploy apache2 --constraints mem=
).
See more:
juju set-constraints
Get values. To view an application’s current constraints, use the constraints
command:
juju constraints mariadb
See more:
juju constraints
Scale an application
The capability of a service to adjust its resource footprint to a level appropriate for fulfilling client demands placed upon it is known as scalability. Scaling vertically affects the resources of existing machines (memory, CPU, disk space) whereas scaling horizontally, in Juju, involves the number of application units available.
Units are not always synonymous with machines however. Multiple units can be placed onto a single machine (co-location) and still be considered horizontal scaling if sufficient resources are present on the machine.
This page will describe how rudimentary scaling works with Juju as well as mention some less common situations.
Scaling up
In the context of Juju, scaling up means increasing the number of application units and always involves the add-unit
command. The exception is for a Kubernetes-backed cloud where the scale-application
command is used.
Closely resembling scaling up is the addition of a machine devoid of a unit. This is accomplished via the add-machine
command:
juju add-machine
A machine provisioned via the add-machine
command that does not yet house an application unit will, by default, be used for any subsequent application deployment (via the deploy
command).
Scaling up behind a load balancer
In many cases simply adding more units will not make an application scale properly. A load balancer or proxy is often required.
Below is an example of deploying a load balanced MediaWiki application by placing the HAProxy application in front of it:
juju deploy mediawiki
juju deploy mysql
juju deploy haproxy
juju integrate mediawiki:db mysql
juju integrate mediawiki haproxy
juju expose haproxy
When a relation is made between MediaWiki and HAProxy, the latter will be configured to load balance requests to the MediaWiki application. This means that client requests should go to the HAProxy instance. To get the proxy’s IP address run the following:
juju status haproxy
You can now scale up the MediaWiki application behind the proxy as you see fit. To add five more units (with each running in its own machine):
juju add-unit -n 5 mediawiki
Scaling up within a Kubernetes model
To scale a Kubernetes application up or down, run the scale-application
command followed by the name of the application and the desired – higher or lower – number of units. For example, below we scale mediawiki
to 3 units:
juju scale-application mediawiki 3
Scaling up using a charm with built-in scaling
Some charms have scaling built-in where scaling up really is as simple as adding more units.
An example of this is the WordPress charm:
juju deploy mysql
juju deploy wordpress
juju integrate mysql wordpress
juju expose wordpress
To scale, just add more units:
juju add-unit wordpress
This will cause a new unit (and machine) to be spawned and configured to work alongside the existing one.
By default, add-unit
will add a single unit. To request multiple units the -n
option is needed. For example, to further scale up our current application by adding 100 units of MySQL one would run:
juju add-unit -n 100 mysql
Scaling up through co-location
Like the deploy
command, it is possible to co-locate multiple applications on a single machine. This is done via the --to
option.
For example, to add a unit of MySQL to the machine with an ID of ‘23’:
juju add-unit mysql --to 23
To add a unit of the same application to existing LXC container ‘3’ residing on host machine ‘24’:
juju add-unit mysql --to 24/lxc/3
Not all applications will happily co-exist (usually due to conflicting configuration files). It is therefore generally safer to place units on dedicated machines or containers.
Here we add a unit of MySQL to a new LXC container on host machine 25:
juju add-unit mysql --to lxc:25
Scaling up by specifying new constraints
It is possible to scale out an application by adding a unit with different hardware requirements (constraints) than those set with the initial deployment. The default behaviour is for new units to use the same, if any, constraints.
This is done by indirectly creating a machine with a constraint and then adding the unit to it. For example, to add a unit with 16 GiB of memory to the MySQL application if the initial deployment was only, say, 4 GiB:
juju add-machine --constraints mem=16G
juju machines
juju add-unit mysql --to 3
Above, it is presumed that juju machines
informed us that the new machine was assigned an ID of ‘3’.
Read the Using constraints page for details on constraints.
Scaling down
In the context of Juju, scaling down means decreasing the number of application units and always involves the remove-unit
command. The exception is for a Kubernetes-backed cloud where the scale-application
command is used.
Closely resembling scaling down is the direct removal of a machine. This is therefore also covered here and is accomplished via the remove-machine
command.
To scale down the MediaWiki application by removing a specific unit:
juju remove-unit mediawiki/1
Note that if this is the only unit running on the underlying machine, the machine will also be removed.
A machine cannot be manually removed if any of the following is true:
- it houses a unit
- it is being used as the only controller
- it is hosting Juju-managed containers (KVM guests or LXD containers)
For example, to remove a machine with ID of ‘6’:
juju remove-machine 6
For more information on removing applications and machines, see the Removing things page.
Scaling down within a Kubernetes model
To scale down while in a Kubernetes model the total number of desired units for the application is simply stated. Here we want a total of two units:
juju scale-application mediawiki 2
Charm Implementation
When developing charms using the Operator Framework, scaling is handled via relation events - specifically through peer relations. For more information see:
Change space bindings for an application
To change space bindings for a deployed application, run the bind
command followed by the name of the application followed by the name of a default space and/or key-value pairs consisting of specific application endpoints and the space you want to bind them to.
For example, to update the default binding for the application and automatically update all existing endpoint bindings that were referencing the old default, pass the name of the new default space:
juju bind <application> <new default space>
Or, to bind individual endpoints to a space, pass key-value pairs of specific application endpoints and the specific space you want to bind them to:
juju bind <application> endpoint-1=space-1 endpoint-2=space-2
Finally, to both update the default space and individual endpoints in one go, pass both:
juju bind <application> new-default endpoint-1=space-1
See more:
juju bind
Upgrade an application
See also: Upgrading things, Application, Juju SDK | Channel, Juju SDK | Upgrading a charm
To upgrade an application, you need to upgrade the channel of its deployed charm.
This always involves the refresh
command, but the exact way to use it differs a little bit depending on whether you are dealing with a Charmhub charm or rather a local charm.
Contents:
Upgrade a Charmhub charm
See also:
juju status
,juju info
,juju refresh
Run status
to find the current channel.
Run info
followed by the charm name to find out all the available channels.
Finally, run refresh
followed by the charm name and the channel
option to change the charm to the desired channel.
Upgrade a local charm
See also:
juju refresh
To upgrade a local charm, run the refresh
command followed by the name of the charm and the local path to the charm:
juju refresh juju-test --path ./path/to/juju-test
The command offers many other options, for example, the possibility to replace a charm completely with another charm by using the --switch
option followed by a different path (a process known as ‘crossgrading’). (Note: --path
and --switch
are mutually exclusive. Use --switch
if you want to replace your existing charm with a completely new charm.)
Remove an application
See also: Removing things reference
Contents:
Remove an application
An application can be removed with:
juju remove-application <application-name>
For example:
juju remove-application apache2
This will remove all of the application’s units. All associated machines will also be removed providing they are not hosting containers or another application’s units.
If persistent storage is in use by the application it will be detached and left in the model. However, the --destroy-storage
option can be used to instruct Juju to destroy the storage once detached.
Removing an application which has relations with another application will terminate that relation. This may adversely affect the other application. See section Removing relations below for how to selectively remove relations.
As a last resort, use the --force
option (in v.2.6.1
).
Manage application integrations
Remove a charm or a charm bundle
A charmed operator is the means by which an application is installed. There is therefore no method to remove a charm. Removal should be done at either the unit or application level.
A bundle is not a logical entity that can be removed. Once a bundle is deployed, applications can evolve in numerous ways that are not tracked and associated with the original bundle. For complex deployments, the recommendation is to deploy on a per-model basis so the removal of a complex deployment becomes equivalent to the removal of a model.
Remove an application offer
An application offer (for a cross model relation) is removed with:
juju remove-offer <offer url>
For example:
juju remove-offer hosted-mysql
The attempt will fail if a relation has already been made to the offer. To override this behaviour the --force
option is required, in which case the relation is also removed.
Note that if the offer does not reside in the current model then the full URL must be used:
juju remove-offer prod.model/hosted-mysql
Contributors: @nvinuesa
Last updated 21 hours ago.