> ## Documentation Index
> Fetch the complete documentation index at: https://support.lilt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Install Package

LILT ships each self-managed release as a signed set of artifacts in Amazon S3. The install package is a single tarball that contains the install scripts, the Helm charts, and the values files for one deployment flavor. This article describes the artifacts, how to verify them, and what you get when you extract one.

## Release Flavors

Every release builds two install packages from the same source. You choose a flavor by downloading the matching tarball. There is no runtime flag that switches between them.

| Flavor      | Tarball                               | Entrypoint            | Use it when                                                     |
| ----------- | ------------------------------------- | --------------------- | --------------------------------------------------------------- |
| EKS         | `on-prem-installer-eks_<hash>.tar.gz` | `install-lilt-eks.sh` | You run LILT on Amazon Elastic Kubernetes Service.              |
| On-premises | `on-prem-installer_<hash>.tar.gz`     | `install-lilt.sh`     | You run LILT on bare-metal or virtual machines that you manage. |

`<hash>` is the first eight characters of the source commit the release was built from. Both tarballs in a release share the same hash.

The two flavors differ in what infrastructure they bring with them:

* The **on-premises** flavor installs the supporting infrastructure itself: Flannel for cluster networking, MetalLB for load balancing, the local persistent-volume provisioner for storage, MySQL, and MinIO for object storage.

* The **EKS** flavor leaves that to AWS. It expects the VPC CNI, an Elastic Load Balancer, the EBS CSI driver, Amazon RDS, and Amazon S3. In their place it adds Cluster Autoscaler and External Secrets Operator, both installed by default, plus cert-manager *(optional)* and the `lilt-aws-env` Terraform module *(optional)*.

