# Help deploying older versions of Discourse

**URL:** https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409
**Category:** Self-hosting
**Created:** [March 20, 2026, 8:37am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409 "2026-03-20T08:37:11Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 20, 2026, 8:37am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/1 "2026-03-20T08:37:11Z")

</div>

There should be an error here, I tried to pull `v3.6.0.beta2` via a tag, but encountered the following error:

```plaintext
FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && sudo -H -E -u discourse bash -c '
  set -o errexit
  git fetch --tags --prune-tags --prune --force origin
  if [[$(git symbolic-ref --short HEAD) == v3.6.0.beta2]] ; then
      git pull
  else
      git -c advice.detachedHead=false checkout v3.6.0.beta2
  fi
' failed with return #<Process::Status: pid 146 exit 128>
Location of failure: /usr/local/lib/ruby/gems/3.4.0/gems/pups-1.4.0/lib/pups/exec_command.rb:138:in `Pups::ExecCommand#spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"code", "cmd'=>["sudo -H -E -u discourse git clean -f", "sudo -H -E -u discourse bash -c '\\n set -o errexit\\n git fetch --tags --prune-tags --prune --force origin\\n if [[$(git symbolic-ref --short HEAD) == $version]] ; then\\n git pull\\n else\\n git -c advice.detachedHead=false checkout $version\\n fi\\n'", "sudo -H -E -u discourse git config user.discourse-version $version", "mkdir -p tmp", "chown discourse:www-data tmp", "mkdir -p tmp/pids", "mkdir -p tmp/sockets", "touch tmp/.gitkeep", "mkdir -p /shared/log/rails", "bash -c \\"touch -a /shared/log/rails/{production,production_errors,unicorn.stdout,unicorn.stderr,sidekiq}.log\\"", "bash -c \\"ln -s /shared/log/rails/{production,production_errors,unicorn.stdout,unicorn.stderr,sidekiq}.log $home/log\\"", "bash -c \\"mkdir -p /shared/{uploads,backups}\\"", "bash -c \\"ln -s /shared/{uploads,backups} $home/public\\"", "bash -c \\"mkdir -p /shared/tmp/{backups,restores}\\"", "bash -c \\"ln -s /shared/tmp/{backups,restores} $home/tmp\\"", "chown -R discourse:www-data /shared/log/rails /shared/uploads /shared/backups /shared/tmp", "[! -d public/plugins] || find public/plugins/ -maxdepth 1 -xtype l -delete"]}
bootstrap failed with exit code 128
**FAILED TO BOOTSTRAP** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
adc8ef45e9ae880827c9294dbbf73dfe9ab413a050c83fe3f4722c2911876ce2

```

> `version` only supports branches, not tags!

What is correct is:

```plaintext
params:
  version: release/2025.11

```

As for why I want to pull `release/2025.11`, it’s because the current production environment is on a version close to that, and I want to upgrade, but I’m afraid of potential issues. Furthermore, the audit process does not allow me to perform upgrades directly; I must first validate the upgrade process (from `release/2025.11` to `release/2026.1`) in the test environment before proceeding in production. Although this is somewhat tedious, it is indeed the best choice for a correct process. Thus, I had to look for a way to pull a specific branch or tag here.

Sorry for saying so much unnecessary stuff. Fortunately, I have now found a passable solution. Thank you everyone.

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 23, 2026, 2:58am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/2 "2026-03-23T02:58:32Z")

</div>

I continue to update on other impacts caused by this modification:

Installing a specific branch was successful, but attempting to verify an upgrade from this branch failed. This is because the latest update is not detected on the update page, preventing the update operation from being performed on the page.

 ![image](https://global.discourse-cdn.com/meta/original/4X/a/4/6/a4609bbc4bdcada8fbc86b9b3b87bd3aadd6476f.png)

 ![image](https://global.discourse-cdn.com/meta/original/4X/d/2/e/d2e48d60a3eb27cba979626db86dcac3772baedf.png)

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 27, 2026, 1:37am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/3 "2026-03-27T01:37:01Z")

</div>

Continuing from the previous topic, a new issue has been identified. When the local codebase is outdated, it can cause frontend compilation failures or other errors. Therefore, before making any modifications, the local codebase must be updated to the latest version.

```plaintext
# If you have previously modified the local codebase, please stash your changes first
# git stash

# Update to the latest version
git pull

# Reapply the stashed changes, or re-edit the corresponding configuration files
# git stash pop

```

Only after updating the local repository to the latest version can the installation proceed smoothly to build the specified branch as per the previous steps.

The local codebase referred to here is: `https://github.com/discourse/discourse_docker.git`

That is, the codebase after a standard installation.

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 27, 2026, 2:29am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/4 "2026-03-27T02:29:30Z")

</div>

Finally, here is a summary.

Our requirement is: install a specific version.

1. Update the local code repository `https://github.com/discourse/discourse_docker.git`

```bash
# Enter the project root directory
cd /var/discourse
# Update to the latest version
git pull

```

1. Modify the version to be specified

Edit `containers/app.yml` and add the following configuration at the end:

```yaml
params:
  version: release/2026.1 # Best practice should be: esr

```

