Skip to content

[Shlink] update wipes shlink-web-client/servers.json, breaking the Web Client every time #17020

Description

@frontend-report

Script: Shlink

Reported by: @Corgei

Guidelines

  • Read and understood guidelines: yes
  • Verbose mode used: yes

Issue occurs during: Script Update

Environment

  • Linux distribution: Debian
  • Proxmox version: 9.1
  • Default settings: No
  • Advanced settings: Yes
  • Exact command: bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/shlink.sh)"

Description

After running the built-in update command inside a Shlink LXC (installed via this repo's ct/shlink.sh / install/shlink-install.sh), the Shlink Web Client loses its configured server and shows the "Welcome! Add a server" screen, even though the Shlink API backend continues to work fine.

Root cause (confirmed by reading install/shlink-install.sh and ct/shlink.sh):

  • On initial install, install/shlink-install.sh creates /opt/shlink-web-client/servers.json with the initial API key so the Web Client works out of the box.
  • On update, update_script() in ct/shlink.sh does:
    1. For /opt/shlink (API): backs up .env and data/, does CLEAN_INSTALL=1 fetch_and_deploy_gh_release ..., then restores the backup. This correctly preserves configuration.
    2. For /opt/shlink-web-client (Web Client): does CLEAN_INSTALL=1 fetch_and_deploy_gh_release ... with NO backup/restore step for servers.json.
  • Because CLEAN_INSTALL=1 wipes the target directory before redeploying, servers.json (and any other user customization under /opt/shlink-web-client, e.g. a custom nginx config placed there) is permanently deleted on every update. The Web Client then has no server configured and shows the onboarding screen, which looks like a "connection lost" / outage to the end user, even though nothing about the API, database, or network changed.

This is inconsistent with how /opt/shlink itself is handled (backup + restore around the clean install) and is easy to reproduce on every update.

Steps to reproduce

  1. Install Shlink via this repo's script, opting in to "Install Shlink Web Client?" during setup.
  2. Confirm the Web Client works and has a server configured (/opt/shlink-web-client/servers.json exists and is populated).
  3. Run update from the container console (or re-run the ct script with the update path).
  4. After the update finishes, open the Web Client in a browser.

Error output

No error/exception is thrown by the update script itself; it reports success. The symptom is only visible in the browser: the Web Client shows the onboarding screen ("Welcome! This application will help you manage your Shlink servers." / "+ Add a server") instead of the previously configured server, because /opt/shlink-web-client/servers.json no longer exists.

Verification performed on an affected container:
$ ls -la /opt/shlink-web-client/servers.json
ls: cannot access '/opt/shlink-web-client/servers.json': No such file or directory
$ curl -s http://127.0.0.1:3000/servers.json
(404 / empty — served via try_files /servers.json /conf.d/servers.json;, neither path exists after the update)

Meanwhile the API itself remains healthy:
$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/rest/health
200

Additional context

Suggested fix, mirroring what is already done for /opt/shlink:

In ct/shlink.sh update_script(), before the CLEAN_INSTALL for shlink-web-client, back up /opt/shlink-web-client/servers.json (if it exists) to a temp location, and restore it after fetch_and_deploy_gh_release completes — the same backup/restore pattern already used for /opt/shlink/.env and /opt/shlink/data. For example:

if [[ -f /opt/shlink-web-client/servers.json ]]; then
cp /opt/shlink-web-client/servers.json /opt/shlink-web-client-servers.json.bak
fi
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "shlink-web-client"
"shlinkio/shlink-web-client" "prebuild" "latest" "/opt/shlink-web-client"
"shlink-web-client_*_dist.zip"
if [[ -f /opt/shlink-web-client-servers.json.bak ]]; then
mv /opt/shlink-web-client-servers.json.bak /opt/shlink-web-client/servers.json
fi

As a workaround, I'm currently keeping a persistent copy of servers.json outside /opt/shlink-web-client and using a systemd path unit to restore it automatically whenever the directory changes, but this should ideally be fixed in the upstream update script so every user doesn't need to do this themselves.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions