Store 0.2.31
Installs native apps and Docker recipes from this project's repository and others you add
system
Download
| NAS | Size | SHA256 | |
|---|---|---|---|
| My Cloud PR4100 | 85 KB | Download | 9a73105bc48a8ddb… |
| My Cloud PR2100 | 85 KB | Download | 4affe90e0865c7d6… |
| My Cloud DL4100 | 85 KB | Download | 96497a9350b6a91e… |
| My Cloud DL2100 | 85 KB | Download | 7f541a85a33b39fe… |
| My Cloud EX4100 | 85 KB | Download | 8ce06187bf0e862d… |
| My Cloud EX2100 | 85 KB | Download | 908b7466991804b7… |
| My Cloud EX2 Ultra | 85 KB | Download | eaeb6c3640c2e23d… |
| My Cloud Mirror (Gen 2) | 85 KB | Download | eaf924280a39ea70… |
| My Cloud (Gen 2) | 85 KB | Download | c1b6c921bfd0771f… |
| WD Cloud | 85 KB | Download | 1bc4d43bca854638… |
An unofficial Store for WD NAS systems: it installs native apps (WD .bin packages) and Docker recipes from repositories - this project's, and any others you add - from a page in the NAS dashboard, without SSH. Repositories follow the Store and recipe format.
While it's on, the Store is the dashboard's Apps page: the list of installed apps down the side is replaced by the Store, full width (see The Apps page). Its tabs:
- Installed: every app on the NAS (this project's, WD's and any installed by hand) and every recipe. An app's page has Configure (its own page, as the side list previously opened it), a Running switch (the NAS's own on/off switch), and Update and Remove.
- Apps: install, update and remove native apps. The Store downloads the package for your NAS model, checks it against the checksum in the repository's catalogue, and installs it with the NAS's own installer (the same one as the dashboard's manual install).
- Recipes: apps that run in Docker (e.g. Immich). Each recipe's settings are a short form (e.g. which share the photos go in): the Store writes them to a
.envfile next to the recipe's compose file, starts it withdocker compose, and - with the Nginx app installed - gives it an HTTPS address. Settings can be changed later, and recipes updated or removed, from the same page. - Manual install: installing an app from its package file (
.bin) on your computer, with the NAS's own installer - as the Apps page's "install an app manually" did. - WD Store: Western Digital's own app store, as the Apps page offered it.
- Repositories: the list of catalogues the Store reads. New versions are looked for by themselves: every night, and when the page opens if it's been over an hour (Refresh does it now). This project is there by default; others can be added by their address (a GitHub repository, or the HTTPS address of a
store.json).
Two things run by themselves every night: the check for new versions (04:25) and the automatic updates (04:30, only of what you've ticked). Everything else happens only when the page is used. Only NAS admins can use the page (see Management pages). Activity shows the log of the latest install, update or removal, and the automatic updates.
Trust
Apps and recipes run as root, so the Store is careful about where they come from:
- Everything is downloaded over HTTPS only (redirects to plain HTTP are refused).
- Every download is checked against the SHA256 checksum in the repository's catalogue - packages, and every file of a recipe - and refused if it doesn't match.
- A repository can sign its catalogue (Ed25519). Its key is remembered when the repository is added, and from then on a catalogue that isn't signed by that key is refused. If the key changes, the page shows the new key's fingerprint and waits for you to accept it. (Checking signatures needs PHP's sodium extension: the NAS's own PHP may not have it, in which case the Store uses the PHP app's PHP. Without either, a signed repository is refused rather than trusted.)
- Adding a repository other than this project's asks you to confirm that you trust it, and its apps and recipes are labelled as third-party.
- A recipe's files can't reach outside its folder, and the folders a recipe is given must be on a share - never
Nas_Prog, where other apps keep their secrets. - WD's installer also checks each package's own signature.
Apps
- Some apps are listed by a repository but made by someone else - e.g. Plex Media Server, Plex's own package for each WD model, downloaded from Plex. Their page says so; the repository vouches for the package's checksum.
- Updating an app means removing the installed version and installing the new one - the NAS's installer won't install over an app. The Store only does this for apps that keep their data outside their install folder (e.g.
Nas_Prog/_jellyfin), which this project's apps do; for others it shows that an update is available. If the NAS's installer fails after the old version was removed, the Store puts the old version back and starts it (it keeps its files, as hard links, until the new one is in), and says why the installer failed. Updating or removing the Nginx app while the dashboard is reached through it asks first, as the page loses its connection: start it fromhttp://<nas-ip>/instead. - Removing an app keeps its data folder; the Store says where it is. An app that another installed app needs (its
InstDepend) can't be removed until that one is. - Removing the Store (Installed → Store → Remove) brings back the NAS's own Apps page. Everything it installed stays installed, and its settings (e.g. your repositories) stay in
Nas_Prog/_storefor if it's installed again. To turn it off for a while instead, untick Running.
Automatic updates
Each installed app the Store can update, and each recipe, has an Update automatically switch on its page. Every night at 04:30 the Store updates those with a newer version, as their Update button would:
- From the repository each came from - never a different one, e.g. a fork. An app installed by hand is updated from the one repository offering it; if several do, update it once from the one you want.
- One at a time: apps after the apps they need (e.g. PHP before Nginx), then recipes, then the Store itself last - so its own update can't stop the others. One failing doesn't stop the rest; an app whose new version doesn't install is put back and started, as with its Update button.
- Some updates are left for you, and the Activity tab says why: a repository saying a version needs a step by hand (e.g. a database's data upgrade -
manual_updatein its catalogue), a recipe's new version asking for a setting it can't fill in by itself (e.g. a new password - new settings with a default take it), a repository whose signing key changed, or requirements not met. Its page still updates it. - The Activity tab lists what tonight's run will do with each ticked app and recipe, and what the last run did. A run that updates something shows its log there, as other jobs do.
- With the ntfy app installed, give the Activity tab a topic and ntfy is told what was updated, what failed, and what was left for you (once per version). Nothing is sent on nights with nothing new.
Updating an app restarts it, so ticked apps are briefly down at around 04:30.
Repositories
Removing a repository only removes it from the Store's list (and its cached catalogue). Apps and recipes installed from it stay installed and keep working, and a recipe's settings can still be changed and it can be removed (from the copy of the recipe kept in its folder) - they just get no updates. Adding the repository again picks them up where they were, updates included. Its signing key is pinned afresh when it's added again.
The Apps page
The Store replaces the dashboard's Apps page with its own copy of it (wd/app.php, bind-mounted over WD's read-only /usr/local/modules/web/pages/addons/app.php when the Store starts - at boot, or when it's switched on). WD's file is never changed: switching the Store off, removing it or updating it puts WD's page back. The copy keeps everything of WD's that its app store needs (its scripts, dialogs and manual install), without the list down the side.
If the Store's page ever fails to load there, the Apps page says so and how to get WD's back over SSH:
umount /usr/local/modules/web/pages/addons/app.php
Recipes
- A recipe's settings, compose file and data go in its own folder in
Nas_Prog(e.g.Nas_Prog/_immich), root-only. Passwords and generated secrets are kept only in its.env. - Changing settings rewrites
.envand applies it (docker compose up -d). Settings that only make sense at install time (e.g. Immich's face recognition default) become the app's own settings afterwards. - Updating a recipe asks only for its new settings, if any.
- Removing a recipe stops and removes its containers and its Nginx site. You choose which folders are deleted with it (none by default); folders the recipe marks as yours - e.g. Immich's photos - are never offered. If its own folder is kept, installing it again reuses its settings (e.g. its database password, which the database was created with). A recipe set up by hand (e.g. with its
setup.sh) is picked up the same way. - If an installation fails part-way, it's undone.
Several repositories offering the same app (e.g. a fork)
A fork of this project usually offers the same apps, under the same ids. The Store keeps them apart:
- Each app is listed once per repository. Repositories with the same name are labelled with their owner (e.g.
WD NAS App Builder (paul-norman)andWD NAS App Builder (someone)). - The Store remembers which repository it installed each app and recipe from, and only that one updates it. Another repository's page for it says where it came from; for apps that keep their data, it offers Switch to this repository - an update from that repository, after which its updates come from there.
- An app installed by hand (Manual install, or over SSH) has no repository: any repository can update it, the Installed tab shows the newest version on offer, and its page lists the others. The update you choose sets where its updates come from.
- A recipe is installed from one repository at a time (its folder is the same): another repository's page for it points to its page there. If the repository it came from has been removed from the list, another repository offering it can take it over instead (Switch to this repository on its page there - its settings, folders and containers stay as they are).
- An app's page also says when another repository has a newer version of it, with a link to its page there (which can switch it over).
Forking
To publish your own repository from a fork:
- Set your repository's details in
store/metadata.json(repository: its name, summary, homepage and maintainer) - a different name saves users from telling the two apart by owner. - Sign it with your own key (
openssl genpkey -algorithm ed25519 -out key.pem, then--sign-key key.pem). Never reuse this project's. - Build
store.jsonwithstore/tools/build_store.py, pointing--package-url(and--base-url,--release-url,--sources-url) at your fork's releases and files. - Users add it by its GitHub address (Repositories) - next to this project's, or instead of it.
The Store's own default repository (added on a first install) is STORE_DEFAULT_REPO in lib/store.php. A fork that ships its own Store build can change it to its own; one that doesn't leaves its users with this project's repository, plus whichever they add.
Where things are
| What | Where |
|---|---|
| Repositories, cached catalogues and icons, the last job's log, the automatic updates' settings and last run | Nas_Prog/_store (root only) |
| Packages while they're installed | /usr/local/apps_upload (the dashboard's own upload folder, on the disk - deleted once installed) |
| Each recipe | Nas_Prog/<its folder>: compose.yaml, .env, compose.override.yaml (folders chosen in its settings), .store/ (the recipe's files and the install record) |
Testing a repository
store/tools/make_test_repo.sh builds a repository from your built packages and the recipes, in a folder any HTTPS web server can serve - e.g. a site of the Nginx app on the NAS itself (Nginx app → Sites, pointed at the folder; PHP off):
MODEL_OVERRIDE=MyCloudPR4100 ./build.sh store # and any apps to offer
store/tools/make_test_repo.sh /path/to/share/repo https://repo.<your domain>/
Then add https://repo.<your domain>/store.json in the Store (Repositories). Add --sign-key key.pem (an Ed25519 key: openssl genpkey -algorithm ed25519 -out key.pem) to sign it.
The Store's own tests run without a NAS: see tests/store.