Repo transferred from the-luap/picpeak → PicPeak/picpeak. Docker images
publish to ghcr.io/picpeak/picpeak/{backend,frontend} (lowercase, per the
GHCR canonical form computed by docker-build.yml's `${GITHUB_REPOSITORY,,}`).
Sweep covers:
- docker-compose.production.yml + Dockerfiles → new image registry path
- README, CONTRIBUTING, SECURITY, SIMPLE_SETUP, scripts/picpeak-setup.sh
→ new GitHub URLs
- Update-check / release-notes services (updateCheckService,
environmentService, updateNotificationService, adminSystem,
UpdateNotification, githubReleaseUrl) → GitHub API + tag URLs use the
canonical PicPeak/picpeak path
- Issue templates + README-DOCKER + workflow README → updated package URLs
- One commit-context comment in migrations/090 + customerAccountsService
CHANGELOG.md is intentionally untouched (historical release entries are
immutable; GitHub auto-redirects the old URLs indefinitely).
CLAUDE.md keeps the bare `(the-luap)` reference — that's the maintainer's
personal handle, not a repo URL.
22 files, 48/48 line swaps (every change is a 1:1 URL replacement).
Two follow-up fixes inside the same install-experience surface as
the previous commit:
1. **Removed `docker compose exec -T backend npm run migrate`** in
both install_docker and update_docker_installation. The backend
container's wait-for-db.sh already runs `npm run migrate:safe`
on startup; the script was racing it with a separate (and
non-safe) `npm run migrate`. That race is the most likely
actual mechanism behind #484's "relation 'photos' does not
exist" error on the second install attempt — partial schema
visible to one of the two parallel migrators. Replaced with a
bounded wait for the backend container to become healthy
(Docker healthcheck reports green only after wait-for-db.sh
finishes its migration pass).
2. **Added the missing frontend container** to the script-generated
compose. The script previously generated a postgres + redis +
backend stack with no frontend at all (backend on host port
3001), while the documented production install
(docker-compose.production.yml) ships postgres + redis +
backend + frontend (nginx /api proxy on host port 3000). That
shape divergence is half of issue B in #484 — script-installed
admins had no frontend container and were left wondering where
the UI lived. Aligning both compose files on the same shape
eliminates the divergence; the frontend uses curl in its
healthcheck (frontend/Dockerfile explicitly `apk add curl`)
unlike the backend.
The remaining piece of issue B — picking ONE canonical install
path (build-from-source script vs. prebuilt-image production
compose) and deprecating the other — is a deployment-strategy
call that deserves its own design pass. Both paths now produce
architecturally-equivalent stacks.
Three install-experience bugs that compounded into MrGabri's "fresh
install fails" report:
1. **postgres healthcheck noise.** `pg_isready -U <user>` without
-d defaults to probing a database whose name matches the user.
Since DB_NAME defaults to picpeak_prod (not picpeak), every
healthcheck interval logged
FATAL: database "picpeak" does not exist
into postgres logs even though the install was working
correctly. Reporter saw the FATAL, assumed broken, restarted
with DB_NAME=picpeak, hit a tainted-state migration error on
the second try, filed a bug. Fixed in both
docker-compose.production.yml and the inline compose generated
by scripts/picpeak-setup.sh — pin -d to ${DB_NAME} so the
probe hits the real database.
2. **backend container shows perpetually `unhealthy`.** Both
compose files used `curl -f` for the backend healthcheck, but
backend/Dockerfile only installs dumb-init + postgresql-client +
ffmpeg — no curl. Switch to wget --no-verbose --tries=1 --spider
to match what backend/Dockerfile's own HEALTHCHECK already
does. Now docker ps, docker compose ps, and the backend image's
built-in healthcheck all agree.
3. **stale separate `workers` container.** scripts/picpeak-setup.sh
still generated a second container running `npm run workers`
alongside the backend, but workers (fileWatcher,
expirationChecker, emailQueueProcessor, backgroundProcessor,
webhookWorker) have been started by server.js in-process for
a while — see the comment at line ~895 of the same script for
the systemd-side cleanup. The duplicate container caused two
file watchers and two expiration checkers to compete for the
same DB rows. Removed from the generated compose; install +
upgrade paths now stop and rm any pre-existing picpeak-workers
container.
Doesn't address issue B's bigger architecture mismatch (the script
generates a build-from-source compose with no frontend container,
while docker-compose.production.yml uses prebuilt images with a
separate frontend container). That deserves its own design pass
to pick a canonical install path and align — out of scope here.
Two intertwined bugs reported in #427 by @iSchumi6210:
1. Login silently fails over HTTP. Backend defaulted COOKIE_SECURE to true
when NODE_ENV=production. Over plain HTTP the browser drops the Secure
cookie → next /auth/session request returns 401 → redirect back to
/admin/login → no error shown. picpeak-setup.sh writes
NODE_ENV=production but never writes COOKIE_SECURE, so every first-time
install without a reverse proxy hits this.
2. Admin password is generated but admins can't find it. The 001_init.js
migration writes the generated password to data/ADMIN_CREDENTIALS.txt
inside the backend container, but picpeak-setup.sh only copies it out
when --reset-admin-password is passed. Default-path users never see it
and resort to manual bcrypt updates in psql.
Changes:
- tokenUtils.js: production default goes from `true` to `'auto'`. On real
HTTPS req.secure is true → Secure flag is still emitted (no security
regression for reverse-proxy deployments). On plain HTTP req.secure is
false → Secure flag omitted → login works. Users who explicitly want
the strict HTTPS-only behaviour can still set COOKIE_SECURE=true.
- .env.example: rewrite the COOKIE_SECURE block to make the new default
obvious and explain when to override (set =true for strict, =false to
skip the per-request check, leave unset for the auto behaviour).
- picpeak-setup.sh (both Docker and native paths):
- Write COOKIE_SECURE=auto explicitly to the generated .env (defense in
depth so the right behaviour is preserved even if the backend default
flips again later)
- After migrations, ALWAYS copy ADMIN_CREDENTIALS.txt out of the
backend container/data dir to the host data dir, chmod 600, and print
the email + password to the install output. The credentials file
remains as a backup record that the operator should delete after
noting the password.
Verified locally with all 4 permutations of NODE_ENV × COOKIE_SECURE:
production, unset → HTTPS: secure=true ✓ HTTP: secure=false ✓ (was both true)
production, =true → both: secure=true (strict opt-in preserved)
production, =auto → HTTPS: secure=true HTTP: secure=false (already-correct)
development, unset → both: secure=false (dev unchanged)
Issue #66: Remove redundant picpeak-workers.service creation from setup script.
Workers (fileWatcher, expirationChecker, emailProcessor) are now started
automatically by server.js, so a separate systemd service is not needed.
The legacy service cleanup code is retained for migration purposes.
Issue #67: Ensure storage directories exist at container startup in
wait-for-db.sh. When host directories are bind-mounted in Docker, the
container's built-in directories are overridden. This fix creates the
required directory structure (events/active, events/archived, thumbnails)
before the application starts, preventing EACCES permission errors.