Files
projectsend/.env.example
T
ignacionelson 503676647f Let a split-user host serve downloads
A download is not served by PHP. PHP authorizes it and hands the web
server the path with X-Accel-Redirect, so the web server has to open a
file PHP wrote. Where those are different users — cPanel and Plesk
commonly arrange it that way — it cannot: uploads land 0600 inside a 0700
directory, and traversing 0700 means being its owner. Nothing else on the
site shows a symptom. Uploading works, the library lists everything, and
only downloads fail, as ERR_INVALID_RESPONSE in the browser and
`open() ... failed (13: Permission denied)` in the web server's log.

FILES_WEB_SERVER_READABLE writes uploads 0644/0755 instead. Opt-in and
spread into the disk configuration rather than switched by a ternary, so
an install that does not set it keeps byte-for-byte the configuration it
had: the relaxed modes are readable by every account on the machine,
which is the wrong trade wherever the web server and PHP are one user, as
in the image and on most self-administered servers.

The two halves are not enforced alike, which is the part worth knowing.
`visibility` has Flysystem chmod each file after writing it, so 0644
holds under any umask. A directory is created by mkdir(), which masks its
mode argument, so 0755 is a ceiling: a pool at umask 0077 still produces
0700 and still cannot be traversed. That cannot be fixed from config, so
INSTALL.md carries it — how to tell the two users apart, the one-time
chmod for files already on disk, and the pool setting for the umask.
FilePermissionsTest asserts all three modes, umask cases included, since
the asymmetry is invisible from the configuration.

Reported by @denkfabrik-li (#1668), who diagnosed it and verified the
remedy on the affected host.
2026-08-21 16:34:14 -03:00

100 lines
2.6 KiB
Bash

APP_NAME=ProjectSend
PROJECTSEND_EDITION=community
# Emergency off switch for the CAPTCHA on public forms, for an operator who
# has a shell but no working login. Everything else about the feature is
# configured at /system/settings/captcha.
# PROJECTSEND_CAPTCHA_DISABLED=true
# Optional: uid/gid the app/web containers' internal user runs as, so the
# bind-mounted repo needs no permission fixes. Defaults to 1000; override
# if your host user's `id -u`/`id -g` differ.
# WWWUSER=1000
# WWWGROUP=1000
# Optional: create the first administrator unattended on container start.
# Leave unset to use the first-run setup screen instead.
# ADMIN_NAME="Administrator"
# ADMIN_EMAIL=admin@example.com
# ADMIN_PASSWORD=
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_TIMEZONE=UTC
APP_URL=http://localhost
# Required whenever a proxy/load balancer sits in front of this app (an
# ALB, Cloudflare, a hosted ingress) — otherwise every request looks like
# it comes from the proxy, collapsing per-IP rate limits and the download
# IP log. Comma-separated addresses/CIDRs, or "*" to trust any proxy
# (only safe when nothing but the proxy can reach the app).
# TRUSTED_PROXIES=
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
PHP_CLI_SERVER_WORKERS=4
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=projectsend
DB_USERNAME=projectsend
DB_PASSWORD=secret
SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
# Set this only if your web server and PHP-FPM run as different system
# users — common on cPanel/Plesk shared hosting. Uploaded files are
# written 0600 in 0700 directories, which nginx cannot read, and since
# nginx is what actually streams a download (PHP authorizes, then hands
# it the path) every download fails while the rest of the site works.
# Relaxes those to 0644/0755, which every account on the machine can
# read — leave it off if your web server and PHP are the same user.
# FILES_WEB_SERVER_READABLE=true
QUEUE_CONNECTION=redis
CACHE_STORE=redis
CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false