How to manage applications

See also: Application

This document shows how to manage applications with Juju.


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 \

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, a machine constraint (e.g., availability zone), the number of application units you want (clusterised), a space binding, a placement directive (e.g., to deploy 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).

Expand to view examples of using a placement directive to deploy to specific targets

See also: Placement directive

# Deploy to a new lxd-type container on new machine:
juju deploy mariadb --to lxd

# Deploy to a new container on existing machine 25:
juju deploy mongodb --to lxd:25

# Deploy to existing lxd-type container 3 on existing machine 24:
juju deploy nginx --to 24/lxd/3

# Deploy to zone us-east-1a on AWS:
juju deploy mysql --to zone=us-east-1a

# Dploy to a specific machine on MAAS:
juju deploy mediawiki --to node1.maas

# Deploy to a specific machine on LXD:
juju deploy mariadb --to node1.lxd

For a Kubernetes-backed cloud, a Kubernetes node can be targeted based on matching labels. The label can be either built-in or one that is user-defined and added to the node. For example:

# Deploy to a specific Kubernetes node (using either a built-in or a user-defined label):
juju deploy mariadb-k8s --to

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

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

Run an application action

See also: Action

See more: How to manage actions

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,

  • 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
    description: Admin users to create, user:pass
    is_default: true
    type: string
    value: ""
    description: turn on debugging features of mediawiki
    is_default: true
    type: boolean
    value: false
    description: URL to fetch logo from
    is_default: true
    type: string
    value: ""
    description: The name, or Title of the Wiki
    is_default: true
    type: string
    value: Please set name of wiki
    description: The server url to set "$wgServer". Useful for reverse proxies
    is_default: true
    type: string
    value: ""
    description: skin for the Wiki
    is_default: true
    type: string
    value: vector
    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.

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

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

Scale an application

See also: Scaling

Scale an application vertically

To scale an application vertically, set constraints for the machine(s) that the application’s units will be deployed on.

See more: How to manage machine constraints for an application

Scale an application horizontally

To scale an application horizontally, control the number of units.

See more: How to control the number of units

Make an application highly available

See also: High availability

  1. Find out if the charm delivering the application supports high availability natively or not. If the latter, find out what you need to do. This could mean integrating with a load balancing reverse proxy, configuring storage etc.

  2. Scale up horizontally as usual.

Expand to view an example featuring the machine charm for Wordpress

The wordpress charm supports high availability natively, so we can proceed to scale up horizontally:

juju add-unit wordpress

Expand to view an example featuring the machine charm for Mediawiki

The mediawiki charm needs to be placed behind a load balancing reverse proxy. We can do that by deploying the haproxy charm, integrating the haproxy application with wordpress, and then scaling the wordpress application up horizontally:

# Suppose you have a deployment with mediawiki and mysql and you want to scale mediawiki.
juju deploy mediawiki
juju deploy mysql

# Deploy haproxy and integrate it with your existing deployment, then expose haproxy:
juju deploy haproxy
juju integrate mediawiki:db mysql
juju integrate mediawiki haproxy
juju expose haproxy

# Get the proxy's IP address:
juju status haproxy

# Finally, scale mediawiki up horizontally 
# (since it's a machine charm, use 'add-unit') 
# by adding a few more units:
juju add-unit -n 5 mediawiki

Every time a unit is added to an application, Juju will spread out that application’s units, distributing them evenly as supported by the provider (e.g., across multiple availability zones) to best ensure high availability. So long as a cloud’s availability zones don’t all fail at once, and the charm and the charm’s application are well written (changing leaders, coordinating across units, etc.), you can rest assured that cloud downtime will not affect your application.

See more: Charmhub | wordpress, Charmhub | mediawiki, Charmhub | haproxy, How to scale an application horizontally

Integrate an application with another application

See more: How to manage relations

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           ready
wordpress/0*  active    idle   0  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

[note type=information]
To override an initial `expose` command, run the command again with the new desired specifications.

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
  exposed: true
      - ::/0

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

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

Change space bindings for an application

See also: Binding

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

Update an application

To update an application, you need to update the channel of its deployed charm.

See more: How to update a charm

Remove an application

See also: Removing things

To remove an application, run the remove-application command followed by the name of the application. 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.

As a last resort, use the --force option (in v.2.6.1).

See more: juju remove-application

Contributors: @nvinuesa , @tmihoc

There used to be a section on deploying to specific machines. This is a very common use case with enterprise workloads and it would be great to have it again. The deploy help page is super long to point people at.

There is a broken link here

I have updated containerd config but the changes are not getting pushed out the machines. Is it documented anywhere how juju/charms poll for app changes, polling frequency ?

It would be useful to add a full example on upgrading a charm to a latest version.

@camille.rodriguez1 Sorry for the late reply. In the applications doc I’ve clarified that updating an application means updating the charm, and link to the doc on managing charms: How to manage applications In the doc on managing charms I’ve added an expand box with a full example for PostgreSQL: How to manage charms

@pmatulis Sorry for the very late reply. I’ve updated that section with an expand box with examples of placement directives for various clouds.

@ameberg : Sorry for the late reply. I’m not sure I understand your question entirely, but here is what I can say: Juju will poll Charmhub once a day to check for updates. The poll will cause juju status to indicate a newer charm version is available. The user can then update the charm to that version, if they wish to. I’ve updated the doc to clarify this.