Optional here means the component ships in the tarball either way and you decide whether to use it. cert-manager is off unless you set `ENABLE_CERT_MANAGER=true`, and the Terraform module is only used if you provision your infrastructure with it. Every component the installer runs has a toggle of its own, so anything in the list can be turned off — see [Component flags](/kb/install-system-aws-eks#component-flags).

<Note>
  The EKS tarball is the only one that contains the Terraform module. If you plan to provision AWS infrastructure with Terraform, download the EKS flavor. See [Provision AWS infrastructure with Terraform](/kb/install-aws-terraform-module).
</Note>

## Download the Package

LILT gives you an S3 release URI for your version, in the form `s3://<bucket>/lilt-enterprise-<version>/`. The bucket is chosen per release when it is published, so use the URI LILT gives you rather than assuming one. Current releases are published to `lilt-self-managed-releases`; releases from before the move are in `lilt-enterprise-releases`.

<Note>
  This is LILT's distribution bucket, which is where you download from. It is unrelated to the S3 bucket LILT runs on. That one lives in your own account, is named `<PREFIX>-s3` by the Terraform module, and is set with `S3_BUCKET` in `install.env`.
</Note>

Every release uses the same layout under the release prefix:

```
lilt-enterprise-<version>/
├── install_packages/            # the two flavor tarballs and their .md5 sidecars
├── docker_images/               # container image tarballs
└── documentation/
    ├── md5sum.txt               # consolidated checksums for the whole release
    ├── image_map.tsv            # LILT application images: tag, target repo, source repo
    └── image_list.txt           # third-party images
```

Set the release URI and the flavor you want, then download:

```bash theme={null}
export RELEASE_URI="s3://<bucket>/lilt-enterprise-<version>"
export FLAVOR="on-prem-installer-eks"   # or "on-prem-installer" for on-premises

mkdir -p ~/lilt-release && cd ~/lilt-release
aws s3 cp "$RELEASE_URI/documentation/md5sum.txt" .
aws s3 sync "$RELEASE_URI/install_packages/" ./install_packages/ \
  --exclude '*' --include "${FLAVOR}_*"
```

## Verify the Package

Each tarball is published with a `.md5` sidecar that holds the checksum of the local file. The consolidated `documentation/md5sum.txt` covers every artifact in the release.

<Warning>
  Do not compare an S3 ETag against a checksum. LILT uploads these artifacts as multipart objects, so the ETag is a hash of part hashes, not the MD5 of the file. Use the published `.md5` files.
</Warning>

Verify the tarball you downloaded:

```bash theme={null}
cd ~/lilt-release/install_packages
md5sum -c "$(ls ${FLAVOR}_*.tar.gz).md5"
```

To verify everything you pulled, run `md5sum -c md5sum.txt` from the directory that holds the release tree. The file lists paths relative to the release prefix.

## Extract the Package

```bash theme={null}
mkdir -p /opt/lilt && cd /opt/lilt
tar xzf ~/lilt-release/install_packages/${FLAVOR}_*.tar.gz
```

Confirm that you extracted the flavor you expected. Only the EKS tarball contains `install-lilt-eks.sh`:

```bash theme={null}
test -f install-lilt-eks.sh && echo "EKS flavor"
test -f install-lilt.sh && echo "on-premises flavor"
```

## What the Package Contains

| Path                                       | Contents                                                                                      |
| ------------------------------------------ | --------------------------------------------------------------------------------------------- |
| `install-lilt-eks.sh` or `install-lilt.sh` | The entrypoint for the flavor. Runs each component in order.                                  |
| `install.env.example`                      | Every configuration variable the installer reads, with its default. Copy it to `install.env`. |
| `install_scripts/`                         | One `install-<component>.sh` per component, plus shared helpers and `seed-registry.sh`.       |
| `charts/`                                  | Every Helm chart the install needs, vendored at the pinned version.                           |
| `lilt/`                                    | The LILT umbrella chart, its environment overlays, and the secret seed files.                 |
| `lilt-networking/`                         | The HTTPRoute and Gateway resources that publish LILT.                                        |
| `docs/`                                    | The install guides for the flavor you downloaded.                                             |
| `uninstall-lilt.sh`                        | Ordered teardown of everything the installer created.                                         |
| `terraform-modules/lilt-aws-env/`          | EKS flavor only. The Terraform module that provisions the AWS infrastructure.                 |

<Warning>
  The charts in `charts/` are vendored as local `.tgz` archives, pinned to the versions the release was tested with, but the installer does not use them unless you tell it to. `CHART_BASE` defaults to an OCI registry that an air-gapped cluster cannot reach. To install from the charts in the tarball, point `CHART_BASE` at that directory:

  ```bash theme={null}
  # install.env
  CHART_BASE=/opt/lilt/charts
  ```

  Use an absolute path. When `CHART_BASE` is a filesystem path, the installer resolves each chart to the packaged `.tgz` in that directory and ignores the version flag, because the vendored archive already is the pinned version.

  Do not point `CHART_BASE` at a container registry mirror unless you have confirmed that every chart the release uses is present there. Mirroring only the LILT-authored charts leaves the third-party ones unresolvable.
</Warning>

## Seed Your Container Registry

The cluster pulls LILT images from a registry that you control. `install_scripts/seed-registry.sh` copies the release's images from the release tree, or straight from S3, into that registry. This is the step an air-gapped install depends on, and it is the longest step in the whole process.

The script reads `documentation/image_map.tsv` and `documentation/image_list.txt` from the release, so it always seeds exactly the images that release needs.

<Warning>
  Install [crane](https://github.com/google/go-containerregistry) before you run this. The installer does not install it, and `seed-registry.sh` stops immediately with `ERROR: crane not on PATH.` The script ships with both flavors, so this applies to on-premises and EKS alike.

  ```bash theme={null}
  curl -fsSL "https://github.com/google/go-containerregistry/releases/download/v0.22.0/go-containerregistry_Linux_x86_64.tar.gz" \
    | tar xz -C /usr/local/bin crane
  chmod +x /usr/local/bin/crane
  ```

  crane reads the usual Docker credential config, so authenticate first, for example with `aws ecr get-login-password --region <region> | crane auth login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com`.
</Warning>

### Point It at the Release

`--release` takes either the S3 release prefix or a release directory you already downloaded. Both hold the same images; they differ in how much disk you need.

| Form            | Value                                                                                                                                                    | Disk needed                                                 |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| S3 prefix       | The release URI LILT gave you, the same one used to [download the package](#download-the-package), for example `s3://<bucket>/lilt-enterprise-<version>` | One image at a time. Each is fetched, pushed, then deleted. |
| Local directory | The directory you synced the release into, for example `~/lilt-release`                                                                                  | The whole release, about 180 GB.                            |

Prefer the S3 form unless the machine has no route to S3. It needs room for the largest single image rather than the entire bundle, and it is the same URI you already have.

`--release` points at the **release**, which contains `documentation/` and `docker_images/`. It is not the extracted installer tarball, which contains the install scripts and charts.

```bash theme={null}
export RELEASE_URI="s3://<bucket>/lilt-enterprise-<version>"
export TARGET_REGISTRY="<account-id>.dkr.ecr.<region>.amazonaws.com"
```

### Preview, Then Push

Without `--apply` the script reports a plan and copies nothing. Run this first:

```bash theme={null}
sh install_scripts/seed-registry.sh \
  --release "$RELEASE_URI" \
  --registry "$TARGET_REGISTRY"
```

Each image is listed as `PUSH` or, if your registry already holds that tag, `HAVE`. When the plan looks right, add `--apply`:

```bash theme={null}
sh install_scripts/seed-registry.sh \
  --release "$RELEASE_URI" \
  --registry "$TARGET_REGISTRY" \
  --apply
```

<Note>
  Add `--path` if you set the `REGISTRY_PATH_*` variables in `install.env`. It defaults to empty, which matches the plain-ECR layout where those variables are also empty. Set one and not the other and the install pulls from a path nothing was pushed to.
</Note>

You can also drive the script from `install.env` with `ENABLE_SEED_REGISTRY`, `SEED_REGISTRY_RELEASE`, `SEED_REGISTRY_TARGET`, and `SEED_REGISTRY_APPLY`, which lets the installer run it as part of an unattended install.

The script skips images your registry already has, so a re-run after a failure resumes rather than starting over.

### Sizing the Staging Directory

`seed-registry.sh` stages each image on local disk before it pushes. A release moves roughly 180 GB in total, and the largest single image is about 47 GB.

<Warning>
  Set `SEED_REGISTRY_WORK_DIR` to a path on a real disk, and give that disk room for the largest image in the release. On Amazon Linux 2023, RHEL 9, Debian 12, and most other current distributions, `/tmp` is a tmpfs sized at half of system RAM. Staging a large image there fails with `No space left on device` while `df` shows the root volume nearly empty. The default of `/var/tmp` avoids this.
</Warning>

### Amazon ECR

Amazon ECR does not create a repository when you push to one that does not exist. `seed-registry.sh` creates each repository before its first push, which needs the `ecr:CreateRepository` permission. If your repositories are provisioned separately, set `SEED_REGISTRY_CREATE_REPOS=false`.

### Let the Cluster Pull

Seeding puts the images in your registry. The cluster still has to authenticate to pull them, and LILT relies on node-level authentication for that rather than on per-namespace pull secrets.

On EKS with ECR this is already handled: the LILT Terraform module attaches the `AmazonEC2ContainerRegistryReadOnly` policy to the node role, so every node can pull from the account's registry with no further configuration. If you provision your own cluster, grant the node role the same access. See [Install on an existing EKS cluster](/kb/install-aws-existing-cluster).

For a registry that cannot authenticate at the node level, configure the credential the way your runtime expects before you install. A pod that cannot pull sits in `ImagePullBackOff`, which names the image but not the missing credential.

## Next Steps

* [Install System (AWS EKS)](/kb/install-system-aws-eks) — configure and run the EKS install.
* [Provision AWS infrastructure with Terraform](/kb/install-aws-terraform-module) — create the cluster, database, and IAM roles with the `lilt-aws-env` module.
* [Install on an existing EKS cluster](/kb/install-aws-existing-cluster) — use infrastructure you provisioned yourself.
* [Install System (Amazon Linux 2023 or Rocky 8/9)](/kb/install-system-amazon-linux-2023-or-rocky-8-9) — the on-premises flavor.
