Enterprise Store

Platform:

Ubuntu
24.04
Channel Revision Published Runs on
latest/stable 7 16 Oct 2026
Ubuntu 24.04
latest/edge 8 17 Oct 2026
Ubuntu 24.04
juju deploy enterprise-store

Deploying in airgapped mode

This page describes how to deploy the enterprise-store charm in offline / airgapped mode, in which nothing reaches the internet. The snaps that make up the enterprise-store are shipped in through the store-bundle resource, and blob storage is provided by an S3 backend via the s3-integrator charm.

For a deployment that proxies the global Snap Store, see the Proxy mode deploy guide instead.

Offline mode requires two things in addition to a proxy-mode deployment:

  • The store-bundle resource, containing the snaps to install.
  • The offline config set to true
  • The s3-credentials relation to an s3-integrator, providing blob storage. The unit stays in BlockedStatus until this relation is established.

Prerequisites

Controller

A Juju controller on a machine cloud (for example LXD) is required:

sudo snap install juju
sudo snap install lxd
lxd init --auto
juju bootstrap localhost <controller_name>

PostgreSQL

The charm requires a PostgreSQL database over the postgresql_client interface. The enterprise-store needs the btree_gist extension. The charm requests the superuser role and attempts to provision the extension itself, but it is recommended to also enable it explicitly on the PostgreSQL charm so the extension is available regardless of role handling:

juju config postgresql plugin_btree_gist_enable=true

The offline store bundle

Everything needed for the airgapped install ships in a single tarball, offline-snap-store.tar.gz, produced by registering the store with the store-admin snap using the --offline flag:

store-admin register https://offline.example.com --offline

When extracted, the tarball contains an offline-snap-store/ directory holding:

  • snapd_*.snap, core22_*.snap and enterprise-store_*.snap
  • a matching *.assert file for each of those snaps
  • proxy.assert - the store assertion, applied on first bootstrap only
  • registration_bundle.b64 - the base64 registration bundle for the registration_bundle config option

This single tarball is used in two different places, described below.

As the store-bundle resource

Attach the tarball to the charm as-is, as the store-bundle resource. All three snaps are installed together whenever a new tarball is attached (because enterprise-store depends on core22), but the store assertion is applied exactly once. Updating the snaps later therefore never recreates the store, and update tarballs may omit proxy.assert.

Attaching can be done at deploy time with --resource (see the deploy sections below), or on an already-deployed charm with:

juju attach-resource enterprise-store store-bundle=./offline-snap-store.tar.gz

As the registration_bundle config option

The registration_bundle config value is not the tarball itself but the registration_bundle.b64 file contained inside it, which must first be extracted:

tar xzf offline-snap-store.tar.gz offline-snap-store/registration_bundle.b64

Once extracted, supply the contents of that file to the charm through the registration_bundle config option, either during deployment (via the Juju bundle or Terraform config shown below) or afterwards on the CLI:

juju config enterprise-store \
    registration_bundle="$(cat offline-snap-store/registration_bundle.b64)"

S3 storage setup

The s3-integrator needs credentials and connection details for your S3 endpoint (for example MinIO). Credentials are provided through a Juju secret:

juju add-secret s3-creds access-key="<access-key>" secret-key="<secret-key>"
juju grant-secret s3-creds s3-integrator
juju config s3-integrator \
    credentials=secret:<secret-id> \
    endpoint=<s3-endpoint> \
    bucket=<bucket-name>

The charm maps the s3-integrator connection info onto the enterprise-store snap configuration as follows (the same bucket is used for both the scanned and unscanned containers, and the charm sets proxy.storage.backend to s3):

s3-integrator field enterprise-store snap config
access-key proxy.storage.s3.access-key-id
secret-key proxy.storage.s3.secret-access-key
bucket proxy.storage.s3.unscanned-container-name
bucket proxy.storage.s3.scanned-container-name
endpoint proxy.storage.s3.server-url
region proxy.storage.s3.region
s3-uri-style proxy.storage.s3.use-path-style

Deploy with the Juju CLI

juju deploy postgresql --channel 14/stable
juju config postgresql plugin_btree_gist_enable=true
juju deploy enterprise-store --channel stable \
    --config offline=true \
    --resource store-bundle=./offline-snap-store.tar.gz
juju deploy s3-integrator --channel 2/stable
juju integrate postgresql:database enterprise-store:database
juju integrate s3-integrator enterprise-store:s3-credentials
juju config enterprise-store \
    registration_bundle="$(cat offline-snap-store/registration_bundle.b64)"

If the charm is already deployed, a new bundle can be attached (and updated later) with:

juju attach-resource enterprise-store store-bundle=./offline-snap-store.tar.gz

Configure the s3-integrator credentials and connection details as shown in the S3 storage setup section.

Deploy with a Juju bundle

applications:
  postgresql:
    charm: postgresql
    channel: 14/stable
    num_units: 1
    options:
      plugin_btree_gist_enable: true
  s3-integrator:
    charm: s3-integrator
    channel: 2/stable
    num_units: 1
  enterprise-store:
    charm: /path/to/charm
    num_units: 3
    options:
      offline: true
      registration_bundle: include-file://path/to/registration_bundle.b64
    resources:
      store-bundle: ./offline-snap-store.tar.gz

relations:
- - postgresql:database
  - enterprise-store:database
- - s3-integrator
  - enterprise-store:s3-credentials

With the above example it is assumed that offline-snap-store.tar.gz is available in the current directory.

Deploy with Terraform

The Juju Terraform provider cannot deploy a purely local .charm using the most current release (v2.3.0). Without this offline deployments are not possible using terraform. This functionality may be added at some point at which point the information would be detailed in the provider documentation

High availability and TLS

For a highly available deployment (multiple units fronted by haproxy) and for TLS termination options, see the High availability deploy guide.