1. Rebuild

```yaml
./launcher rebuild app

```

> If `version: esr`, you don’t need to read further.
> 
> First, run `git pull` to ensure the local code repository is up to date. Then specify the branch to deploy, and finally rebuild. This instruction applies to scenarios where you want to upgrade from `release/2026.1` to `release/2026.7`.
> 
> If you simply want to upgrade an already installed `release/2026.1`, you should just click “Upgrade” in the admin dashboard. This applies to scenarios where `release/2026.1` has updates (especially security fixes).

---

<div class="post-metadata">

### Author: ![Ed\_S](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ed_s/32/134015_2.png) [@Ed\_S](https://meta.discourse.org/u/Ed_S)
#### Post date: [March 27, 2026, 7:24am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/5 "2026-03-27T07:24:30Z")

</div>

> [@singi2016cn](#):
>
> ```plaintext
> params:
> version: release/2026.1
> 
> ```

I think it would be very unusual to configure a specific version, rather than a flavour/stream/tag, like latest or stable. I’m actually no longer sure what tags are normal and available and useful with this system.

---

<div class="post-metadata">

### Author: ![Moin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/moin/32/554653_2.png) [@Moin](https://meta.discourse.org/u/Moin)
#### Post date: [March 27, 2026, 7:30am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/6 "2026-03-27T07:30:16Z")

</div>

Have you taken a look at [Configure a supported tracking branch to get Discourse software updates](https://meta.discourse.org/t/configure-a-supported-tracking-branch-to-get-discourse-software-updates/17014/1) ? Maybe it helps for understanding which tags are useful

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 27, 2026, 7:31am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/7 "2026-03-27T07:31:37Z")

</div>

Yes, for ordinary users, the default `latest` is sufficient. However, for my scenario, I have no choice but to investigate how to use a specific version. I can’t just tell the `boss`: “Oh, I’m sorry, `Discourse` doesn’t currently support checking out a specific version; we can only update to the latest version.”

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 27, 2026, 7:32am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/8 "2026-03-27T07:32:40Z")

</div>

This post is very helpful; I will take a careful look at it. Thank you.

---

<div class="post-metadata">

### Author: ![Ed\_S](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ed_s/32/134015_2.png) [@Ed\_S](https://meta.discourse.org/u/Ed_S)
#### Post date: [March 27, 2026, 7:33am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/9 "2026-03-27T07:33:28Z")

</div>

