4 Commits

Author SHA1 Message Date
ignacionelson 92a132d74f Give zip builds their own queue, so one archive cannot hold up the mail
The last piece of the #1687 follow-up. BuildZipDownloadJob allows itself
an hour, every shipped topology runs exactly one worker, and everything
shares the default queue -- so one large archive delayed every
notification email queued behind it. The size cap and the
one-build-per-person rule bounded that in July; they did not remove it.

onQueue('zips') in the constructor rather than at the dispatch site, so a
second caller cannot forget it. Both images grow a worker for it:
compose.yaml gains worker-zips, supervisord gains [program:queue-zips],
and the existing worker in each narrows to --queue=default. --tries=1
there matches the job, which records its own failure rather than being
retried.

The part that needs care is the manual install. A worker whose command
still says plain `queue:work` consumes `default` only, so it would send
email happily and never finish a single zip, with nothing in any log
saying why. INSTALL.md's unit now reads --queue=default,zips -- one
worker watching both, which is right for most installations -- and says
what happens if you leave it off, with the two-worker split offered for
anyone who would rather keep the two kinds of work apart. CHANGELOG
carries it as an upgrade note, since it is something to do rather than
something that was done.

Verified in the dev stack rather than only in a test: dispatched a build
and watched worker-zips take it while the default worker stayed idle.
2026-08-26 18:06:40 -03:00
ignacionelson 202a1d7ad5 Point the Docker guide at the image people actually run
#1658 reports that app, web, db and redis have no restart policy, so the
stack does not come back after a reboot. True, and fixed here — but the
file it is about is the development stack, and the production example has
had the policy all along. The reporter got there by following DOCKER.md,
which is #1627 again: 745f24c fixed the README's pointer and left this
page's body describing a stack no user should be running.

Against an image install almost every procedure on it was wrong. It said
uploads live in `storage/app/files/` "in the project directory" and `.env`
beside it — both are on the storage volume, and the entrypoint generates
that `.env` itself. Its compose.override.yaml recipe bind-mounted into
app, web, worker and scheduler, which are one container under supervisord
in the image, at a path one level too deep to carry APP_KEY. It told
people to chown a directory the entrypoint already chowns, to rsync from a
host path that does not exist, and to `git pull` to upgrade. Its mysqldump
read ${DB_ROOT_PASSWORD} from a .env an image install does not have, so
the documented backup silently fell back to `root` and failed. Docker Hub
links this page as "where your data lives, backups, moving to another
server".

So it is now about the image, and shorter for it: two volumes instead of
three loose things, the key explained where people actually lose it, no
override file because the compose file is the operator's own, and a
reboot section — the answer to the issue for anyone who wrote their own
compose. The clone-and-build stack keeps one pointer to CONTRIBUTING.md,
which has been the correct place for it since #1627.

The Docker Hub page keeps the two facts a reader who never leaves it
needs and hands off the procedures, so the drift that caused this has one
copy to go wrong instead of two.

Adminer and mailpit stay without a restart policy on purpose: those come
up for a session, not for the life of the machine.

Refs #1658

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:21:12 -03:00
Ignacio Nelson f446398dfd Say which step is missing instead of failing blankly (#1633)
Somebody followed the README's Docker quickstart, which starts the
development stack, and got three failures in a row with nothing to search
for (#1627): the worker died once a second on a missing autoloader, the
site answered a bare 500, and once dependencies were installed by hand the
setup screen threw ViteManifestNotFoundException.

None of that is wrong behaviour for a clone — vendor/ and public/build/
are deliberately not in git — but every one of those failures kept its
cause to itself.

The preflight guard exists to turn "this was never set up" into a
sentence, and it runs before the autoloader precisely so it can. It now
answers two more questions: dependencies not installed, and frontend not
built. The dependency check goes first, before the .env one, because the
fix that branch prints — php artisan key:generate — cannot itself run
without the autoloader, so reporting the key first hands somebody a second
and more confusing error. A running vite dev server counts as built:
public/hot means the assets come from there, and blocking a developer
mid-session would be worse than the exception this replaces.

The worker and scheduler exec straight into artisan, so before composer
install they died instantly and restarted forever, filling the log that
had to be read to fix it. They now print what is missing and exit slowly,
and recover on their own once it is there. The scheduler gains the restart
policy the worker already had — without one it exits during that window
and stays exited, and scheduled work then silently never happens.

Rehearsed on a genuine clone of the public repository, following the
reporter's exact path: worker prints instructions instead of fatals (2
restarts in 30s, not 30), the browser gets "ProjectSend is not installed
yet" naming composer install, then "not configured yet", then "not built
yet" naming npm run build, then the setup screen.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 02:21:29 -03:00
ignacionelson 6e47d76ba6 ProjectSend 2.0.0
Client file sharing, rebuilt from the ground up: a private area per
client, resumable uploads, folders, groups and categories, sharing with
expiry dates and download limits, comments, file versions, an activity
log, a REST API, and sixteen languages.

This repository begins here. ProjectSend 2 was developed privately, and
that development history is not published — the previous generation
remains available, with its own history, at projectsend/legacy.

Free software under the GNU General Public License v2, or (at your
option) any later version.
2026-08-14 01:38:12 -03:00