From 8156664cccf4d514d7ac9856ea05e242621b5923 Mon Sep 17 00:00:00 2001 From: ignacionelson Date: Tue, 18 Aug 2026 15:32:45 -0300 Subject: [PATCH] Give the official Docker image a way to migrate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The guide had no answer for the install method we recommend most. The published image carries no Composer — it ships the application already built and has no use for one — so `composer require`, the first command in Step 1, is not a thing a Docker reader can run at all. The guide's Docker line assumed the stack in this repository, which builds from source and does have one. Composer is a PHP file, and PHP is what the image is. Fetching it into /tmp for the length of the migration works, and the whole path is verified rather than plausible: the tool installs, all four projectsend:migrate:* commands register with no package:discover run by hand, and the export script the Bundle route needs is where the guide now says it is. Two details in there are load-bearing rather than decorative. `-u www-data` because exec lands as root and a root-owned vendor/ is a problem the application meets later rather than now. `--update-no-dev` because the shipped lock file knows about pest and phpstan, and a production install should not grow a test suite on the way past. The section says plainly that the install lives in the container's writable layer and does not survive the container being replaced. That is honest about a real limit, and the reason it is acceptable is worth saying too: the run's progress and its id map are in the database, so losing the package costs an install, not a migration. Step 1 is now three self-contained sections rather than one set of commands with exceptions bolted on, because the previous shape is what let a reader follow instructions that could not work on their install. Verified against the real image, built locally from the release zip — the Docker Hub repository is still private, so pulling it was not an option. Co-Authored-By: Claude Opus 5 --- MIGRATING-FROM-V1.md | 56 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/MIGRATING-FROM-V1.md b/MIGRATING-FROM-V1.md index f8883334..429c3ae1 100644 --- a/MIGRATING-FROM-V1.md +++ b/MIGRATING-FROM-V1.md @@ -100,18 +100,17 @@ The tool reports each of these before it starts and names every affected row. It ## Step 1 — Install the tool -On the **new** install: +Everything here happens on the **new** install. How the tool gets there — and whether you get its +screen — depends on how ProjectSend itself got onto the machine, so find yours below and use that +section on its own. + +### If you installed from a release zip ```sh composer require projectsend/v1-migration-tool php artisan migrate # creates the tool's two tables ``` -What comes after that depends on how ProjectSend got onto the machine, and so does whether you get -the tool's screen. - -### If you installed from a release zip - That is the whole installation — there is no `npm run build` to run. The zip ships its assets already compiled and deliberately without the toolchain that compiled them, so there is no `package.json` to build from. @@ -124,16 +123,44 @@ Nothing is missing from the migration itself. Every step below lists the command commands do everything the screen does, and on a zip install they are the interface rather than a fallback. Start with [Step 2](#step-2--pick-your-route) and follow the commands. -### If you are running from a git checkout +### If you are running the official Docker image -Including the Docker stack in this repository. Build the frontend so the screen appears: +The image carries no Composer. It ships the application already built and has no use for one, so +fetch it for the length of the migration and use it in place: ```sh -npm run build +docker compose exec -u www-data app \ + php -r 'copy("https://getcomposer.org/composer.phar", "/tmp/composer.phar");' +docker compose exec -u www-data app \ + php /tmp/composer.phar require projectsend/v1-migration-tool --update-no-dev +docker compose exec -u www-data app php artisan migrate ``` -In Docker, prefix the two commands above with `docker compose exec app`; `npm run build` runs on -the host, where the toolchain is. +`-u www-data` is not decoration: `exec` lands as root, and a root-owned `vendor/` is a problem the +application runs into later rather than now. `--update-no-dev` keeps the test tooling that the lock +file knows about out of a production install. + +That install lives in the container's writable layer, so it lasts until the container is replaced — +a `docker compose pull`, or any change to your compose file, takes it with it. For a migration you +finish in one sitting that is fine, and if it does go, install it again: the run's progress and its +id map are in the database, not in the package. + +There is no `/system/migrate` screen here either, for the same reason as a zip install. The commands +are the interface — start with [Step 2](#step-2--pick-your-route). + +### If you are running from a git checkout + +Including the Docker stack in this repository, which builds the application from source rather than +pulling the published image. + +```sh +composer require projectsend/v1-migration-tool +php artisan migrate # creates the tool's two tables +npm run build # so the tool's screen enters the frontend bundle +``` + +In Docker, prefix the first two with `docker compose exec app`; `npm run build` runs on the host, +where the toolchain is. Then open **`/system/migrate`**, signed in as a staff user with the *Edit settings* permission. There is no sidebar link — a one-time tool does not earn a permanent slot in the navigation of an @@ -190,6 +217,13 @@ over. Take it from the package, which is where it lives on every install: vendor/projectsend/v1-migration-tool/bin/projectsend-v1-export.php ``` +In Docker, copy it out of the container first: + +```sh +docker compose cp \ + app:/var/www/html/vendor/projectsend/v1-migration-tool/bin/projectsend-v1-export.php . +``` + If you have the screen, `/system/migrate` offers it as a download instead. On the **Legacy** server: