# Cannot install plugins even with jenkins-version flag specified

**URL:** <https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909>\
**Category:** Using Jenkins\
**Tags:** question, docker\
**Created:** [August 6, 2024, 12:37am UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909 "2024-08-06T00:37:20Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![brsolomon-deloitte](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/brsolomon-deloitte/32/5068_2.png) [@brsolomon-deloitte](https://community.jenkins.io/u/brsolomon-deloitte)\
**Post date:** [August 6, 2024, 12:37am UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/1 "2024-08-06T00:37:20Z")

</div>

We are upgrading from Jenkins (containerized, running on Amazon ECS):

- from: `jenkins/jenkins:2.346.3-lts-jdk8`

- to: `jenkins/jenkins:2.452.3-lts-jdk17`.

- Our existing Jenkins controller has many plugins installed.

Currently we are making a simple attempt to mimic this upgrade by:

- Running a `jenkins/jenkins:2.346.3-lts-jdk8` with a `jenkins_home` volume, and installing some plugins
- Stopping the container
- Starting a `jenkins/jenkins:2.452.3-lts-jdk17` and pointing it to the same volume

However, even when using `--jenkins-version 2.346.3`, the plugins fail to install with many error similiar to:

```plaintext
package-name (version) requires a greater version of Jenkins (2.387.3) than 2.346.3

```

A `Dockerfile.old` to reproduce this:

```Dockerfile
FROM jenkins/jenkins:2.346.3-lts-jdk8

ENV JENKINS_VERSION=2.346.3
RUN set -eux \
    && jenkins-plugin-cli \
        --jenkins-version 2.346.3 \
        --verbose \
        --plugins \
            ws-cleanup:0.43 \
            htmlpublisher:1.31

```

Shown above are the current versions of two plugins in use by our actual Jenkins controller - so we expect them to successfully install for a Jenkins image using the same base image with same plugin versions. This is key in our ability to test and experiment with the upgrade.

```bash
docker build -f Dockerfile.old -t old-jenkins .

```

**How can we succesfully install (any) plugins into the `2.346.3-lts-jdk8` image?**

---

<div class="post-metadata">

**Author:** ![brsolomon-deloitte](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/brsolomon-deloitte/32/5068_2.png) [@brsolomon-deloitte](https://community.jenkins.io/u/brsolomon-deloitte)\
**Post date:** [August 6, 2024, 12:50am UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/2 "2024-08-06T00:50:02Z")

</div>

Also tried the format `artifact:version:url` as suggested by the `jenkins-plugin-cli` docs. Same error.

```Dockerfile
FROM jenkins/jenkins:2.346.3-lts-jdk8

ENV JENKINS_VERSION=2.346.3
RUN set -eux \
    && jenkins-plugin-cli \
        --jenkins-version 2.346.3 \
        --verbose \
        --plugins \
            'ws-cleanup:0.43:https://updates.jenkins.io/download/plugins/ws-cleanup/0.43/ws-cleanup.hpi' \
            'htmlpublisher:1.31:https://updates.jenkins.io/download/plugins/htmlpublisher/1.31/htmlpublisher.hpi'

```

It appears that the failure occurs because `jenkins-plugin-cli` only obeys this versioning constraint for the named plugins and not for their dependencies.

---

<div class="post-metadata">

**Author:** ![brsolomon-deloitte](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/brsolomon-deloitte/32/5068_2.png) [@brsolomon-deloitte](https://community.jenkins.io/u/brsolomon-deloitte)\
**Post date:** [August 6, 2024, 12:53am UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/3 "2024-08-06T00:53:33Z")

</div>

Also occurs with `--plugin-file`:

```bash
cat << EOF > jenkins-plugins.yaml
plugins:
  - artifactId: htmlpublisher
    source:
      version: 1.31
  - artifactId: ws-cleanup
    source:
      version: 0.43
EOF

```

```Dockerfile
FROM jenkins/jenkins:2.346.3-lts-jdk8

ENV JENKINS_VERSION=2.346.3
COPY jenkins-plugins.yaml /tmp
RUN set -eux \
    && jenkins-plugin-cli \
        --jenkins-version 2.346.3 \
        --verbose \
        --plugin-file /tmp/jenkins-plugins.yaml

```

---

<div class="post-metadata">

**Author:** ![brsolomon-deloitte](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/brsolomon-deloitte/32/5068_2.png) [@brsolomon-deloitte](https://community.jenkins.io/u/brsolomon-deloitte)\
**Post date:** [August 6, 2024, 1:03am UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/4 "2024-08-06T01:03:16Z")

</div>

On top of this reported issue: more documentation would be appreciated over the recommended way to upgrade plugins during a Jenkins version upgrade.

The documentation at [Upgrading to Java 11](https://www.jenkins.io/doc/book/platform-information/upgrade-java-to-11/) states “it is important to upgrade all plugins” [as a final step after the Jenkins/Java upgrade].

Is the idea here that the new Jenkins container, re-using the existing volume for JENKINS\_HOME, should start with ‘broken’ plugins and then upgrade them in-place to versions that are compatible with the new Jenkins version? Or, should the plugins directory be wiped first followed by a clean install? More specificity in documentation around this issue would be nice.

---

<div class="post-metadata">

**Author:** ![MarkEWaite](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/markewaite/32/20_2.png) [@MarkEWaite](https://community.jenkins.io/u/MarkEWaite)\
**Post date:** [August 6, 2024, 11:47am UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/5 "2024-08-06T11:47:27Z")

</div>

> [@brsolomon-deloitte](#):
>
> A `Dockerfile.old` to reproduce this:
> 
> ```auto
> FROM jenkins/jenkins:2.346.3-lts-jdk8
> 
> ENV JENKINS_VERSION=2.346.3
> RUN set -eux \
> && jenkins-plugin-cli \
> --jenkins-version 2.346.3 \
> --verbose \
> --plugins \
> ws-cleanup:0.43 \
> htmlpublisher:1.31
> 
> ```
> 
> Shown above are the current versions of two plugins in use by our actual Jenkins controller - so we expect them to successfully install for a Jenkins image using the same base image with same plugin versions. This is key in our ability to test and experiment with the upgrade.
> 
> ```auto
> docker build -f Dockerfile.old -t old-jenkins .
> 
> ```
> 
> **How can we succesfully install (any) plugins into the `2.346.3-lts-jdk8` image?**

Your technique is a very good technique, but it needs a further refinement.

[Jenkins 2.346.3](https://www.jenkins.io/changelog-stable/2.346.3/) is two years old. The Jenkins update center provides plugin version support information for Jenkins releases from the last 12 months. The [update center documentation](https://updates.jenkins.io/#version-specific-update-sites) says:

> Jenkins weekly and LTS releases up to a year old are supported; anything older will receive update metadata for the oldest supported releases.

Based on that, your container image that represents the current state of your Jenkins controller needs a definition of **all the plugins to install and their versions**. You can generate that list from “Manage Jenkins” → “Script Console” with the script that is available in [“How to report an issue”](https://www.jenkins.io/participate/report-issue/#what-information-to-provide-for-environment-and-description). That script is:

```groovy
Jenkins.instance.pluginManager.plugins
    .collect()
    .sort { it.getShortName() }
    .each {
        plugin -> println("${plugin.getShortName()}:${plugin.getVersion()}")
    }
return

```

The output of that script can be used in a [`plugins.txt` file](https://github.com/MarkEWaite/docker-lfs/blob/6f299978ac02224327b6e34925391d15f4e86ea0/plugins.txt) or you can list the plugin names and versions on the command line as you’ve done in your example. Refer to [“Preinstalling plugins”](https://github.com/jenkinsci/docker?tab=readme-ov-file#preinstalling-plugins) in the container documentation for more details.

---

<div class="post-metadata">

**Author:** ![brsolomon-deloitte](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/brsolomon-deloitte/32/5068_2.png) [@brsolomon-deloitte](https://community.jenkins.io/u/brsolomon-deloitte)\
**Post date:** [August 6, 2024, 12:57pm UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/6 "2024-08-06T12:57:34Z")

</div>

Thanks @MarkEWaite ! Specifying the full plugins.txt with pinned versions of dependencies indeed does the trick. I’m now able to build and run with the existing (old) plugins installed.

So, now we are faced with upgrading to `jenkins/jenkins:2.452.3-lts-jdk17`.

What is not entirely clear to me from the Jenkins docs is, **what is the recommended upgrade procedure for upgrading plugins, as part of a large Jenkins/JDK version upgrade such as this one?**

Should we _remove_ the existing `plugins/` directory from the currently-used `jenkins_home` volume prior to upgrade?

To reproduce this situation - create `Dockerfile.old`:

```Dockerfile
# Dockerfile.old
FROM jenkins/jenkins:2.346.3-lts-jdk8

# plugins.old.txt contains dump of full plugin:version
# export from Jenkins Script Console
COPY plugins.old.txt /tmp
RUN set -eux \
    && jenkins-plugin-cli \
        --verbose \
        --plugin-file /tmp/plugins.old.txt \
    && mkdir -pv ${JENKINS_HOME}/plugins \
    && cp -r -p \
        /usr/share/jenkins/ref/plugins/. \
        ${JENKINS_HOME}/plugins/.

```

Build and run as:

```bash
docker build -f Dockerfile.old -t old-jenkins .
docker volume create jenkins_home
docker run -d -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  --name jenkins \
  old-jenkins

```

This will provide a Jenkins 2.346.3 controller running on JDK 8 with the working (old) plugins installed.

Now we are faced with running a new container based on `jenkins/jenkins:2.452.3-jdk17` that uses a mount for the existing `jenkins_home` volume.

For instance,

```bash
docker container stop jenkins
docker container rm jenkins

```

Now, `cp plugins.old.txt plugins.new.txt`, and remove the pinned `:version` specifiers from `plugins.new.txt` to allow the versions to float to the latest.

Then create create `Dockerfile.new`:

```Dockerfile
# Dockerfile.new
FROM jenkins/jenkins:2.452.3-lts-jdk17

COPY plugins.new.txt /tmp
RUN set -eux \
    && jenkins-plugin-cli \
        --verbose \
        --plugin-file /tmp/plugins.new.txt \
    && mkdir -pv ${JENKINS_HOME}/plugins \
    && cp -r -p \
        /usr/share/jenkins/ref/plugins/. \
        ${JENKINS_HOME}/plugins/.

```

Build and run as:

```bash
docker build -f Dockerfile.new -t new-jenkins .
docker run -d -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  --name jenkins \
  new-jenkins

```

Then, `docker logs jenkins` will show many errors such as the following:

```plaintext
Failed Loading plugin Mina SSHD API :: Core v2.12.1-101.v85b_e08b_780dd (mina-sshd-api-core)
Update required: SSH Credentials Plugin (ssh-credentials 305.v8f4381501156) to be updated to 326.v7fcb_a_ef6194b_ or higher

```

These errors make sense since the `plugins/` directory from `jenkins_home` Docker volume _eclipses_ the `plugins/` that are copied to `${JENKINS_HOME}/plugins/` as part of the declarative Docker image build process. In other words, the plugins that we attempt to pre-install into the new image are overridden by the existing old plugins – and the old plugins raise errors since they are incompatible with the new Jenkins version.

---

<div class="post-metadata">

**Author:** ![MarkEWaite](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/markewaite/32/20_2.png) [@MarkEWaite](https://community.jenkins.io/u/MarkEWaite)\
**Post date:** [August 6, 2024, 1:27pm UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/7 "2024-08-06T13:27:54Z")

</div>

I believe that you can use the concept of an “override” to force the updated plugin versions to replace the existing plugin versions on startup. The [container image documentation](https://github.com/jenkinsci/docker?tab=readme-ov-file#usage-1) says:

> When the Jenkins container starts, it will check `JENKINS_HOME` has this reference content, and copy them there if required. It will not override such files, so if you upgraded some plugins from UI they won’t be reverted on next start.
> 
> In case you _do_ want to override, append ‘.override’ to the name of the reference file. E.g. a file named `/usr/share/jenkins/ref/config.xml.override` will overwrite an existing `config.xml` file in JENKINS\_HOME.

There is also a [pending pull request](https://github.com/jenkinsci/docker/pull/1538) to the container image documentation that might offer some additional insights

---

<div class="post-metadata">

**Author:** ![brsolomon-deloitte](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/brsolomon-deloitte/32/5068_2.png) [@brsolomon-deloitte](https://community.jenkins.io/u/brsolomon-deloitte)\
**Post date:** [August 6, 2024, 1:53pm UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/8 "2024-08-06T13:53:25Z")

</div>

Not quite sure if I’m following. Would this suggest adding a `.override` extension to each file, recursively, under `/usr/share/jenkins/ref/plugins/`?

Here is what we have currently, which, without extensive testing, seems to be working:

Step 1 - mimic the existing Jenkins with volume and outdated plugins:

```bash
docker volume create jenkins_home
docker run -d -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home --name jenkins old-jenkins

```

Perform initial admin login to jenkins, create user, verify outdated plugins are installed.

Step 2 - _remove_ existing plugins directory from volume.

```bash
docker container stop jenkins
docker run -it --rm \
  -v jenkins_home:/var/jenkins_home \
  --name shell \
  alpine
# and rm -rf /var/jenkins_home/plugins

```

Step 3 - run new Jenkins

```bash
docker container rm jenkins
docker run -d -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home --name jenkins new-jenkins

```

Step 4 - verify that new plugins are installed at localhost:8080.

---

<div class="post-metadata">

**Author:** ![MarkEWaite](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/markewaite/32/20_2.png) [@MarkEWaite](https://community.jenkins.io/u/MarkEWaite)\
**Post date:** [August 6, 2024, 1:59pm UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/9 "2024-08-06T13:59:59Z")

</div>

> [@brsolomon-deloitte](#):
>
> Not quite sure if I’m following. Would this suggest adding a `.override` extension to each file, recursively, under `/usr/share/jenkins/ref/plugins/`?

Yes, that’s what it is suggesting. That makes it clear that you intend to overwrite existing files during container startup.

---

<div class="post-metadata">

**Author:** ![brsolomon-deloitte](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/brsolomon-deloitte/32/5068_2.png) [@brsolomon-deloitte](https://community.jenkins.io/u/brsolomon-deloitte)\
**Post date:** [August 6, 2024, 2:06pm UTC](https://community.jenkins.io/t/cannot-install-plugins-even-with-jenkins-version-flag-specified/17909/10 "2024-08-06T14:06:49Z")

</div>

Okay, thanks.

I see that the Helm chart offers an [`overwritePlugins` flag](https://github.com/helm/charts/pull/11231). It would be nice to mimic this functionality for non-K8s deployments of containerized Jenkins - for instance, through use of an environment variable or something else, which `jenkins.sh` ENTRYPOINT picks up and knows to overwrite existing plugins on the volume, with those sitting in /usr/share/jenkins/ref/plugins/ that have been installed as part of the image build process.

For now, we are going to proceed with the intermediate step of `rm -rf plugins/*` from the volume, as is done by the K8s deployment, prior to startup of the new container.