> [@Moin](#):
>
> Have you taken a look at [Configure a supported tracking branch to get Discourse software updates](https://meta.discourse.org/t/configure-a-supported-tracking-branch-to-get-discourse-software-updates/17014/1) ?

I hadn’t seen that - thanks. Looks like we should be using latest/release/esr now. I see my own (old) app.yml picks up the default by being commented out:

```plaintext
  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

```

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 27, 2026, 7:39am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/10 "2026-03-27T07:39:02Z")

</div>

`version` currently does not support tags. To add support, the build script must be modified. The best practice would originally be:

```plaintext
params:
  version: esr

```

However, currently, it must be changed to:

```plaintext
params:
  version: release/2026.1

```

---

<div class="post-metadata">

### Author: ![Moin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/moin/32/554653_2.png) [@Moin](https://meta.discourse.org/u/Moin)
#### Post date: [March 27, 2026, 7:45am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/11 "2026-03-27T07:45:39Z")

</div>

Interesting. Even before the new versioning strategy, `beta` had been a tag instead of a branch for quite a while: [Upcoming changes to the beta branch of Discourse](https://meta.discourse.org/t/upcoming-changes-to-the-beta-branch-of-discourse/262063)

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 27, 2026, 7:49am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/12 "2026-03-27T07:49:47Z")

</div>

It’s me, I’m also confused, but the current build code indeed cannot use tags. This shouldn’t be the case.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [March 27, 2026, 10:26am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/13 "2026-03-27T10:26:46Z")

</div>

`version: release/2026.1` should work fine. If you want to take advantage of the new overlapping support periods on versions, then this is the correct way to do it. (but of course, you must to remember to update manually before 2026.1 reaches its end-of-life)

`version: esr` should also work. The system is designed to support tags. It is implemented as [`git checkout $version`](https://github.com/discourse/discourse_docker/blob/e5531b924d5456173aef8177b33813fdba3c1d8a/templates/web.template.yml#L106C61-L106C61).

> [@singi2016cn](#):
>
> Edit `templates/web.template.yml`

You should not make this change in `web.template.yml`. You should make it in your site-specific `containers/app.yml`

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [March 26, 2026, 3:47pm UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/15 "2026-03-26T15:47:29Z")

</div>

Something doesn’t appear to be right here. I was running v3.5.0 beta3 with the yml set to `version: tests-passed`

Then I noticed this versioning change so before rebuilding I changed the yml to `version: esr` and then did a rebuild from the CLI.

Now in discourse I see

> Installed  
> 2026.3.0-latest.1

This appears to be using the tests passed tag instead of the esr tag. I verified that app.yml is showing the version as esr , so why it it grabbing the latest build ?

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [March 27, 2026, 12:42pm UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/17 "2026-03-27T12:42:48Z")

</div>

So essentially there’s no way to get the most recent stable / esr build anymore?

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [March 27, 2026, 7:23pm UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/19 "2026-03-27T19:23:27Z")

</div>

> [@RBoy](#):
>
> Then I noticed this versioning change so before rebuilding I changed the yml to `version: esr` and then did a rebuild from the CLI.

Can you share the relevant lines of the `app.yml` file. Is `version:` definitely indented underneath the `params:` section? And have you definitely removed the `#` YAML comment character from the beginning of the line?

> [@RBoy](#):
>
> Now in discourse I see
> 
> > Installed  
> > 2026.3.0-latest.1

Just FYI, if you do want to get back onto ESR, you’ll need to either restore an earlier backup, or wait until the next ESR release in July. Downgrading a discourse installation is not supported 😢

---

<div class="post-metadata">

### Author: ![RBoy](https://avatars.discourse-cdn.com/v4/letter/r/2bfe46/32.png) [@RBoy](https://meta.discourse.org/u/RBoy)
#### Post date: [March 28, 2026, 7:29pm UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/20 "2026-03-28T19:29:37Z")

</div>

Yes am aware that I cannot downgrade. Attaching a screenshot showing the indentation.

Notice anything wrong here?

 ![IMG_2215](https://global.discourse-cdn.com/meta/original/4X/a/3/6/a360cde2a3880719d81c73b05332b844075d950b.jpeg)

---

<div class="post-metadata">

### Author: ![Ed\_S](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ed_s/32/134015_2.png) [@Ed\_S](https://meta.discourse.org/u/Ed_S)
#### Post date: [March 28, 2026, 8:07pm UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/21 "2026-03-28T20:07:22Z")

</div>

I believe `version` should be indented because it’s part of `params`.

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 30, 2026, 1:18am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/22 "2026-03-30T01:18:17Z")

</div>

Yes, I initially configured it directly in `containers/app.yml`, but for some reason, it didn’t take effect. Out of necessity, I ended up modifying `templates/web.template.yml` directly. I will try modifying `containers/app.yml` again.

---

<div class="post-metadata">

### Author: ![singi2016cn](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/singi2016cn/32/532755_2.png) [@singi2016cn](https://meta.discourse.org/u/singi2016cn)
#### Post date: [March 30, 2026, 1:21am UTC](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409/23 "2026-03-30T01:21:44Z")

</div>

Additionally, could you check why configuring `version: esr` does not take effect? Is this an isolated issue on my end, or is it a common occurrence? My network environment is indeed quite poor.

Configuration is as follows:

```plaintext
params:
  version: v3.6.0.beta2

```

The error message is:

```plaintext
FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && sudo -H -E -u discourse bash -c '
  set -o errexit
  git fetch --tags --prune-tags --prune --force origin
  if [[$(git symbolic-ref --short HEAD) == v3.6.0.beta2]] ; then
      git pull
  else
      git -c advice.detachedHead=false checkout v3.6.0.beta2
  fi
' failed with return #<Process::Status: pid 146 exit 128>
Location of failure: /usr/local/lib/ruby/gems/3.4.0/gems/pups-1.4.0/lib/pups/exec_command.rb:138:in 'Pups::ExecCommand#spawn'
exec failed with the params {"cd" => "$home", "hook" => "code", "cmd" => ["sudo -H -E -u discourse git clean -f", "sudo -H -E -u discourse bash -c '\n set -o errexit\n git fetch --tags --prune-tags --prune --force origin\n if [[$(git symbolic-ref --short HEAD) == $version]] ; then\n git pull\n else\n git -c advice.detachedHead=false checkout $version\n fi\n'", "sudo -H -E -u discourse git config user.discourse-version $version", "mkdir -p tmp", "chown discourse:www-data tmp", "mkdir -p tmp/pids", "mkdir -p tmp/sockets", "touch tmp/.gitkeep", "mkdir -p /shared/log/rails", "bash -c \"touch -a /shared/log/rails/{production,production_errors,unicorn.stdout,unicorn.stderr,sidekiq}.log\"", "bash -c \"ln -s /shared/log/rails/{production,production_errors,unicorn.stdout,unicorn.stderr,sidekiq}.log $home/log\"", "bash -c \"mkdir -p /shared/{uploads,backups}\"", "bash -c \"ln -s /shared/{uploads,backups} $home/public\"", "bash -c \"mkdir -p /shared/tmp/{backups,restores}\"", "bash -c \"ln -s /shared/tmp/{backups,restores} $home/tmp\"", "chown -R discourse:www-data /shared/log/rails /shared/uploads /shared/backups /shared/tmp", "[! -d public/plugins] || find public/plugins/ -maxdepth 1 -xtype l -delete"]}
bootstrap failed with exit code 128
**FAILED TO BOOTSTRAP** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
adc8ef45e9ae880827c9294dbbf73dfe9ab413a050c83fe3f4722c2911876ce2

```

The root cause is that the `git symbolic-ref --short HEAD` command can only return the branch name.

[Next page](https://meta.discourse.org/t/help-deploying-older-versions-of-discourse/399409.md?page=2)
